Browse Source

First step of hierarchical schedulers' restructuring.
Scheduler tree nodes and scheduler-hierarchic strategies
have been separated to gain lisibility and reusability.
Experimental, we need to comment and document it further
before being used.

Marc Sergent 12 years ago
parent
commit
b34e4bb751

+ 36 - 7
include/starpu_sched_node.h

@@ -52,6 +52,12 @@ struct starpu_sched_node
 	struct starpu_task * (*pop_task)(struct starpu_sched_node *,
 					 unsigned sched_ctx_id);
 
+	/* node->push_back_task(node, task)
+	 * This function is called when a push fails after a pop has been done,
+	 * to push it back correctly to the popped node
+	 */
+	int (*push_back_task)(struct starpu_sched_node *,
+			 struct starpu_task *);
 	/* this function is an heuristic that compute load of subtree, basicaly
 	 * it compute
 	 * estimated_load(node) = sum(estimated_load(node_childs)) +
@@ -99,6 +105,9 @@ struct starpu_sched_node
 	 */
 	int properties;
 
+	void (*room)(struct starpu_sched_node * node, unsigned sched_ctx_id);
+	int (*avail)(struct starpu_sched_node * node);
+
 #ifdef STARPU_HAVE_HWLOC
 	/* in case of a hierarchical scheduler, this is set to the part of
 	 * topology that is binded to this node, eg: a numa node for a ws
@@ -128,8 +137,6 @@ struct starpu_sched_tree
 	starpu_pthread_mutex_t lock;
 };
 
-
-
 struct starpu_sched_node * starpu_sched_node_create(void);
 
 void starpu_sched_node_destroy(struct starpu_sched_node * node);
@@ -154,9 +161,24 @@ int starpu_sched_node_is_simple_worker(struct starpu_sched_node * node);
 int starpu_sched_node_is_combined_worker(struct starpu_sched_node * node);
 int starpu_sched_node_worker_get_workerid(struct starpu_sched_node * worker_node);
 
-struct starpu_sched_node * starpu_sched_node_fifo_create(void * arg STARPU_ATTRIBUTE_UNUSED);
+struct starpu_fifo_data
+{
+	unsigned ntasks_threshold;
+	double exp_len_threshold;
+};
+
+struct starpu_sched_node * starpu_sched_node_fifo_create(struct starpu_fifo_data * fifo_data);
 int starpu_sched_node_is_fifo(struct starpu_sched_node * node);
 
+struct starpu_prio_data
+{
+	unsigned ntasks_threshold;
+	double exp_len_threshold;
+};
+
+struct starpu_sched_node * starpu_sched_node_prio_create(struct starpu_prio_data * prio_data);
+int starpu_sched_node_is_prio(struct starpu_sched_node * node);
+
 struct starpu_sched_node * starpu_sched_node_work_stealing_create(void * arg STARPU_ATTRIBUTE_UNUSED);
 int starpu_sched_node_is_work_stealing(struct starpu_sched_node * node);
 int starpu_sched_tree_work_stealing_push_task(struct starpu_task *task);
@@ -171,10 +193,6 @@ struct starpu_heft_data
 	double beta;
 	double gamma;
 	double idle_power;
-	struct starpu_sched_node * (*no_perf_model_node_create)(void * arg_no_perf_model);
-	void * arg_no_perf_model;
-	struct starpu_sched_node * (*calibrating_node_create)(void * arg_calibrating_node);
-	void * arg_calibrating_node;
 };
 
 /* create a node with heft_data paremeters
@@ -191,6 +209,17 @@ int starpu_sched_node_is_heft(struct starpu_sched_node * node);
  */
 struct starpu_sched_node * starpu_sched_node_best_implementation_create(void * arg STARPU_ATTRIBUTE_UNUSED);
 
+struct starpu_calibrator_data
+{
+	struct starpu_sched_node * (*no_perf_model_node_create)(void * arg_no_perf_model);
+	void * arg_no_perf_model;
+	struct starpu_sched_node * next_node;
+};
+
+struct starpu_sched_node * starpu_sched_node_calibrator_create(struct starpu_calibrator_data * calibrator_data);
+int starpu_sched_node_is_calibrator(struct starpu_sched_node * node);
+int starpu_sched_node_calibrator_room(struct starpu_sched_node * node, unsigned sched_ctx_id);
+
 /*create an empty tree
  */
 struct starpu_sched_tree * starpu_sched_tree_create(unsigned sched_ctx_id);

+ 8 - 2
src/Makefile.am

@@ -247,11 +247,17 @@ libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES = 		\
 	sched_policies/node_fifo.c 				\
 	sched_policies/node_work_stealing.c			\
 	sched_policies/prio_deque.c				\
+	sched_policies/node_prio.c 				\
 	sched_policies/node_random.c				\
 	sched_policies/node_heft.c				\
-	sched_policies/node_composed.c				\
 	sched_policies/node_best_implementation.c		\
-	sched_policies/hierarchical_heft.c			\
+	sched_policies/node_calibrator.c				\
+	sched_policies/node_composed.c				\
+	sched_policies/tree_eager.c				\
+	sched_policies/tree_prio.c				\
+	sched_policies/tree_random.c				\
+	sched_policies/tree_ws.c				\
+	sched_policies/tree_dmda.c				\
 	sched_policies/scheduler_maker.c			
 
 

+ 11 - 0
src/common/fxt.h

@@ -146,6 +146,9 @@
 #define	_STARPU_FUT_START_WRITEBACK	0x5158
 #define	_STARPU_FUT_END_WRITEBACK	0x5159
 
+#define _STARPU_FUT_SCHED_NODE_PUSH_PRIO 	0x515a
+#define _STARPU_FUT_SCHED_NODE_POP_PRIO 	0x515b
+
 #ifdef STARPU_USE_FXT
 #include <fxt/fxt.h>
 #include <fxt/fut.h>
@@ -607,6 +610,12 @@ do {										\
 #define _STARPU_TRACE_END_UNPARTITION(handle, memnode)		\
 	FUT_DO_PROBE3(_STARPU_FUT_END_UNPARTITION, memnode, _starpu_gettid(), handle);
 
+#define _STARPU_TRACE_SCHED_NODE_PUSH_PRIO(workerid, ntasks, exp_len)		\
+	FUT_DO_PROBE4(_STARPU_FUT_SCHED_NODE_PUSH_PRIO, _starpu_gettid(), workerid, ntasks, exp_len);
+
+#define _STARPU_TRACE_SCHED_NODE_POP_PRIO(workerid, ntasks, exp_len)		\
+	FUT_DO_PROBE4(_STARPU_FUT_SCHED_NODE_POP_PRIO, _starpu_gettid(), workerid, ntasks, exp_len);
+
 #else // !STARPU_USE_FXT
 
 /* Dummy macros in case FxT is disabled */
@@ -678,6 +687,8 @@ do {										\
 #define _STARPU_TRACE_MEMORY_FULL(size)				do {} while(0)
 #define _STARPU_TRACE_START_UNPARTITION(handle, memnode)	do {} while(0)
 #define _STARPU_TRACE_END_UNPARTITION(handle, memnode)		do {} while(0)
+#define _STARPU_TRACE_SCHED_NODE_PUSH_PRIO(workerid, ntasks, exp_len)	do {} while(0)
+#define _STARPU_TRACE_SCHED_NODE_POP_PRIO(workerid, ntasks, exp_len)	do {} while(0)
 
 #endif // STARPU_USE_FXT
 

+ 2 - 4
src/core/sched_policy.c

@@ -33,13 +33,11 @@ int starpu_get_prefetch_flag(void)
 
 static struct starpu_sched_policy *predefined_policies[] =
 {
-#ifdef STARPU_HAVE_HWLOC
-	&_starpu_sched_tree_heft_hierarchical_policy,
-#endif
 	&_starpu_sched_tree_eager_policy,
+	&_starpu_sched_tree_prio_policy,
 	&_starpu_sched_tree_random_policy,
 	&_starpu_sched_tree_ws_policy,
-	&_starpu_sched_tree_heft_policy,
+	&_starpu_sched_tree_dmda_policy,
 	&_starpu_sched_eager_policy,
 	&_starpu_sched_prio_policy,
 	&_starpu_sched_random_policy,

+ 2 - 2
src/core/sched_policy.h

@@ -68,8 +68,8 @@ extern struct starpu_sched_policy _starpu_sched_eager_policy;
 extern struct starpu_sched_policy _starpu_sched_parallel_heft_policy;
 extern struct starpu_sched_policy _starpu_sched_peager_policy;
 extern struct starpu_sched_policy _starpu_sched_tree_eager_policy;
+extern struct starpu_sched_policy _starpu_sched_tree_prio_policy;
 extern struct starpu_sched_policy _starpu_sched_tree_random_policy;
 extern struct starpu_sched_policy _starpu_sched_tree_ws_policy;
-extern struct starpu_sched_policy _starpu_sched_tree_heft_policy;
-extern struct starpu_sched_policy _starpu_sched_tree_heft_hierarchical_policy;
+extern struct starpu_sched_policy _starpu_sched_tree_dmda_policy;
 #endif // __SCHED_POLICY_H__

+ 6 - 0
src/debug/traces/starpu_fxt.c

@@ -1673,6 +1673,12 @@ void starpu_fxt_parse_new_file(char *filename_in, struct starpu_fxt_options *opt
 			case _STARPU_FUT_MEMORY_FULL:
 				break;
 
+			case _STARPU_FUT_SCHED_NODE_POP_PRIO:
+				break;
+
+			case _STARPU_FUT_SCHED_NODE_PUSH_PRIO:
+				break;
+
 			default:
 #ifdef STARPU_VERBOSE
 				fprintf(stderr, "unknown event.. %x at time %llx WITH OFFSET %llx\n",

+ 0 - 2
src/sched_policies/node_best_implementation.c

@@ -72,8 +72,6 @@ static void select_best_implementation_and_set_preds(struct starpu_bitmap * work
 }
 
 
-
-
 static int select_best_implementation_push_task(struct starpu_sched_node * node, struct starpu_task * task)
 {
 	STARPU_ASSERT(node->nchilds == 1);

+ 148 - 0
src/sched_policies/node_calibrator.c

@@ -0,0 +1,148 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2013  Marc Sergent
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#include <starpu_sched_node.h>
+#include <starpu_scheduler.h>
+
+struct _starpu_calibrator_data
+{
+	struct starpu_sched_node * no_perf_model_node;
+	struct starpu_sched_node * next_node;
+};
+
+static int calibrator_push_task(struct starpu_sched_node * node, struct starpu_task * task)
+{
+	STARPU_ASSERT(node && node->data && task && starpu_sched_node_is_calibrator(node));
+	STARPU_ASSERT(starpu_sched_node_can_execute_task(node,task));
+
+	struct _starpu_calibrator_data * data = node->data;
+	starpu_task_bundle_t bundle = task->bundle;
+	
+
+	int workerid;
+	for(workerid = starpu_bitmap_first(node->workers_in_ctx);
+	    workerid != -1;
+	    workerid = starpu_bitmap_next(node->workers_in_ctx, workerid))
+	{
+		struct starpu_perfmodel_arch* archtype = starpu_worker_get_perf_archtype(workerid);
+		int nimpl;
+		for(nimpl = 0; nimpl < STARPU_MAXIMPLEMENTATIONS; nimpl++)
+		{
+			if(starpu_worker_can_execute_task(workerid,task,nimpl)
+			   || starpu_combined_worker_can_execute_task(workerid, task, nimpl))
+			{
+				double d;
+
+				if(bundle)
+					d = starpu_task_bundle_expected_length(bundle, archtype, nimpl);
+				else
+					d = starpu_task_expected_length(task, archtype, nimpl);
+
+				if(isnan(d))
+				{
+					int i;
+					for (i = 0; i < node->nchilds; i++)
+					{
+						int idworker;
+						for(idworker = starpu_bitmap_first(node->childs[i]->workers);
+							idworker != -1;
+							idworker = starpu_bitmap_next(node->childs[i]->workers, idworker))
+						{
+							if (idworker == workerid)
+								return node->childs[i]->push_task(node->childs[i],task);
+						}
+					}
+				}
+				if(_STARPU_IS_ZERO(d))
+					return data->no_perf_model_node->push_task(data->no_perf_model_node,task);
+			}
+		}
+	}
+
+	return data->next_node->push_task(data->next_node,task);
+}
+
+int starpu_sched_node_is_calibrator(struct starpu_sched_node * node)
+{
+	return node->push_task == calibrator_push_task;
+}
+
+void calibrator_add_child(struct starpu_sched_node * node, struct starpu_sched_node * child)
+{
+	STARPU_ASSERT(starpu_sched_node_is_calibrator(node));
+	starpu_sched_node_add_child(node, child);
+	struct _starpu_calibrator_data * data = node->data;
+	starpu_sched_node_add_child(data->no_perf_model_node,child);
+	starpu_sched_node_add_child(data->next_node, child);
+}
+
+void calibrator_remove_child(struct starpu_sched_node * node, struct starpu_sched_node * child)
+{
+
+	STARPU_ASSERT(starpu_sched_node_is_calibrator(node));
+	starpu_sched_node_remove_child(node, child);
+	struct _starpu_calibrator_data * data = node->data;
+	starpu_sched_node_remove_child(data->no_perf_model_node,child);
+	starpu_sched_node_remove_child(data->next_node, child);
+}
+
+static void calibrator_notify_change_in_workers(struct starpu_sched_node * node)
+{
+	STARPU_ASSERT(starpu_sched_node_is_calibrator(node));
+	struct _starpu_calibrator_data * data = node->data;
+	starpu_bitmap_unset_all(data->no_perf_model_node->workers_in_ctx);
+	starpu_bitmap_unset_all(data->no_perf_model_node->workers);
+
+	starpu_bitmap_or(data->no_perf_model_node->workers_in_ctx, node->workers_in_ctx);
+	starpu_bitmap_or(data->no_perf_model_node->workers, node->workers);
+
+	data->no_perf_model_node->properties = node->properties;
+
+	starpu_bitmap_unset_all(data->next_node->workers_in_ctx);
+	starpu_bitmap_unset_all(data->next_node->workers);
+
+	starpu_bitmap_or(data->next_node->workers_in_ctx, node->workers_in_ctx);
+	starpu_bitmap_or(data->next_node->workers, node->workers);
+
+	data->next_node->properties = node->properties;
+}
+
+void calibrator_node_deinit_data(struct starpu_sched_node * node)
+
+{
+	STARPU_ASSERT(node && node->data);
+	struct _starpu_calibrator_data * d = node->data;
+	starpu_sched_node_destroy(d->no_perf_model_node);
+	starpu_sched_node_destroy(d->next_node);
+	free(d);
+}
+
+struct starpu_sched_node * starpu_sched_node_calibrator_create(struct starpu_calibrator_data * params)
+{
+	STARPU_ASSERT(params);
+	struct starpu_sched_node * node = starpu_sched_node_create();
+	struct _starpu_calibrator_data * data = malloc(sizeof(*data));
+	data->no_perf_model_node = params->no_perf_model_node_create(params->arg_no_perf_model);
+	data->next_node = params->next_node;
+	node->data = data;
+	node->push_task = calibrator_push_task;
+	node->add_child = calibrator_add_child;
+	node->remove_child = calibrator_remove_child;
+	node->deinit_data = calibrator_node_deinit_data;
+	node->notify_change_workers = calibrator_notify_change_in_workers;
+
+	return node;
+}

+ 56 - 67
src/sched_policies/node_fifo.c

@@ -17,20 +17,22 @@
 #include <starpu_sched_node.h>
 #include <starpu_scheduler.h>
 
-#include "prio_deque.h"
+#include "fifo_queues.h"
 
 
 struct _starpu_fifo_data
 {
-	struct _starpu_prio_deque fifo;
+	struct _starpu_fifo_taskq * fifo;
 	starpu_pthread_mutex_t mutex;
+	unsigned ntasks_threshold;
+	double exp_len_threshold;
 };
 
 void fifo_node_deinit_data(struct starpu_sched_node * node)
 {
 	STARPU_ASSERT(node && node->data);
 	struct _starpu_fifo_data * f = node->data;
-	_starpu_prio_deque_destroy(&f->fifo);
+	_starpu_destroy_fifo(f->fifo);
 	STARPU_PTHREAD_MUTEX_DESTROY(&f->mutex);
 	free(f);
 }
@@ -39,7 +41,7 @@ static double fifo_estimated_end(struct starpu_sched_node * node)
 {
 	STARPU_ASSERT(node && node->data);
 	struct _starpu_fifo_data * data = node->data;
-	struct _starpu_prio_deque * fifo = &data->fifo;
+	struct _starpu_fifo_taskq * fifo = data->fifo;
 	starpu_pthread_mutex_t * mutex = &data->mutex;
 	int card = starpu_bitmap_cardinal(node->workers_in_ctx);
 	STARPU_ASSERT(card != 0);
@@ -56,7 +58,7 @@ static double fifo_estimated_load(struct starpu_sched_node * node)
 	STARPU_ASSERT(node && node->data);
 	STARPU_ASSERT(starpu_bitmap_cardinal(node->workers_in_ctx) != 0);
 	struct _starpu_fifo_data * data = node->data;
-	struct _starpu_prio_deque * fifo = &data->fifo;
+	struct _starpu_fifo_taskq * fifo = data->fifo;
 	starpu_pthread_mutex_t * mutex = &data->mutex;
 	double relative_speedup = 0.0;
 	double load;
@@ -96,33 +98,54 @@ static int fifo_push_task(struct starpu_sched_node * node, struct starpu_task *
 	STARPU_ASSERT(node && node->data && task);
 	STARPU_ASSERT(starpu_sched_node_can_execute_task(node,task));
 	struct _starpu_fifo_data * data = node->data;
-	struct _starpu_prio_deque * fifo = &data->fifo;
+	struct _starpu_fifo_taskq * fifo = data->fifo;
 	starpu_pthread_mutex_t * mutex = &data->mutex;
+	int ret;
+
 	STARPU_PTHREAD_MUTEX_LOCK(mutex);
-	int ret = _starpu_prio_deque_push_task(fifo, task);
+	double exp_len;
 	if(!isnan(task->predicted))
+		exp_len = fifo->exp_len + task->predicted;
+	else
+		exp_len = fifo->exp_len;
+
+	if((data->ntasks_threshold != 0) && (data->exp_len_threshold != 0.0) && 
+			((fifo->ntasks >= data->ntasks_threshold) || (exp_len >= data->exp_len_threshold)))
 	{
-		fifo->exp_len += task->predicted;
-		fifo->exp_end = fifo->exp_start + fifo->exp_len;
+		ret = 1;
+		STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
 	}
-	STARPU_ASSERT(!isnan(fifo->exp_end));
-	STARPU_ASSERT(!isnan(fifo->exp_len));
-	STARPU_ASSERT(!isnan(fifo->exp_start));
-	STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
-
-	starpu_sched_node_wake_available_worker(node,task);
+	else
+	{
+		ret = _starpu_fifo_push_task(fifo,task);
+		if(!isnan(task->predicted))
+		{
+			fifo->exp_len += exp_len;
+			fifo->exp_end = fifo->exp_start + fifo->exp_len;
+		}
+		STARPU_ASSERT(!isnan(fifo->exp_end));
+		STARPU_ASSERT(!isnan(fifo->exp_len));
+		STARPU_ASSERT(!isnan(fifo->exp_start));
+		STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
 
+		node->avail(node);
+	}
 	return ret;
 }
 
+int starpu_sched_node_is_fifo(struct starpu_sched_node * node)
+{
+	return node->push_task == fifo_push_task;
+}
+
 static struct starpu_task * fifo_pop_task(struct starpu_sched_node * node, unsigned sched_ctx_id)
 {
 	STARPU_ASSERT(node && node->data);
 	struct _starpu_fifo_data * data = node->data;
-	struct _starpu_prio_deque * fifo = &data->fifo;
+	struct _starpu_fifo_taskq * fifo = data->fifo;
 	starpu_pthread_mutex_t * mutex = &data->mutex;
 	STARPU_PTHREAD_MUTEX_LOCK(mutex);
-	struct starpu_task * task = _starpu_prio_deque_pop_task_for_worker(fifo, starpu_worker_get_id());
+	struct starpu_task * task = _starpu_fifo_pop_task(fifo, starpu_worker_get_id());
 	if(task)
 	{
 		if(!isnan(task->predicted))
@@ -138,73 +161,39 @@ static struct starpu_task * fifo_pop_task(struct starpu_sched_node * node, unsig
 	STARPU_ASSERT(!isnan(fifo->exp_len));
 	STARPU_ASSERT(!isnan(fifo->exp_start));
 	STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
+
+	node->room(node, sched_ctx_id);
+	
 	if(task)
 		return task;
-	struct starpu_sched_node * father = node->fathers[sched_ctx_id];
-	if(father)
-		return father->pop_task(father,sched_ctx_id);
-	return NULL;
-}
 
-int starpu_sched_node_is_fifo(struct starpu_sched_node * node)
-{
-	return node->push_task == fifo_push_task;
+	return NULL;
 }
 
-struct starpu_sched_node * starpu_sched_node_fifo_create(void * arg STARPU_ATTRIBUTE_UNUSED)
+struct starpu_sched_node * starpu_sched_node_fifo_create(struct starpu_fifo_data * params)
 {
 	struct starpu_sched_node * node = starpu_sched_node_create();
 	struct _starpu_fifo_data * data = malloc(sizeof(*data));
-	_starpu_prio_deque_init(&data->fifo);
+	data->fifo = _starpu_create_fifo();
 	STARPU_PTHREAD_MUTEX_INIT(&data->mutex,NULL);
 	node->data = data;
 	node->estimated_end = fifo_estimated_end;
 	node->estimated_load = fifo_estimated_load;
 	node->push_task = fifo_push_task;
+	node->push_back_task = fifo_push_task;
 	node->pop_task = fifo_pop_task;
 	node->deinit_data = fifo_node_deinit_data;
-	return node;
-}
-
-
 
-
-static void initialize_eager_center_policy(unsigned sched_ctx_id)
-{
-	starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
-	struct starpu_sched_tree *t = starpu_sched_tree_create(sched_ctx_id);
- 	t->root = starpu_sched_node_fifo_create(NULL);
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
+	if(params)
 	{
-		struct starpu_sched_node * node = starpu_sched_node_worker_get(i);
-		if(!node)
-			continue;
-		node->fathers[sched_ctx_id] = t->root;
-		t->root->add_child(t->root, node);
+		data->ntasks_threshold=params->ntasks_threshold;
+		data->exp_len_threshold=params->exp_len_threshold;
+	}
+	else
+	{
+		data->ntasks_threshold=0;
+		data->exp_len_threshold=0.0;
 	}
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
-}
 
-static void deinitialize_eager_center_policy(unsigned sched_ctx_id)
-{
-	struct starpu_sched_tree *tree = (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	starpu_sched_tree_destroy(tree);
-	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
+	return node;
 }
-
-struct starpu_sched_policy _starpu_sched_tree_eager_policy =
-{
-	.init_sched = initialize_eager_center_policy,
-	.deinit_sched = deinitialize_eager_center_policy,
-	.add_workers = starpu_sched_tree_add_workers,
-	.remove_workers = starpu_sched_tree_remove_workers,
-	.push_task = starpu_sched_tree_push_task,
-	.pop_task = starpu_sched_tree_pop_task,
-	.pre_exec_hook = starpu_sched_node_worker_pre_exec_hook,
-	.post_exec_hook = starpu_sched_node_worker_post_exec_hook,
-	.pop_every_task = NULL,//pop_every_task_eager_policy,
-	.policy_name = "tree",
-	.policy_description = "test tree policy"
-};

+ 25 - 205
src/sched_policies/node_heft.c

@@ -1,19 +1,30 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2013  Simon Archipoff
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
 #include <starpu_sched_node.h>
-#include "fifo_queues.h"
 #include "sched_node.h"
 #include <starpu_perfmodel.h>
-#include <starpu_scheduler.h>
 #include <float.h>
 
-
 struct _starpu_heft_data
 {
 	double alpha;
 	double beta;
 	double gamma;
 	double idle_power;
-	struct starpu_sched_node * no_perf_model_node;
-	struct starpu_sched_node * calibrating_node;
 };
 
 /* compute predicted_end by taking into account the case of the predicted transfer and the predicted_end overlap
@@ -75,10 +86,6 @@ static int heft_push_task(struct starpu_sched_node * node, struct starpu_task *
 		struct starpu_sched_node * c = node->childs[i];
 		if(starpu_sched_node_execute_preds(c, task, estimated_lengths + i))
 		{
-			if(isnan(estimated_lengths[i]))
-				return d->calibrating_node->push_task(d->calibrating_node, task);
-			if(_STARPU_IS_ZERO(estimated_lengths[i]))
-				return d->no_perf_model_node->push_task(d->no_perf_model_node, task);
 			estimated_transfer_length[i] = starpu_sched_node_transfer_length(c, task);
 			estimated_ends[i] = c->estimated_end(c);
 			double now = starpu_timing_now();
@@ -119,95 +126,26 @@ static int heft_push_task(struct starpu_sched_node * node, struct starpu_task *
 	STARPU_ASSERT(best_inode != -1);
 	best_node = node->childs[best_inode];
 
-    starpu_sched_node_prefetch_on_node(best_node, task);
-
-	return best_node->push_task(best_node, task);
-}
-
-
-
-#define _STARPU_SCHED_ALPHA_DEFAULT 1.0
-#define _STARPU_SCHED_BETA_DEFAULT 1.0
-#define _STARPU_SCHED_GAMMA_DEFAULT 1000.0
-static double alpha = _STARPU_SCHED_ALPHA_DEFAULT;
-static double beta = _STARPU_SCHED_BETA_DEFAULT;
-static double _gamma = _STARPU_SCHED_GAMMA_DEFAULT;
-
-#ifdef STARPU_USE_TOP
-static const float alpha_minimum=0;
-static const float alpha_maximum=10.0;
-static const float beta_minimum=0;
-static const float beta_maximum=10.0;
-static const float gamma_minimum=0;
-static const float gamma_maximum=10000.0;
-static const float idle_power_minimum=0;
-static const float idle_power_maximum=10000.0;
-#endif /* !STARPU_USE_TOP */
+	int ret = best_node->push_task(best_node, task);
 
-static double idle_power = 0.0;
+	if(!ret)
+		starpu_sched_node_prefetch_on_node(best_node, task);
 
-#ifdef STARPU_USE_TOP
-static void param_modified(struct starpu_top_param* d)
-{
-#ifdef STARPU_DEVEL
-#warning FIXME: get sched ctx to get alpha/beta/gamma/idle values
-#endif
-	/* Just to show parameter modification. */
-	fprintf(stderr,
-		"%s has been modified : "
-		"alpha=%f|beta=%f|gamma=%f|idle_power=%f !\n",
-		d->name, alpha,beta,_gamma, idle_power);
+	return ret;
 }
-#endif /* !STARPU_USE_TOP */
 
-void heft_add_child(struct starpu_sched_node * node, struct starpu_sched_node * child)
+void heft_node_deinit_data(struct starpu_sched_node * node)
 {
 	STARPU_ASSERT(starpu_sched_node_is_heft(node));
-	starpu_sched_node_add_child(node, child);
-	struct _starpu_heft_data * data = node->data;
-	starpu_sched_node_add_child(data->no_perf_model_node,child);
-	starpu_sched_node_add_child(data->calibrating_node, child);
+	struct _starpu_heft_data * d = node->data;
+	free(d);
 }
 
-void heft_remove_child(struct starpu_sched_node * node, struct starpu_sched_node * child)
+int starpu_sched_node_is_heft(struct starpu_sched_node * node)
 {
-
-	STARPU_ASSERT(starpu_sched_node_is_heft(node));
-	starpu_sched_node_remove_child(node, child);
-	struct _starpu_heft_data * data = node->data;
-	starpu_sched_node_remove_child(data->no_perf_model_node,child);
-	starpu_sched_node_remove_child(data->calibrating_node, child);
+	return node->push_task == heft_push_task;
 }
 
-static void heft_notify_change_in_workers(struct starpu_sched_node * node)
-{
-	STARPU_ASSERT(starpu_sched_node_is_heft(node));
-	struct _starpu_heft_data * data = node->data;
-	starpu_bitmap_unset_all(data->no_perf_model_node->workers_in_ctx);
-	starpu_bitmap_unset_all(data->no_perf_model_node->workers);
-
-	starpu_bitmap_or(data->no_perf_model_node->workers_in_ctx, node->workers_in_ctx);
-	starpu_bitmap_or(data->no_perf_model_node->workers, node->workers);
-
-	data->no_perf_model_node->properties = node->properties;
-
-
-	starpu_bitmap_unset_all(data->calibrating_node->workers_in_ctx);
-	starpu_bitmap_unset_all(data->calibrating_node->workers);
-
-	starpu_bitmap_or(data->calibrating_node->workers_in_ctx, node->workers_in_ctx);
-	starpu_bitmap_or(data->calibrating_node->workers, node->workers);
-
-	data->calibrating_node->properties = node->properties;
-}
-void heft_node_deinit_data(struct starpu_sched_node * node)
-{
-	STARPU_ASSERT(starpu_sched_node_is_heft(node));
-	struct _starpu_heft_data * d = node->data;
-	starpu_sched_node_destroy(d->no_perf_model_node);
-	starpu_sched_node_destroy(d->calibrating_node);
-	free(d);
-}
 struct starpu_sched_node * starpu_sched_node_heft_create(struct starpu_heft_data * params)
 {
 	struct starpu_sched_node * node = starpu_sched_node_create();
@@ -218,128 +156,10 @@ struct starpu_sched_node * starpu_sched_node_heft_create(struct starpu_heft_data
 	data->gamma = params->gamma;
 	data->idle_power = params->idle_power;
 
-	data->no_perf_model_node = params->no_perf_model_node_create(params->arg_no_perf_model);
-
-	data->calibrating_node = params->calibrating_node_create(params->arg_calibrating_node);
-
 	node->data = data;
 
 	node->push_task = heft_push_task;
-	node->add_child = heft_add_child;
-	node->remove_child = heft_remove_child;
 	node->deinit_data = heft_node_deinit_data;
-	node->notify_change_workers = heft_notify_change_in_workers;
 
 	return node;
 }
-
-int starpu_sched_node_is_heft(struct starpu_sched_node * node)
-{
-	return node->push_task == heft_push_task;
-}
-
-
-/* initialize a policy that look like that :
- *     | heft |
- *       /  \
- * | best || best | ...
- * | impl || impl | ...
- *     |      |     ...
- * | fifo || fifo | ...
- *     |      |     ...
- * |worker||worker| ...
- */
-static void initialize_heft_center_policy(unsigned sched_ctx_id)
-{
-	starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
-	const char *strval_alpha = getenv("STARPU_SCHED_ALPHA");
-	if (strval_alpha)
-		alpha = atof(strval_alpha);
-
-	const char *strval_beta = getenv("STARPU_SCHED_BETA");
-	if (strval_beta)
-		beta = atof(strval_beta);
-
-	const char *strval_gamma = getenv("STARPU_SCHED_GAMMA");
-	if (strval_gamma)
-		_gamma = atof(strval_gamma);
-
-	const char *strval_idle_power = getenv("STARPU_IDLE_POWER");
-	if (strval_idle_power)
-		idle_power = atof(strval_idle_power);
-
-#ifdef STARPU_USE_TOP
-	starpu_top_register_parameter_float("DMDA_ALPHA", &alpha,
-					    alpha_minimum, alpha_maximum, param_modified);
-	starpu_top_register_parameter_float("DMDA_BETA", &beta,
-					    beta_minimum, beta_maximum, param_modified);
-	starpu_top_register_parameter_float("DMDA_GAMMA", &_gamma,
-					    gamma_minimum, gamma_maximum, param_modified);
-	starpu_top_register_parameter_float("DMDA_IDLE_POWER", &idle_power,
-					    idle_power_minimum, idle_power_maximum, param_modified);
-#endif /* !STARPU_USE_TOP */
-
-	
-	struct starpu_sched_tree * t = starpu_sched_tree_create(sched_ctx_id);
-	struct starpu_heft_data data =
-		{
-			.alpha = alpha,
-			.beta = beta,
-			.gamma = _gamma,
-			.idle_power = idle_power,
-			.no_perf_model_node_create = starpu_sched_node_random_create,
-			.arg_no_perf_model = NULL,
-			.calibrating_node_create = starpu_sched_node_random_create,
-			.arg_calibrating_node = NULL
-		};
-	t->root = starpu_sched_node_heft_create(&data);
-	
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-	{
-		struct starpu_sched_node * worker_node = starpu_sched_node_worker_get(i);
-		STARPU_ASSERT(worker_node);
-
-#if 1
-		struct starpu_sched_node * fifo = starpu_sched_node_fifo_create(NULL);
-		fifo->add_child(fifo, worker_node);
-		starpu_sched_node_set_father(worker_node, fifo, sched_ctx_id);
-		worker_node = fifo;
-#endif
-
-		struct starpu_sched_node * impl_node = starpu_sched_node_best_implementation_create(NULL);
-		impl_node->add_child(impl_node, worker_node);
-		starpu_sched_node_set_father(worker_node, impl_node, sched_ctx_id);
-
-		t->root->add_child(t->root, impl_node);
-		starpu_sched_node_set_father(impl_node, t->root, sched_ctx_id);
-	}
-
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
-}
-
-static void deinitialize_heft_center_policy(unsigned sched_ctx_id)
-{
-	struct starpu_sched_tree *t = (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	starpu_sched_tree_destroy(t);
-	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
-}
-
-
-
-
-struct starpu_sched_policy _starpu_sched_tree_heft_policy =
-{
-	.init_sched = initialize_heft_center_policy,
-	.deinit_sched = deinitialize_heft_center_policy,
-	.add_workers = starpu_sched_tree_add_workers,
-	.remove_workers = starpu_sched_tree_remove_workers,
-	.push_task = starpu_sched_tree_push_task,
-	.pop_task = starpu_sched_tree_pop_task,
-	.pre_exec_hook = starpu_sched_node_worker_pre_exec_hook,
-	.post_exec_hook = starpu_sched_node_worker_post_exec_hook,
-	.pop_every_task = NULL,
-	.policy_name = "tree-heft",
-	.policy_description = "heft tree policy"
-};

+ 294 - 0
src/sched_policies/node_prio.c

@@ -0,0 +1,294 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2013  Marc Sergent
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#include <starpu_sched_node.h>
+#include <starpu_scheduler.h>
+
+#include "prio_deque.h"
+
+#define STARPU_TRACE_SCHED_NODE_PUSH_PRIO(node,ntasks,exp_len) do {                                 \
+	int workerid = STARPU_NMAXWORKERS + 1;									\
+	if((node->nchilds == 1) && starpu_sched_node_is_worker(node->childs[0])) \
+		workerid = starpu_sched_node_worker_get_workerid(node->childs[0]); \
+	_STARPU_TRACE_SCHED_NODE_PUSH_PRIO(workerid, ntasks, exp_len); \
+} while (0)
+
+#define STARPU_TRACE_SCHED_NODE_POP_PRIO(node,ntasks,exp_len) do {                                 \
+	int workerid = STARPU_NMAXWORKERS + 1;									\
+	if((node->nchilds == 1) && starpu_sched_node_is_worker(node->childs[0])) \
+		workerid = starpu_sched_node_worker_get_workerid(node->childs[0]); \
+	_STARPU_TRACE_SCHED_NODE_POP_PRIO(workerid, ntasks, exp_len); \
+} while (0)
+
+
+struct _starpu_prio_data
+{
+	struct _starpu_prio_deque prio;
+	starpu_pthread_mutex_t mutex;
+	unsigned ntasks_threshold;
+	double exp_len_threshold;
+};
+
+void prio_node_deinit_data(struct starpu_sched_node * node)
+{
+	STARPU_ASSERT(node && node->data);
+	struct _starpu_prio_data * f = node->data;
+	_starpu_prio_deque_destroy(&f->prio);
+	STARPU_PTHREAD_MUTEX_DESTROY(&f->mutex);
+	free(f);
+}
+
+static double prio_estimated_end(struct starpu_sched_node * node)
+{
+	STARPU_ASSERT(node && node->data);
+	struct _starpu_prio_data * data = node->data;
+	struct _starpu_prio_deque * prio = &data->prio;
+	starpu_pthread_mutex_t * mutex = &data->mutex;
+	int card = starpu_bitmap_cardinal(node->workers_in_ctx);
+	STARPU_ASSERT(card != 0);
+	STARPU_PTHREAD_MUTEX_LOCK(mutex);
+	prio->exp_start = STARPU_MAX(prio->exp_start, starpu_timing_now());
+	double estimated_end = prio->exp_start + prio->exp_len / card;
+	STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
+
+	return estimated_end;
+}
+
+static double prio_estimated_load(struct starpu_sched_node * node)
+{
+	STARPU_ASSERT(node && node->data);
+	STARPU_ASSERT(starpu_bitmap_cardinal(node->workers_in_ctx) != 0);
+	struct _starpu_prio_data * data = node->data;
+	struct _starpu_prio_deque * prio = &data->prio;
+	starpu_pthread_mutex_t * mutex = &data->mutex;
+	double relative_speedup = 0.0;
+	double load;
+	if(STARPU_SCHED_NODE_IS_HOMOGENEOUS(node))
+	{		
+		int first_worker = starpu_bitmap_first(node->workers_in_ctx);
+		relative_speedup = starpu_worker_get_relative_speedup(starpu_worker_get_perf_archtype(first_worker));
+		STARPU_PTHREAD_MUTEX_LOCK(mutex);
+		load = prio->ntasks / relative_speedup;
+		STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
+		return load;
+	}
+	else
+	{
+		int i;
+		for(i = starpu_bitmap_first(node->workers_in_ctx);
+		    i != -1;
+		    i = starpu_bitmap_next(node->workers_in_ctx, i))
+			relative_speedup += starpu_worker_get_relative_speedup(starpu_worker_get_perf_archtype(i));
+		relative_speedup /= starpu_bitmap_cardinal(node->workers_in_ctx);
+		STARPU_ASSERT(!_STARPU_IS_ZERO(relative_speedup));
+		STARPU_PTHREAD_MUTEX_LOCK(mutex);
+		load = prio->ntasks / relative_speedup;
+		STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
+	}
+	int i;
+	for(i = 0; i < node->nchilds; i++)
+	{
+		struct starpu_sched_node * c = node->childs[i];
+		load += c->estimated_load(c);
+	}
+	return load;
+}
+
+static int prio_push_task(struct starpu_sched_node * node, struct starpu_task * task)
+{
+	STARPU_ASSERT(node && node->data && task);
+	STARPU_ASSERT(starpu_sched_node_can_execute_task(node,task));
+	struct _starpu_prio_data * data = node->data;
+	struct _starpu_prio_deque * prio = &data->prio;
+	starpu_pthread_mutex_t * mutex = &data->mutex;
+	int ret;
+
+	STARPU_ASSERT(node->nchilds == 1);
+	struct starpu_sched_node * child = node->childs[0];
+	if(starpu_sched_node_is_worker(child))
+		ret = 1;
+	else
+		ret = child->push_task(child,task);
+
+	if(ret)
+	{
+		STARPU_PTHREAD_MUTEX_LOCK(mutex);
+		double exp_len;
+		if(!isnan(task->predicted))
+			exp_len = prio->exp_len + task->predicted;
+		else
+			exp_len = prio->exp_len;
+
+		if((data->ntasks_threshold != 0) && (data->exp_len_threshold != 0.0) && 
+				((prio->ntasks >= data->ntasks_threshold) || (exp_len >= data->exp_len_threshold)))
+		{
+			/*
+			if(task->predicted > data->exp_len_threshold)
+			{
+				_STARPU_DISP("Warning : a predicted task length (%lf) exceeds the expected length threshold (%lf) of a prio node queue, you should reconsider the value of this thresold\n",task->predicted,data->exp_len_threshold);
+				data->exp_len_threshold *= 2;
+			}
+			*/
+			ret = 1;
+			STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
+		}
+		else
+		{
+			ret = _starpu_prio_deque_push_task(prio,task);
+			STARPU_TRACE_SCHED_NODE_PUSH_PRIO(node, prio->ntasks, exp_len);
+			if(!isnan(task->predicted))
+			{
+				prio->exp_len = exp_len;
+				prio->exp_end = prio->exp_start + prio->exp_len;
+			}
+			STARPU_ASSERT(!isnan(prio->exp_end));
+			STARPU_ASSERT(!isnan(prio->exp_len));
+			STARPU_ASSERT(!isnan(prio->exp_start));
+			STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
+
+			node->avail(node);
+		}
+	}
+	return ret;
+}
+
+static int prio_push_back_task(struct starpu_sched_node * node, struct starpu_task * task)
+{
+	STARPU_ASSERT(node && node->data && task);
+	STARPU_ASSERT(starpu_sched_node_can_execute_task(node,task));
+	struct _starpu_prio_data * data = node->data;
+	struct _starpu_prio_deque * prio = &data->prio;
+	starpu_pthread_mutex_t * mutex = &data->mutex;
+	int ret;
+
+	STARPU_ASSERT(node->nchilds == 1);
+	struct starpu_sched_node * child = node->childs[0];
+	if(starpu_sched_node_is_worker(child))
+		ret = 1;
+	else
+		ret = child->push_task(child,task);
+
+	if(ret)
+	{
+		STARPU_PTHREAD_MUTEX_LOCK(mutex);
+		double exp_len;
+		if(!isnan(task->predicted))
+			exp_len = prio->exp_len + task->predicted;
+		else
+			exp_len = prio->exp_len;
+
+		_starpu_prio_deque_push_back_task(prio,task);
+		STARPU_TRACE_SCHED_NODE_PUSH_PRIO(node, prio->ntasks, exp_len);
+		if(!isnan(task->predicted))
+		{
+			prio->exp_len = exp_len;
+			prio->exp_end = prio->exp_start + exp_len;
+		}
+		STARPU_ASSERT(!isnan(prio->exp_end));
+		STARPU_ASSERT(!isnan(prio->exp_len));
+		STARPU_ASSERT(!isnan(prio->exp_start));
+		STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
+
+		node->avail(node);
+	}
+	return ret;
+}
+
+int starpu_sched_node_is_prio(struct starpu_sched_node * node)
+{
+	return node->push_task == prio_push_task;
+}
+
+static struct starpu_task * prio_pop_task(struct starpu_sched_node * node, unsigned sched_ctx_id)
+{
+	STARPU_ASSERT(node && node->data);
+	struct _starpu_prio_data * data = node->data;
+	struct _starpu_prio_deque * prio = &data->prio;
+	starpu_pthread_mutex_t * mutex = &data->mutex;
+	STARPU_PTHREAD_MUTEX_LOCK(mutex);
+	struct starpu_task * task = _starpu_prio_deque_pop_task(prio);
+	if(task)
+	{
+		if(!isnan(task->predicted))
+		{
+			prio->exp_start = starpu_timing_now() + task->predicted;
+			prio->exp_len -= task->predicted;
+		}
+		prio->exp_end = prio->exp_start + prio->exp_len;
+		if(prio->ntasks == 0)
+			prio->exp_len = 0.0;
+		
+		STARPU_TRACE_SCHED_NODE_POP_PRIO(node, prio->ntasks, prio->exp_len);
+	}
+	STARPU_ASSERT(!isnan(prio->exp_end));
+	STARPU_ASSERT(!isnan(prio->exp_len));
+	STARPU_ASSERT(!isnan(prio->exp_start));
+	STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
+
+	struct starpu_sched_node * father = node->fathers[sched_ctx_id];
+	if(father != NULL)
+		father->room(father, sched_ctx_id);
+	
+	if(task)
+		return task;
+
+	return NULL;
+}
+
+static void prio_room(struct starpu_sched_node * node, unsigned sched_ctx_id)
+{
+	STARPU_ASSERT(node && starpu_sched_node_is_prio(node));
+	int ret = 0;
+
+	struct starpu_task * task = node->pop_task(node, sched_ctx_id);
+	if(task)
+		ret = node->push_back_task(node,task);	
+	while(task && !ret) 
+	{
+		task = node->pop_task(node, sched_ctx_id);
+		if(task)
+			ret = node->push_back_task(node,task);	
+	} 
+}
+
+struct starpu_sched_node * starpu_sched_node_prio_create(struct starpu_prio_data * params)
+{
+	struct starpu_sched_node * node = starpu_sched_node_create();
+	struct _starpu_prio_data * data = malloc(sizeof(*data));
+	_starpu_prio_deque_init(&data->prio);
+	STARPU_PTHREAD_MUTEX_INIT(&data->mutex,NULL);
+	node->data = data;
+	node->estimated_end = prio_estimated_end;
+	node->estimated_load = prio_estimated_load;
+	node->push_task = prio_push_task;
+	node->push_back_task = prio_push_back_task;
+	node->pop_task = prio_pop_task;
+	node->room = prio_room;
+	node->deinit_data = prio_node_deinit_data;
+
+	if(params)
+	{
+		data->ntasks_threshold=params->ntasks_threshold;
+		data->exp_len_threshold=params->exp_len_threshold;
+	}
+	else
+	{
+		data->ntasks_threshold=0;
+		data->exp_len_threshold=0.0;
+	}
+
+	return node;
+}

+ 0 - 42
src/sched_policies/node_random.c

@@ -112,45 +112,3 @@ int starpu_sched_node_is_random(struct starpu_sched_node *node)
 {
 	return node->push_task == random_push_task;
 }
-
-
-static void initialize_random_center_policy(unsigned sched_ctx_id)
-{
-	starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
-	struct starpu_sched_tree *t = starpu_sched_tree_create(sched_ctx_id);
- 	t->root = starpu_sched_node_random_create(NULL);
-
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
-	{
-		struct starpu_sched_node * node = starpu_sched_node_worker_get(i);
-		if(!node)
-			continue;
-		node->fathers[sched_ctx_id] = t->root;
-		t->root->add_child(t->root, node);
-	}
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
-}
-static void deinitialize_random_center_policy(unsigned sched_ctx_id)
-{
-	struct starpu_sched_tree *tree = (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	starpu_sched_tree_destroy(tree);
-	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
-}
-
-
-struct starpu_sched_policy _starpu_sched_tree_random_policy =
-{
-	.init_sched = initialize_random_center_policy,
-	.deinit_sched = deinitialize_random_center_policy,
-	.add_workers = starpu_sched_tree_add_workers,
-	.remove_workers = starpu_sched_tree_remove_workers,
-	.push_task = starpu_sched_tree_push_task,
-	.pop_task = starpu_sched_tree_pop_task,
-	.pre_exec_hook = NULL,
-	.post_exec_hook = NULL,
-	.pop_every_task = NULL,
-	.policy_name = "tree-random",
-	.policy_description = "random tree policy"
-};

+ 28 - 0
src/sched_policies/node_sched.c

@@ -474,6 +474,32 @@ void starpu_sched_node_prefetch_on_node(struct starpu_sched_node * node, struct
        }
 }
 
+void starpu_sched_node_room(struct starpu_sched_node * node, unsigned sched_ctx_id)
+{
+	STARPU_ASSERT(sched_ctx_id < STARPU_NMAX_SCHED_CTXS);
+	STARPU_ASSERT(node);
+	struct starpu_sched_node * father = node->fathers[sched_ctx_id];
+	if(father != NULL)
+		father->room(father, sched_ctx_id);
+}
+
+int starpu_sched_node_avail(struct starpu_sched_node * node)
+{
+	STARPU_ASSERT(node);
+	int ret;
+	if(node->nchilds > 0)
+	{
+		int i;
+		for(i = 0; i < node->nchilds; i++)
+		{
+			struct starpu_sched_node * child = node->childs[i];
+			ret = child->avail(child);
+			if(ret)
+				break;
+		}
+	}
+	return 0;
+}
 
 void take_node_and_does_nothing(struct starpu_sched_node * node STARPU_ATTRIBUTE_UNUSED)
 {
@@ -488,6 +514,8 @@ struct starpu_sched_node * starpu_sched_node_create(void)
 	node->add_child = starpu_sched_node_add_child;
 	node->remove_child = starpu_sched_node_remove_child;
 	node->pop_task = pop_task_node;
+	node->room = starpu_sched_node_room;
+	node->avail = starpu_sched_node_avail;
 	node->estimated_load = estimated_load;
 	node->estimated_end = _starpu_sched_node_estimated_end_min;
 	node->deinit_data = take_node_and_does_nothing;

+ 5 - 52
src/sched_policies/node_work_stealing.c

@@ -272,8 +272,6 @@ int starpu_sched_tree_work_stealing_push_task(struct starpu_task *task)
 }
 
 
-
-
 void _ws_add_child(struct starpu_sched_node * node, struct starpu_sched_node * child)
 {
 	struct _starpu_work_stealing_data * wsd = node->data;
@@ -329,6 +327,11 @@ void _work_stealing_node_deinit_data(struct starpu_sched_node * node)
 	free(node->data);
 }
 
+int starpu_sched_node_is_work_stealing(struct starpu_sched_node * node)
+{
+	return node->push_task == push_task;
+}
+
 struct starpu_sched_node * starpu_sched_node_work_stealing_create(void * arg STARPU_ATTRIBUTE_UNUSED)
 {
 	struct starpu_sched_node * node = starpu_sched_node_create();
@@ -344,53 +347,3 @@ struct starpu_sched_node * starpu_sched_node_work_stealing_create(void * arg STA
 	node->data = wsd;
 	return  node;
 }
-
-int starpu_sched_node_is_work_stealing(struct starpu_sched_node * node)
-{
-	return node->push_task == push_task;
-}
-
-
-
-static void initialize_ws_center_policy(unsigned sched_ctx_id)
-{
-	starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
-	struct starpu_sched_tree *t = starpu_sched_tree_create(sched_ctx_id);
-	struct starpu_sched_node * ws;
- 	t->root = ws = starpu_sched_node_work_stealing_create(NULL);
-	t->workers = starpu_bitmap_create();
-	unsigned i;
-	for(i = 0; i < starpu_worker_get_count(); i++)
-	{
-		struct starpu_sched_node * node = starpu_sched_node_worker_get(i);
-		if(!node)
-			continue;
-		node->fathers[sched_ctx_id] = ws;
-		ws->add_child(ws, node);
-	}
-	starpu_sched_tree_update_workers(t);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
-}
-
-static void deinitialize_ws_center_policy(unsigned sched_ctx_id)
-{
-	struct starpu_sched_tree *t = (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	starpu_sched_tree_destroy(t);
-	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
-}
-
-
-struct starpu_sched_policy _starpu_sched_tree_ws_policy =
-{
-	.init_sched = initialize_ws_center_policy,
-	.deinit_sched = deinitialize_ws_center_policy,
-	.add_workers = starpu_sched_tree_add_workers,
-	.remove_workers = starpu_sched_tree_remove_workers,
-	.push_task = starpu_sched_tree_work_stealing_push_task,
-	.pop_task = starpu_sched_tree_pop_task,
-	.pre_exec_hook = NULL,
-	.post_exec_hook = NULL,
-	.pop_every_task = NULL,
-	.policy_name = "tree-ws",
-	.policy_description = "work stealing tree policy"
-};

+ 7 - 5
src/sched_policies/node_worker.c

@@ -310,22 +310,23 @@ enum starpu_perfmodel_archtype starpu_sched_node_worker_get_perf_arch(struct sta
 }
 */
 
-static void simple_worker_available(struct starpu_sched_node * worker_node)
+static int simple_worker_available(struct starpu_sched_node * worker_node)
 {
 	(void) worker_node;
 #ifndef STARPU_NON_BLOCKING_DRIVERS
 	struct _starpu_worker * w = _starpu_sched_node_worker_get_worker(worker_node);
 	if(w->workerid == starpu_worker_get_id())
-		return;
+		return 1;
 	starpu_pthread_mutex_t *sched_mutex = &w->sched_mutex;
 	starpu_pthread_cond_t *sched_cond = &w->sched_cond;
 	STARPU_PTHREAD_MUTEX_LOCK(sched_mutex);
 	STARPU_PTHREAD_COND_SIGNAL(sched_cond);
 	STARPU_PTHREAD_MUTEX_UNLOCK(sched_mutex);
 #endif
+	return 1;
 }
 
-static void combined_worker_available(struct starpu_sched_node * node)
+static int combined_worker_available(struct starpu_sched_node * node)
 {
 	(void) node;
 #ifndef STARPU_NON_BLOCKING_DRIVERS
@@ -346,6 +347,7 @@ static void combined_worker_available(struct starpu_sched_node * node)
 		STARPU_PTHREAD_MUTEX_UNLOCK(sched_mutex);
 	}
 #endif
+	return 1;
 }
 
 static int simple_worker_push_task(struct starpu_sched_node * node, struct starpu_task *task)
@@ -646,7 +648,6 @@ static struct starpu_sched_node * starpu_sched_node_worker_create(int workerid)
 	node->pop_task = simple_worker_pop_task;
 	node->estimated_end = simple_worker_estimated_end;
 	node->estimated_load = simple_worker_estimated_load;
-//	node->available = simple_worker_available;
 	node->deinit_data = _worker_node_deinit_data;
 	starpu_bitmap_set(node->workers, workerid);
 	starpu_bitmap_or(node->workers_in_ctx, node->workers);
@@ -684,6 +685,7 @@ static struct starpu_sched_node  * starpu_sched_node_combined_worker_create(int
 	node->pop_task = NULL;
 	node->estimated_end = combined_worker_estimated_end;
 	node->estimated_load = combined_worker_estimated_load;
+	node->avail = combined_worker_available;
 	node->deinit_data = _worker_node_deinit_data;
 	starpu_bitmap_set(node->workers, workerid);
 	starpu_bitmap_or(node->workers_in_ctx, node->workers);
@@ -737,7 +739,7 @@ static int _worker_consistant(struct starpu_sched_node * node)
 }
 #endif
 
-int _starpu_sched_node_worker_get_workerid(struct starpu_sched_node * worker_node)
+int starpu_sched_node_worker_get_workerid(struct starpu_sched_node * worker_node)
 {
 #ifndef STARPU_NO_ASSERT
 	STARPU_ASSERT(_worker_consistant(worker_node));

+ 10 - 0
src/sched_policies/prio_deque.c

@@ -80,6 +80,16 @@ int _starpu_prio_deque_push_task(struct _starpu_prio_deque * pdeque, struct star
 	return 0;
 }
 
+int _starpu_prio_deque_push_back_task(struct _starpu_prio_deque * pdeque, struct starpu_task * task)
+{
+	STARPU_ASSERT(pdeque && task);
+	struct starpu_task_list * list = get_prio(pdeque, task->priority);
+	starpu_task_list_push_front(list, task);
+	pdeque->ntasks++;
+	return 0;
+}
+
+
 
 
 /* a little dirty code factorization */

+ 1 - 0
src/sched_policies/prio_deque.h

@@ -42,6 +42,7 @@ int _starpu_prio_deque_is_empty(struct _starpu_prio_deque *);
 
 /* push a task in O(nb priorities) */
 int _starpu_prio_deque_push_task(struct _starpu_prio_deque *, struct starpu_task *);
+int _starpu_prio_deque_push_back_task(struct _starpu_prio_deque *, struct starpu_task *);
 
 
 /* all _starpu_prio_deque_pop/deque_task function return a task or a NULL pointer if none are available

+ 172 - 0
src/sched_policies/tree_dmda.c

@@ -0,0 +1,172 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2013  Marc Sergent 
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#include <starpu_sched_node.h>
+#include <starpu_scheduler.h>
+#include <float.h>
+
+#define _STARPU_SCHED_ALPHA_DEFAULT 1.0
+#define _STARPU_SCHED_BETA_DEFAULT 1.0
+#define _STARPU_SCHED_GAMMA_DEFAULT 1000.0
+#define _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT 150000
+#define _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT 1000000000.0
+static double alpha = _STARPU_SCHED_ALPHA_DEFAULT;
+static double beta = _STARPU_SCHED_BETA_DEFAULT;
+static double _gamma = _STARPU_SCHED_GAMMA_DEFAULT;
+static unsigned ntasks_threshold = _STARPU_SCHED_NTASKS_THRESHOLD_DEFAULT;
+static double exp_len_threshold = _STARPU_SCHED_EXP_LEN_THRESHOLD_DEFAULT;
+
+#ifdef STARPU_USE_TOP
+static const float alpha_minimum=0;
+static const float alpha_maximum=10.0;
+static const float beta_minimum=0;
+static const float beta_maximum=10.0;
+static const float gamma_minimum=0;
+static const float gamma_maximum=10000.0;
+static const float idle_power_minimum=0;
+static const float idle_power_maximum=10000.0;
+#endif /* !STARPU_USE_TOP */
+
+static double idle_power = 0.0;
+
+#ifdef STARPU_USE_TOP
+static void param_modified(struct starpu_top_param* d)
+{
+#ifdef STARPU_DEVEL
+#warning FIXME: get sched ctx to get alpha/beta/gamma/idle values
+#endif
+	/* Just to show parameter modification. */
+	fprintf(stderr,
+		"%s has been modified : "
+		"alpha=%f|beta=%f|gamma=%f|idle_power=%f !\n",
+		d->name, alpha,beta,_gamma, idle_power);
+}
+#endif /* !STARPU_USE_TOP */
+
+static void initialize_dmda_center_policy(unsigned sched_ctx_id)
+{
+	starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
+	const char *strval_alpha = getenv("STARPU_SCHED_ALPHA");
+	if (strval_alpha)
+		alpha = atof(strval_alpha);
+
+	const char *strval_beta = getenv("STARPU_SCHED_BETA");
+	if (strval_beta)
+		beta = atof(strval_beta);
+
+	const char *strval_gamma = getenv("STARPU_SCHED_GAMMA");
+	if (strval_gamma)
+		_gamma = atof(strval_gamma);
+
+	const char *strval_idle_power = getenv("STARPU_IDLE_POWER");
+	if (strval_idle_power)
+		idle_power = atof(strval_idle_power);
+
+	const char *strval_ntasks_threshold = getenv("STARPU_NTASKS_THRESHOLD");
+	if (strval_ntasks_threshold)
+		ntasks_threshold = atof(strval_ntasks_threshold);
+
+	const char *strval_exp_len_threshold = getenv("STARPU_EXP_LEN_THRESHOLD");
+	if (strval_exp_len_threshold)
+		exp_len_threshold = atof(strval_exp_len_threshold);
+
+#ifdef STARPU_USE_TOP
+	starpu_top_register_parameter_float("DMDA_ALPHA", &alpha,
+					    alpha_minimum, alpha_maximum, param_modified);
+	starpu_top_register_parameter_float("DMDA_BETA", &beta,
+					    beta_minimum, beta_maximum, param_modified);
+	starpu_top_register_parameter_float("DMDA_GAMMA", &_gamma,
+					    gamma_minimum, gamma_maximum, param_modified);
+	starpu_top_register_parameter_float("DMDA_IDLE_POWER", &idle_power,
+					    idle_power_minimum, idle_power_maximum, param_modified);
+#endif /* !STARPU_USE_TOP */
+
+	
+	struct starpu_sched_tree * t = starpu_sched_tree_create(sched_ctx_id);
+
+	struct starpu_sched_node * window_node = starpu_sched_node_prio_create(NULL);
+	t->root = window_node;
+
+	struct starpu_heft_data heft_data =
+		{
+			.alpha = alpha,
+			.beta = beta,
+			.gamma = _gamma,
+			.idle_power = idle_power,
+		};
+
+	struct starpu_sched_node * heft_node = starpu_sched_node_heft_create(&heft_data);
+	
+	struct starpu_calibrator_data calibrator_data =
+		{
+			.no_perf_model_node_create = starpu_sched_node_prio_create,
+			.arg_no_perf_model = NULL,
+			.next_node = heft_node,
+		};
+
+	struct starpu_sched_node * calibrator_node = starpu_sched_node_calibrator_create(&calibrator_data);
+	window_node->add_child(window_node, calibrator_node);
+	starpu_sched_node_set_father(calibrator_node, window_node, sched_ctx_id);
+
+	struct starpu_prio_data prio_data =
+		{
+			.ntasks_threshold = ntasks_threshold,
+			.exp_len_threshold = exp_len_threshold,
+		};
+
+	unsigned i;
+	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
+	{
+		struct starpu_sched_node * worker_node = starpu_sched_node_worker_get(i);
+		STARPU_ASSERT(worker_node);
+
+		struct starpu_sched_node * prio = starpu_sched_node_prio_create(&prio_data);
+		prio->add_child(prio, worker_node);
+		starpu_sched_node_set_father(worker_node, prio, sched_ctx_id);
+
+		struct starpu_sched_node * impl_node = starpu_sched_node_best_implementation_create(NULL);
+		impl_node->add_child(impl_node, prio);
+		starpu_sched_node_set_father(prio, impl_node, sched_ctx_id);
+
+		calibrator_node->add_child(calibrator_node, impl_node);
+		starpu_sched_node_set_father(impl_node, calibrator_node, sched_ctx_id);
+	}
+
+	starpu_sched_tree_update_workers(t);
+	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+}
+
+static void deinitialize_dmda_center_policy(unsigned sched_ctx_id)
+{
+	struct starpu_sched_tree *t = (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
+	starpu_sched_tree_destroy(t);
+	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
+}
+
+struct starpu_sched_policy _starpu_sched_tree_dmda_policy =
+{
+	.init_sched = initialize_dmda_center_policy,
+	.deinit_sched = deinitialize_dmda_center_policy,
+	.add_workers = starpu_sched_tree_add_workers,
+	.remove_workers = starpu_sched_tree_remove_workers,
+	.push_task = starpu_sched_tree_push_task,
+	.pop_task = starpu_sched_tree_pop_task,
+	.pre_exec_hook = starpu_sched_node_worker_pre_exec_hook,
+	.post_exec_hook = starpu_sched_node_worker_post_exec_hook,
+	.pop_every_task = NULL,
+	.policy_name = "tree-dmda",
+	.policy_description = "dmda tree policy"
+};

+ 59 - 0
src/sched_policies/tree_eager.c

@@ -0,0 +1,59 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2013  Simon Archipoff
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#include <starpu_sched_node.h>
+#include <starpu_scheduler.h>
+
+
+static void initialize_eager_center_policy(unsigned sched_ctx_id)
+{
+	starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
+	struct starpu_sched_tree *t = starpu_sched_tree_create(sched_ctx_id);
+ 	t->root = starpu_sched_node_fifo_create(NULL);
+	unsigned i;
+	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
+	{
+		struct starpu_sched_node * node = starpu_sched_node_worker_get(i);
+		if(!node)
+			continue;
+		node->fathers[sched_ctx_id] = t->root;
+		t->root->add_child(t->root, node);
+	}
+	starpu_sched_tree_update_workers(t);
+	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+}
+
+static void deinitialize_eager_center_policy(unsigned sched_ctx_id)
+{
+	struct starpu_sched_tree *tree = (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
+	starpu_sched_tree_destroy(tree);
+	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
+}
+
+struct starpu_sched_policy _starpu_sched_tree_eager_policy =
+{
+	.init_sched = initialize_eager_center_policy,
+	.deinit_sched = deinitialize_eager_center_policy,
+	.add_workers = starpu_sched_tree_add_workers,
+	.remove_workers = starpu_sched_tree_remove_workers,
+	.push_task = starpu_sched_tree_push_task,
+	.pop_task = starpu_sched_tree_pop_task,
+	.pre_exec_hook = starpu_sched_node_worker_pre_exec_hook,
+	.post_exec_hook = starpu_sched_node_worker_post_exec_hook,
+	.pop_every_task = NULL,
+	.policy_name = "tree-eager",
+	.policy_description = "eager tree policy"
+};

+ 59 - 0
src/sched_policies/tree_prio.c

@@ -0,0 +1,59 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2013  Marc Sergent
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#include <starpu_sched_node.h>
+#include <starpu_scheduler.h>
+
+
+static void initialize_prio_center_policy(unsigned sched_ctx_id)
+{
+	starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
+	struct starpu_sched_tree *t = starpu_sched_tree_create(sched_ctx_id);
+ 	t->root = starpu_sched_node_prio_create(NULL);
+	unsigned i;
+	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
+	{
+		struct starpu_sched_node * node = starpu_sched_node_worker_get(i);
+		if(!node)
+			continue;
+		node->fathers[sched_ctx_id] = t->root;
+		t->root->add_child(t->root, node);
+	}
+	starpu_sched_tree_update_workers(t);
+	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+}
+
+static void deinitialize_prio_center_policy(unsigned sched_ctx_id)
+{
+	struct starpu_sched_tree *tree = (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
+	starpu_sched_tree_destroy(tree);
+	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
+}
+
+struct starpu_sched_policy _starpu_sched_tree_prio_policy =
+{
+	.init_sched = initialize_prio_center_policy,
+	.deinit_sched = deinitialize_prio_center_policy,
+	.add_workers = starpu_sched_tree_add_workers,
+	.remove_workers = starpu_sched_tree_remove_workers,
+	.push_task = starpu_sched_tree_push_task,
+	.pop_task = starpu_sched_tree_pop_task,
+	.pre_exec_hook = starpu_sched_node_worker_pre_exec_hook,
+	.post_exec_hook = starpu_sched_node_worker_post_exec_hook,
+	.pop_every_task = NULL,
+	.policy_name = "tree-prio",
+	.policy_description = "prio tree policy"
+};

+ 60 - 0
src/sched_policies/tree_random.c

@@ -0,0 +1,60 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2013  Simon Archipoff
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#include <starpu_sched_node.h>
+#include <starpu_scheduler.h>
+
+
+static void initialize_random_center_policy(unsigned sched_ctx_id)
+{
+	starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
+	struct starpu_sched_tree *t = starpu_sched_tree_create(sched_ctx_id);
+ 	t->root = starpu_sched_node_random_create(NULL);
+
+	unsigned i;
+	for(i = 0; i < starpu_worker_get_count() + starpu_combined_worker_get_count(); i++)
+	{
+		struct starpu_sched_node * node = starpu_sched_node_worker_get(i);
+		if(!node)
+			continue;
+		node->fathers[sched_ctx_id] = t->root;
+		t->root->add_child(t->root, node);
+	}
+	starpu_sched_tree_update_workers(t);
+	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+}
+static void deinitialize_random_center_policy(unsigned sched_ctx_id)
+{
+	struct starpu_sched_tree *tree = (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
+	starpu_sched_tree_destroy(tree);
+	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
+}
+
+
+struct starpu_sched_policy _starpu_sched_tree_random_policy =
+{
+	.init_sched = initialize_random_center_policy,
+	.deinit_sched = deinitialize_random_center_policy,
+	.add_workers = starpu_sched_tree_add_workers,
+	.remove_workers = starpu_sched_tree_remove_workers,
+	.push_task = starpu_sched_tree_push_task,
+	.pop_task = starpu_sched_tree_pop_task,
+	.pre_exec_hook = NULL,
+	.post_exec_hook = NULL,
+	.pop_every_task = NULL,
+	.policy_name = "tree-random",
+	.policy_description = "random tree policy"
+};

+ 62 - 0
src/sched_policies/tree_ws.c

@@ -0,0 +1,62 @@
+/* StarPU --- Runtime system for heterogeneous multicore architectures.
+ *
+ * Copyright (C) 2013  Simon Archipoff
+ *
+ * StarPU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at
+ * your option) any later version.
+ *
+ * StarPU is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * See the GNU Lesser General Public License in COPYING.LGPL for more details.
+ */
+
+#include <starpu_sched_node.h>
+#include <starpu_scheduler.h>
+
+
+static void initialize_ws_center_policy(unsigned sched_ctx_id)
+{
+	starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
+	struct starpu_sched_tree *t = starpu_sched_tree_create(sched_ctx_id);
+	struct starpu_sched_node * ws;
+ 	t->root = ws = starpu_sched_node_work_stealing_create(NULL);
+	t->workers = starpu_bitmap_create();
+	unsigned i;
+	for(i = 0; i < starpu_worker_get_count(); i++)
+	{
+		struct starpu_sched_node * node = starpu_sched_node_worker_get(i);
+		if(!node)
+			continue;
+		node->fathers[sched_ctx_id] = ws;
+		ws->add_child(ws, node);
+	}
+	starpu_sched_tree_update_workers(t);
+	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)t);
+}
+
+static void deinitialize_ws_center_policy(unsigned sched_ctx_id)
+{
+	struct starpu_sched_tree *t = (struct starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
+	starpu_sched_tree_destroy(t);
+	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
+}
+
+
+struct starpu_sched_policy _starpu_sched_tree_ws_policy =
+{
+	.init_sched = initialize_ws_center_policy,
+	.deinit_sched = deinitialize_ws_center_policy,
+	.add_workers = starpu_sched_tree_add_workers,
+	.remove_workers = starpu_sched_tree_remove_workers,
+	.push_task = starpu_sched_tree_work_stealing_push_task,
+	.pop_task = starpu_sched_tree_pop_task,
+	.pre_exec_hook = NULL,
+	.post_exec_hook = NULL,
+	.pop_every_task = NULL,
+	.policy_name = "tree-ws",
+	.policy_description = "work stealing tree policy"
+};