Browse Source

- new interface for scheduler maker
- now composed nodes are wrapped in a special node
- create_node functions now take a void *
- probably introduce bugs since node_composed_create arg is stored in node->data until init_data use it

Simon Archipoff 12 years ago
parent
commit
f997b4b13f

+ 4 - 2
src/Makefile.am

@@ -132,7 +132,8 @@ noinst_HEADERS = 						\
 	sched_policies/node_sched.h				\
 	sched_policies/prio_deque.h				\
 	sched_policies/bitmap.h					\
-	sched_policies/scheduler_maker.h
+	sched_policies/scheduler_maker.h			\
+	sched_policies/node_composed.h
 
 libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES = 		\
 	common/barrier.c					\
@@ -243,7 +244,8 @@ libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES = 		\
 	sched_policies/node_random.c				\
 	sched_policies/node_heft.c				\
 	sched_policies/hierarchical_heft.c			\
-	sched_policies/scheduler_maker.c
+	sched_policies/scheduler_maker.c			\
+	sched_policies/node_composed.c
 if STARPU_USE_CPU
 libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES += drivers/cpu/driver_cpu.c
 endif

+ 15 - 190
src/sched_policies/hierarchical_heft.c

@@ -1,197 +1,12 @@
 #include "node_sched.h"
 #include <core/workers.h>
-
-#if 0//def STARPU_HAVE_HWLOC
-#include <hwloc.h>
-/*
- * this function attempt to create a scheduler with a heft node at top,
- * and for eager for each homogeneous (same kind, same numa node) worker group below
- */
-
-
-static hwloc_bitmap_t get_nodeset(int workerid)
-{
-	struct _starpu_worker *worker = _starpu_get_worker_struct(workerid);;
-	struct _starpu_machine_config *config = _starpu_get_machine_config();
-	struct starpu_machine_topology *topology = &config->topology;
-
-	hwloc_obj_t obj = hwloc_get_obj_by_depth(topology->hwtopology, config->cpu_depth, worker->bindid);
-	STARPU_ASSERT(obj->userdata == worker);
-	return obj->nodeset;
-}
-
-
-struct _starpu_sched_node * _starpu_heft_eager_scheduler_add_worker(unsigned sched_ctx_id, struct _starpu_sched_node * root, int workerid)
-{
-	if(root == NULL)//first worker
-	{
-		root = _starpu_sched_node_heft_create();
-		struct _starpu_sched_node * fifo = _starpu_sched_node_fifo_create();
-		root->add_child(root, fifo, sched_ctx_id);
-		_starpu_sched_node_set_father(fifo, root, sched_ctx_id);
-		struct _starpu_sched_node *worker = _starpu_sched_node_worker_get(workerid);
-		fifo->add_child(fifo,worker,sched_ctx_id);
-		_starpu_sched_node_set_father(worker, fifo, sched_ctx_id);
-		return root;
-	}
-
-	hwloc_bitmap_t node = get_nodeset(workerid);
-	int i;
-	for(i = 0; i < root->nchilds; i++)
-	{
-		struct _starpu_sched_node * child = root->childs[i];
-		int wid = child->workerids[0];
-		hwloc_bitmap_t b = get_nodeset(child->workerids[0]);
-		if(hwloc_bitmap_intersects(b,node) && starpu_worker_get_type(wid) == starpu_worker_get_type(workerid))
-			break;
-	}
-	if(i < root->nchilds)//we already have a worker on the same place
-	{
-		struct _starpu_sched_node * fifo = root->childs[i];
-		STARPU_ASSERT(_starpu_sched_node_is_fifo(fifo));
-		fifo->add_child(fifo, _starpu_sched_node_worker_get(workerid),sched_ctx_id);
-		_starpu_sched_node_set_father(fifo, root, sched_ctx_id);
-		_starpu_sched_node_set_father(_starpu_sched_node_worker_get(workerid),
-					      fifo, sched_ctx_id);
-		return root;
-	}
-
-	STARPU_ASSERT(i ==root->nchilds);
-
-	{
-		struct _starpu_sched_node * fifo = _starpu_sched_node_fifo_create();
-		fifo->add_child(fifo, _starpu_sched_node_worker_get(workerid),sched_ctx_id);
-		_starpu_sched_node_set_father(_starpu_sched_node_worker_get(workerid), fifo, sched_ctx_id);
-		root->add_child(root,fifo, sched_ctx_id);
-		return root;
-	}
-}
-
-static void add_worker_heft(unsigned sched_ctx_id, int * workerids, unsigned nworkers)
-{
-	struct _starpu_sched_tree *t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	unsigned i;
-	STARPU_PTHREAD_RWLOCK_WRLOCK(&t->lock);
-	for(i = 0; i < nworkers; i++)
-	{
-		t->root = _starpu_heft_eager_scheduler_add_worker(sched_ctx_id, t->root, workerids[i]);
-		_starpu_tree_update_after_modification(t);
-	}
-	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
-}
-
-static void remove_worker_heft(unsigned sched_ctx_id, int * workerids, unsigned nworkers)
-{
-	struct _starpu_sched_tree *t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	unsigned i;
-	STARPU_PTHREAD_RWLOCK_WRLOCK(&t->lock);
-	for(i = 0; i < nworkers; i++)
-	{
-		int workerid = workerids[i];
-		struct _starpu_sched_node * node = _starpu_sched_tree_remove_worker(t, workerid, sched_ctx_id);
-		if(node)
-		{
-			/*if(_starpu_sched_node_is_fifo(node))
-			{
-				STARPU_ASSERT(_starpu_sched_node_is_fifo(node));
-				struct starpu_task_list list = _starpu_sched_node_fifo_get_non_executable_tasks(node);
-				int res = _starpu_sched_node_push_tasks_to_firsts_suitable_parent(node, &list, sched_ctx_id);
-				STARPU_ASSERT(!res); (void) res;
-				}*/
-		}
-		_starpu_node_destroy_rec(node, sched_ctx_id);
-	}
-	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
-}
-
-
-static void add_worker_heft(unsigned sched_ctx_id, int * workerids, unsigned nworkers)
-{
-	struct _starpu_sched_tree *t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	unsigned i;
-	STARPU_PTHREAD_RWLOCK_WRLOCK(&t->lock);
-	for(i = 0; i < nworkers; i++)
-	{
-		struct _starpu_sched_node * fifo = _starpu_sched_node_fifo_create();
-		struct _starpu_sched_node * worker =  _starpu_sched_node_worker_get(workerids[i]);
-
-		fifo->add_child(fifo, worker, sched_ctx_id);
-		_starpu_sched_node_set_father(worker, fifo, sched_ctx_id);
-
-		t->root->add_child(t->root, fifo, sched_ctx_id);
-		_starpu_sched_node_set_father(fifo, t->root, sched_ctx_id);
-
-	}
-	_starpu_tree_update_after_modification(t);
-	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
-}
-
-static void remove_worker_heft(unsigned sched_ctx_id, int * workerids, unsigned nworkers)
-{
-	struct _starpu_sched_tree *t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	unsigned i;
-	STARPU_PTHREAD_RWLOCK_WRLOCK(&t->lock);
-	for(i = 0; i < nworkers; i++)
-	{
-		int j;
-		for(j = 0; j < t->root->nchilds; j++)
-			if(t->root->childs[j]->workerids[0] == workerids[i])
-				break;
-		STARPU_ASSERT(j < t->root->nchilds);
-		struct _starpu_sched_node * fifo = t->root->childs[j];
-		_starpu_sched_node_set_father(fifo, NULL, sched_ctx_id);
-		t->root->remove_child(t->root, fifo, sched_ctx_id);
-	}
-	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
-}
-
-static void initialize_heft_center_policy(unsigned sched_ctx_id)
-{
-	starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
-	struct _starpu_sched_tree *data = malloc(sizeof(struct _starpu_sched_tree));
-	STARPU_PTHREAD_RWLOCK_INIT(&data->lock,NULL);
-	struct _starpu_sched_node * ws;
- 	data->root = ws = _starpu_sched_node_heft_create();
-	data->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;
-		struct _starpu_sched_node * fifo = _starpu_sched_node_fifo_create();
-		_starpu_sched_node_add_child(fifo, node);
-		_starpu_sched_node_set_father(node, fifo, sched_ctx_id);
-		
-		_starpu_sched_node_add_child(data->root, fifo);
-		_starpu_sched_node_set_father(fifo, data->root, sched_ctx_id);
-
-	}
-	_starpu_set_workers_bitmaps();
-	_starpu_tree_call_init_data(data);
-	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)data);
-
-
-}
-
-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_bitmap_destroy(t->workers);
-	_starpu_tree_destroy(t, sched_ctx_id);
-	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
-}
-
-
-
-#else
-#endif
-
 #include "scheduler_maker.h"
 
-static _starpu_composed_sched_node_recipe_t  recipe_for_worker(enum starpu_worker_archtype a STARPU_ATTRIBUTE_UNUSED)
+static struct  _starpu_composed_sched_node_recipe *  recipe_for_worker(enum starpu_worker_archtype a STARPU_ATTRIBUTE_UNUSED)
 {
-	return _starpu_create_composed_sched_node_recipe(_starpu_sched_node_fifo_create,NULL);
+	struct _starpu_composed_sched_node_recipe * r = _starpu_sched_node_create_recipe();
+	_starpu_sched_recipe_add_node(r, _starpu_sched_node_fifo_create, NULL);
+	return r;
 }
 
 static void initialize_heft_center_policy(unsigned sched_ctx_id)
@@ -201,13 +16,23 @@ static void initialize_heft_center_policy(unsigned sched_ctx_id)
 	struct _starpu_sched_specs specs;
 	memset(&specs,0,sizeof(specs));
 	
-	specs.hwloc_machine_composed_sched_node = _starpu_create_composed_sched_node_recipe(_starpu_sched_node_heft_create,NULL);
+	specs.hwloc_machine_composed_sched_node = ({
+			struct _starpu_composed_sched_node_recipe * r = _starpu_sched_node_create_recipe();
+			_starpu_sched_recipe_add_node(r, _starpu_sched_node_heft_create,NULL);
+			r;});
+
+	specs.hwloc_node_composed_sched_node = ({
+			struct _starpu_composed_sched_node_recipe * r = _starpu_sched_node_create_recipe();
+			_starpu_sched_recipe_add_node(r, _starpu_sched_node_fifo_create,NULL);
+			r;});
 	specs.worker_composed_sched_node = recipe_for_worker;
 
 	struct _starpu_sched_tree *data = _starpu_make_scheduler(sched_ctx_id, specs);
 
 	_starpu_destroy_composed_sched_node_recipe(specs.hwloc_machine_composed_sched_node);
 
+	
+
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)data);
 
 

+ 175 - 0
src/sched_policies/node_composed.c

@@ -0,0 +1,175 @@
+#include "node_sched.h"
+#include <common/list.h>
+LIST_TYPE(fun_create_node,
+	  struct _starpu_sched_node *(*create_node)(void * arg);
+	  void * arg;
+);
+
+
+struct _starpu_composed_sched_node_recipe
+{
+	struct fun_create_node_list * list;
+};
+
+
+struct _starpu_composed_sched_node_recipe * _starpu_sched_node_create_recipe(void)
+{
+	struct _starpu_composed_sched_node_recipe * recipe = malloc(sizeof(*recipe));
+	recipe->list = fun_create_node_list_new();
+	return recipe;
+}
+
+void _starpu_sched_recipe_add_node(struct _starpu_composed_sched_node_recipe * recipe, struct _starpu_sched_node *(*create_node)(void * arg), void * arg)
+{
+	struct fun_create_node * e = fun_create_node_new();
+	e->create_node = create_node;
+	e->arg = arg;
+	fun_create_node_list_push_back(recipe->list, e);
+}
+
+void _starpu_destroy_composed_sched_node_recipe(struct _starpu_composed_sched_node_recipe * recipe)
+{
+	if(!recipe)
+		return;
+	while(!fun_create_node_list_empty(recipe->list))
+		fun_create_node_delete(fun_create_node_list_pop_back(recipe->list));
+	fun_create_node_list_delete(recipe->list);
+	free(recipe);
+}
+
+struct composed_node
+{
+	struct _starpu_sched_node *top,*bottom;
+};
+struct composed_node create_composed_node(struct _starpu_sched_node * sched_ctx_ids_father[STARPU_NMAX_SCHED_CTXS], struct _starpu_bitmap * workers, struct _starpu_composed_sched_node_recipe * recipe
+#ifdef STARPU_HAVE_HWLOC
+					    ,hwloc_obj_t obj
+#endif
+)
+{
+	struct composed_node c;
+	if(!recipe)
+	{
+		c.top = c.bottom = NULL;
+		return c;
+	}
+	struct fun_create_node_list * list = recipe->list;
+	struct fun_create_node * i = fun_create_node_list_begin(list);
+	STARPU_ASSERT(i);
+	STARPU_ASSERT(i->create_node(i->arg));
+	c.top = c.bottom = i->create_node(i->arg);
+#ifdef STARPU_HAVE_HWLOC
+	c.top->obj = obj;
+#endif
+	memcpy(c.top->fathers, sched_ctx_ids_father, sizeof(sched_ctx_ids_father));
+
+	for(i  = fun_create_node_list_next(i);
+	    i != fun_create_node_list_end(list);
+	    i  = fun_create_node_list_next(i))
+	{
+		STARPU_ASSERT(i->create_node(i->arg));
+		struct _starpu_sched_node * node = i->create_node(i->arg);
+#ifdef STARPU_HAVE_HWLOC
+		node->obj = obj;
+#endif
+		_starpu_sched_node_add_child(c.bottom, node);
+//we want to be able to to traverse scheduler bottom up for all sched ctxs
+		int j;
+		for(j = 0; j < STARPU_NMAX_SCHED_CTXS; j++)
+			if(sched_ctx_ids_father[j])
+				_starpu_sched_node_set_father(node, c.bottom,(unsigned)j);
+		node->workers = workers;
+		c.bottom = node;
+	}
+	STARPU_ASSERT(!_starpu_sched_node_is_worker(c.bottom));
+	return c;
+}
+		
+
+static int composed_node_push_task(struct _starpu_sched_node * node, struct starpu_task * task)
+{
+	struct composed_node *c = node->data;
+	return c->top->push_task(c->top,task);
+}
+struct starpu_task * composed_node_pop_task(struct _starpu_sched_node *node,
+					    unsigned sched_ctx_id)
+{
+	struct composed_node *c = node->data;
+	return c->bottom->pop_task(c->bottom, sched_ctx_id);
+}
+void composed_node_available(struct _starpu_sched_node *node)
+{
+	struct composed_node * c = node->data;
+	c->top->available(c->top);
+}
+	
+double composed_node_estimated_load(struct _starpu_sched_node * node)
+{
+	struct composed_node * c = node->data;
+	return c->top->estimated_load(c->top);
+}
+
+struct _starpu_task_execute_preds composed_node_estimated_execute_preds(struct _starpu_sched_node * node,
+									struct starpu_task * task)
+{
+	struct composed_node * c = node->data;
+	return c->top->estimated_execute_preds(c->top,task);
+}
+
+static void invalid_second_init_data(struct _starpu_sched_node * node STARPU_ATTRIBUTE_UNUSED)
+{
+	STARPU_ABORT();
+}
+
+void composed_node_init_data(struct _starpu_sched_node *node)
+{
+	struct _starpu_composed_sched_node_recipe * recipe = node->data;
+	struct composed_node * c = malloc(sizeof(struct composed_node));
+	*c = create_composed_node(node->fathers, node->workers, recipe
+#ifdef STARPU_HAVE_HWLOC
+				   ,node->obj
+#endif 
+);
+	c->bottom->nchilds = node->nchilds;
+	c->bottom->childs = node->childs;
+
+	node->init_data = invalid_second_init_data;
+}
+
+void composed_node_deinit_data(struct _starpu_sched_node * _node)
+{
+	struct composed_node *c = _node->data;
+	c->bottom->childs = NULL;
+	c->bottom->nchilds = 0;
+	struct _starpu_sched_node * node = c->top;
+	struct _starpu_sched_node * next = NULL;
+	do
+	{
+		node->workers = NULL;
+		node->deinit_data(node);
+		next = node->childs ? node->childs[0] : NULL;
+		_starpu_sched_node_destroy(node);
+	}while(next);
+	free(c);
+	_node->data = NULL;
+}
+
+struct _starpu_sched_node * _starpu_sched_node_composed_node_create(struct _starpu_composed_sched_node_recipe * recipe)
+{
+	STARPU_ASSERT(!fun_create_node_list_empty(recipe->list));
+	struct fun_create_node_list * l = recipe->list;
+	if(l->_head == l->_tail)
+		return l->_head->create_node(l->_head->arg);
+	struct _starpu_sched_node * node = _starpu_sched_node_create();
+
+	node->data = recipe;
+	node->push_task = composed_node_push_task;
+	node->pop_task = composed_node_pop_task;
+	node->available = composed_node_available;
+	node->estimated_load = composed_node_estimated_load;
+	node->estimated_execute_preds = composed_node_estimated_execute_preds;
+	node->init_data = composed_node_init_data;
+	node->deinit_data = composed_node_deinit_data;
+
+	return node;
+}

+ 14 - 0
src/sched_policies/node_composed.h

@@ -0,0 +1,14 @@
+#ifndef __NODE_COMPOSED_H__
+#define __NODE_COMPOSED_H__
+#include "node_sched.h"
+
+struct _starpu_composed_sched_node_recipe;
+
+//create empty recipe
+struct _starpu_composed_sched_node_recipe * _starpu_sched_node_create_recipe(void);
+//add a function creation node to recipe
+void _starpu_sched_recipe_add_node(struct _starpu_composed_sched_node_recipe * recipe, struct _starpu_sched_node *(*create_node)(void * arg), void * arg);
+void _starpu_destroy_composed_sched_node_recipe(struct _starpu_composed_sched_node_recipe *);
+
+struct _starpu_sched_node * _starpu_sched_node_composed_node_create(struct _starpu_composed_sched_node_recipe * recipe);
+#endif

+ 1 - 1
src/sched_policies/node_eager.c

@@ -10,7 +10,7 @@ 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 *data = malloc(sizeof(struct _starpu_sched_tree));
 	STARPU_PTHREAD_RWLOCK_INIT(&data->lock,NULL);
- 	data->root = _starpu_sched_node_fifo_create();
+ 	data->root = _starpu_sched_node_fifo_create(NULL);
 	data->workers = _starpu_bitmap_create();
 	unsigned i;
 	for(i = 0; i < starpu_worker_get_count(); i++)

+ 2 - 5
src/sched_policies/node_fifo.c

@@ -172,13 +172,10 @@ void deinit_fifo_data(struct _starpu_sched_node * node)
 
 int _starpu_sched_node_is_fifo(struct _starpu_sched_node * node)
 {
-	return node->estimated_execute_preds == estimated_execute_preds
-		|| node->estimated_load == estimated_load
-		|| node->push_task == push_task
-		|| node->pop_task == pop_task;
+	return node->init_data == init_fifo_data;
 }
 
-struct _starpu_sched_node * _starpu_sched_node_fifo_create(void)
+struct _starpu_sched_node * _starpu_sched_node_fifo_create(void * arg STARPU_ATTRIBUTE_UNUSED)
 {
 	struct _starpu_sched_node * node = _starpu_sched_node_create();
 	node->estimated_execute_preds = estimated_execute_preds;

+ 4 - 4
src/sched_policies/node_heft.c

@@ -218,7 +218,7 @@ void init_heft_data(struct _starpu_sched_node *node)
 
 	node->data = data;
 
-	_starpu_sched_node_heft_set_no_model_node(node, _starpu_sched_node_random_create);
+	_starpu_sched_node_heft_set_no_model_node(node, _starpu_sched_node_random_create,NULL);
 }
 
 static void destroy_no_model_node(struct _starpu_sched_node * heft_node)
@@ -238,11 +238,11 @@ void deinit_heft_data(struct _starpu_sched_node * node)
 }
 
 void _starpu_sched_node_heft_set_no_model_node(struct _starpu_sched_node * heft_node,
-					       struct _starpu_sched_node * (*create_no_model_node)(void))
+					       struct _starpu_sched_node * (*create_no_model_node)(void *),void * arg)
 {
 	destroy_no_model_node(heft_node);
 	struct _starpu_dmda_data * data = heft_node->data;
-	struct _starpu_sched_node * no_model_node = create_no_model_node();
+	struct _starpu_sched_node * no_model_node = create_no_model_node(arg);
 	no_model_node->childs = malloc(heft_node->nchilds * sizeof(struct _starpu_sched_node *));
 	memcpy(no_model_node->childs, heft_node->childs, heft_node->nchilds * sizeof(struct _strapu_sched_node *));
 
@@ -251,7 +251,7 @@ void _starpu_sched_node_heft_set_no_model_node(struct _starpu_sched_node * heft_
 	data->no_model_node = no_model_node;
 }
 
-struct _starpu_sched_node * _starpu_sched_node_heft_create()
+struct _starpu_sched_node * _starpu_sched_node_heft_create(void * arg STARPU_ATTRIBUTE_UNUSED)
 {
 
 	struct _starpu_sched_node * node = _starpu_sched_node_create();

+ 7 - 2
src/sched_policies/node_random.c

@@ -78,7 +78,7 @@ static int push_task(struct _starpu_sched_node * node, struct starpu_task * task
 }
 
 
-struct _starpu_sched_node * _starpu_sched_node_random_create(void)
+struct _starpu_sched_node * _starpu_sched_node_random_create(void * arg STARPU_ATTRIBUTE_UNUSED)
 {
 	struct _starpu_sched_node * node = _starpu_sched_node_create();
 	node->data = NULL;
@@ -89,12 +89,17 @@ struct _starpu_sched_node * _starpu_sched_node_random_create(void)
 	return node;
 }
 
+int _starpu_sched_node_is_random(struct _starpu_sched_node *node)
+{
+	return node->init_data == init_data_random;
+}
+
 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 *data = malloc(sizeof(struct _starpu_sched_tree));
 	STARPU_PTHREAD_RWLOCK_INIT(&data->lock,NULL);
- 	data->root = _starpu_sched_node_random_create();
+ 	data->root = _starpu_sched_node_random_create(NULL);
 	data->workers = _starpu_bitmap_create();
 
 	unsigned i;

+ 6 - 7
src/sched_policies/node_sched.h

@@ -47,7 +47,6 @@ struct _starpu_sched_node
 #ifdef STARPU_HAVE_HWLOC
 	hwloc_obj_t obj;
 #endif
-
 };
 
 struct _starpu_task_execute_preds
@@ -108,23 +107,23 @@ void _starpu_sched_node_worker_destroy(struct _starpu_sched_node *);
 int _starpu_sched_node_is_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);
+struct _starpu_sched_node * _starpu_sched_node_fifo_create(void * arg STARPU_ATTRIBUTE_UNUSED);
 int _starpu_sched_node_is_fifo(struct _starpu_sched_node * node);
 //struct starpu_task_list  _starpu_sched_node_fifo_get_non_executable_tasks(struct _starpu_sched_node * fifo_node);
 
 /* struct _starpu_sched_node * _starpu_sched_node_work_stealing_create(void); */
 int _starpu_sched_node_is_work_stealing(struct _starpu_sched_node * node);
 
-struct _starpu_sched_node * _starpu_sched_node_random_create(void);
-
-struct _starpu_sched_node * _starpu_sched_node_eager_create(void);
+struct _starpu_sched_node * _starpu_sched_node_random_create(void * arg STARPU_ATTRIBUTE_UNUSED);
+int _starpu_sched_node_is_random(struct _starpu_sched_node *);
+struct _starpu_sched_node * _starpu_sched_node_eager_create(void * arg STARPU_ATTRIBUTE_UNUSED);
 
-struct _starpu_sched_node * _starpu_sched_node_heft_create(void);
+struct _starpu_sched_node * _starpu_sched_node_heft_create(void * arg STARPU_ATTRIBUTE_UNUSED);
 /* this function is called to create the node wich will be used to push task when no perf model are available
  * by default, a random node is created
  */
 void _starpu_sched_node_heft_set_no_model_node(struct _starpu_sched_node * heft_node,
-					       struct _starpu_sched_node * (*create_no_model_node)(void));
+					       struct _starpu_sched_node * (*create_no_model_node)(void * arg), void * arg);
 
 int _starpu_sched_node_is_heft(struct _starpu_sched_node * node);
 

+ 85 - 132
src/sched_policies/scheduler_maker.c

@@ -1,93 +1,21 @@
 #include "scheduler_maker.h"
 #include "node_sched.h"
+#include "node_composed.h"
 #include <common/list.h>
 #include <stdarg.h>
 #include <core/workers.h>
-LIST_TYPE(fun_create_node,
-	  struct _starpu_sched_node *(*create_node)(void);
-);
 
-
-struct _starpu_composed_sched_node_recipe
-{
-	struct fun_create_node_list * list;
-};
-
-
-//variadic args are a null terminated sequence of function struct _starpu_sched_node *(*)(void)
-_starpu_composed_sched_node_recipe_t _starpu_create_composed_sched_node_recipe(struct _starpu_sched_node * (*create_sched_node_top)(void), ...){
-	_starpu_composed_sched_node_recipe_t recipe = malloc(sizeof(*recipe));
-	recipe->list = fun_create_node_list_new();
-
-	struct fun_create_node * e = fun_create_node_new();
-	e->create_node = create_sched_node_top;
-	fun_create_node_list_push_back(recipe->list, e);
-
-	va_list ap;
-	va_start(ap, create_sched_node_top);
-	struct _starpu_sched_node *(*create_node)(void);
-	for(create_node = va_arg(ap, struct _starpu_sched_node * (*)(void));
-	    create_node != NULL;
-	    create_node = va_arg(ap, struct _starpu_sched_node * (*)(void)))
-	{
-		e = fun_create_node_new();
-		e->create_node = create_node;
-		fun_create_node_list_push_back(recipe->list, e);
-	}
-	va_end(ap);
-	
-	return recipe;
-}
-	
-
-void _starpu_destroy_composed_sched_node_recipe(_starpu_composed_sched_node_recipe_t recipe)
+static void set_all_data_to_null(struct _starpu_sched_node * node)
 {
-	if(!recipe)
-		return;
-	while(!fun_create_node_list_empty(recipe->list))
-		fun_create_node_delete(fun_create_node_list_pop_back(recipe->list));
-	fun_create_node_list_delete(recipe->list);
-	free(recipe);
-}
-
-
-
-
-struct composed_sched
-{
-	struct _starpu_sched_node *top,*bottom;
-};
-struct composed_sched create_composed_sched(unsigned sched_ctx_id, hwloc_obj_t obj, _starpu_composed_sched_node_recipe_t recipe)
-{
-	struct composed_sched c;
-	if(!recipe)
-	{
-		c.top = c.bottom = NULL;
-		return c;
-	}
-	struct fun_create_node_list * list = recipe->list;
-	struct fun_create_node * i = fun_create_node_list_begin(list);
-	STARPU_ASSERT(i);
-	STARPU_ASSERT(i->create_node());
-	c.top = c.bottom = i->create_node();
-	c.top->obj = obj;
-
-	for(i  = fun_create_node_list_next(i);
-	    i != fun_create_node_list_end(list);
-	    i  = fun_create_node_list_next(i))
+	if(node)
 	{
-		STARPU_ASSERT(i->create_node());
-		struct _starpu_sched_node * node = i->create_node();
-		node->obj = obj;
-		_starpu_sched_node_add_child(c.bottom, node);
-		_starpu_sched_node_set_father(node, c.bottom, sched_ctx_id);
-		c.bottom = node;
+		node->data = NULL;
+		int i;
+		for(i = 0; i < node->nchilds; i++)
+			set_all_data_to_null(node->childs[i]);
 	}
-	STARPU_ASSERT(!_starpu_sched_node_is_worker(c.bottom));
-	return c;
 }
 
-
 struct sched_node_list
 {
 	struct _starpu_sched_node ** arr;
@@ -112,14 +40,13 @@ static struct sched_node_list helper_make_scheduler(hwloc_obj_t obj, struct _sta
 {
 	STARPU_ASSERT(obj);
 
-	struct composed_sched c;
-	memset(&c,0,sizeof(c));
+	struct _starpu_sched_node * node = NULL;
 
 	/*set nodes for this obj */
 #define CASE(ENUM,spec_member)						\
 		case ENUM:						\
 			if(specs.spec_member)				\
-				c = create_composed_sched(sched_ctx_id,obj,specs.spec_member); \
+				node = _starpu_sched_node_composed_node_create(specs.spec_member); \
 			break
 	switch(obj->type)
 	{
@@ -143,76 +70,55 @@ static struct sched_node_list helper_make_scheduler(hwloc_obj_t obj, struct _sta
 			add_node(&l, lc.arr[j]);
 		destroy_list(&lc);
 	}
-	if(!c.bottom)
+	if(!node)
 		return l;
 	for(i = 0; i < l.size; i++)
 	{
-		_starpu_sched_node_add_child(c.bottom, l.arr[i]);
-		_starpu_sched_node_set_father(l.arr[i],c.bottom,sched_ctx_id);
+		_starpu_sched_node_add_child(node, l.arr[i]);
+		_starpu_sched_node_set_father(l.arr[i],node,sched_ctx_id);
 	}
 	destroy_list(&l);
 	init_list(&l);
-	add_node(&l, c.top);
+	node->obj = obj;
+	add_node(&l, node);
 	return l;
 }
 
-struct _starpu_sched_node * _find_deeper_sched_node_with_obj(struct _starpu_sched_node * root, hwloc_obj_t obj)
+struct _starpu_sched_node * _find_sched_node_with_obj(struct _starpu_sched_node * node, hwloc_obj_t obj)
 {
-	STARPU_ASSERT(root);
-	if(root->obj == obj)
-	{
-		int i = 0;
-		while(i < root->nchilds)
-		{
-			if(root->childs[i]->obj == root->obj)
-			{
-				root = root->childs[i];
-				i = 0;
-			}
-			else
-				i++;
-		}
-		return root;
-	}
-
+	if(node == NULL)
+		return NULL;
+	if(node->obj == obj)
+		return node;
 	int i;
-	for(i = 0; i < root->nchilds; i++)
+	for(i = 0; i < node->nchilds; i++)
 	{
-		struct _starpu_sched_node * node = root->childs[i];
-		struct _starpu_sched_node * tmp = _find_deeper_sched_node_with_obj(node, obj);
+		struct _starpu_sched_node * tmp = _find_sched_node_with_obj(node->childs[i], obj);
 		if(tmp)
 			return tmp;
 	}
 	return NULL;
 }
 
-static void plug_recipe_between(struct _starpu_sched_node * top, struct _starpu_sched_node * bottom,
-				hwloc_obj_t obj,unsigned sched_ctx_id,
-				_starpu_composed_sched_node_recipe_t recipe)
-{
-	struct composed_sched c = create_composed_sched(sched_ctx_id, obj, recipe);	
-	if(!c.top)
-		c.top = c.bottom = bottom;
-	else
-	{
-		_starpu_sched_node_add_child(c.bottom, bottom);
-		_starpu_sched_node_set_father(bottom, c.bottom, sched_ctx_id);
-	}
-	_starpu_sched_node_add_child(top, c.top);
-	_starpu_sched_node_set_father(c.top, top, sched_ctx_id);
-}
+
 static void set_cpu_worker_leaf(struct _starpu_sched_node * root, struct _starpu_sched_node * worker, unsigned sched_ctx_id,
-				_starpu_composed_sched_node_recipe_t cpu_composed_sched_node)
+				struct _starpu_composed_sched_node_recipe * cpu_composed_sched_node)
 {
 	hwloc_obj_t obj = worker->obj;
-	STARPU_ASSERT(!_find_deeper_sched_node_with_obj(root, obj));
+	STARPU_ASSERT(!_find_sched_node_with_obj(root, obj));
 	while(obj)
 	{
 		obj = obj->parent;
-		struct _starpu_sched_node * tmp = _find_deeper_sched_node_with_obj(root, obj);
+		struct _starpu_sched_node * tmp = _find_sched_node_with_obj(root, obj);
 		if(tmp)
 		{
-			plug_recipe_between(tmp, worker, NULL, sched_ctx_id, cpu_composed_sched_node);
+			struct _starpu_sched_node * node = _starpu_sched_node_composed_node_create(cpu_composed_sched_node);
+			node->obj = worker->obj;
+			_starpu_sched_node_set_father(node, tmp, sched_ctx_id);
+			_starpu_sched_node_add_child(tmp, node);
+
+			_starpu_sched_node_set_father(worker, node, sched_ctx_id);
+			_starpu_sched_node_add_child(node, worker);
 			return;
 		}
 	}
@@ -220,9 +126,9 @@ static void set_cpu_worker_leaf(struct _starpu_sched_node * root, struct _starpu
 }
 
 static void set_other_worker_leaf(struct _starpu_sched_node * root, struct _starpu_sched_node * worker, unsigned sched_ctx_id,
-				  _starpu_composed_sched_node_recipe_t device_composed_sched_node, int sched_have_numa_node)
+				  struct _starpu_composed_sched_node_recipe * device_composed_sched_node, int sched_have_numa_node)
 {
-	hwloc_obj_t obj = worker->obj;
+	hwloc_obj_t obj = worker->data;
 	while(obj)
 		if((sched_have_numa_node && obj->type == HWLOC_OBJ_NODE) || obj->type == HWLOC_OBJ_MACHINE)
 			break;
@@ -230,16 +136,59 @@ static void set_other_worker_leaf(struct _starpu_sched_node * root, struct _star
 			obj = obj->parent;
 	STARPU_ASSERT(obj != NULL);
 
-	struct _starpu_sched_node * node = _find_deeper_sched_node_with_obj(root, obj);
-	if(node)
+	struct _starpu_sched_node * tmp = _find_sched_node_with_obj(root, obj);
+	if(tmp)
 	{
-		plug_recipe_between(node, worker, NULL, sched_ctx_id, device_composed_sched_node);
+		struct _starpu_sched_node * node = _starpu_sched_node_composed_node_create(device_composed_sched_node);
+#ifdef STARPU_DEVEL
+#warning FIXME node->obj is set to worker->obj even for accelerators workers
+#endif
+		node->obj = worker->obj;
+		node->fathers[sched_ctx_id] = tmp;
+		_starpu_sched_node_add_child(node, worker);
 		return;
 	}
 	STARPU_ABORT();
 }
 
 
+#ifdef STARPU_DEVEL
+static const char * name_hwloc_node(struct _starpu_sched_node * node)
+{
+	return hwloc_obj_type_string(node->obj->type);
+}
+static const char * name_sched_node(struct _starpu_sched_node * node)
+{
+	if(_starpu_sched_node_is_fifo(node))
+		return "fifo node";
+	if(_starpu_sched_node_is_heft(node))
+		return "heft node";
+	if(_starpu_sched_node_is_random(node))
+		return "random node";
+	if(_starpu_sched_node_is_worker(node))
+	{
+		struct _starpu_worker * w = _starpu_sched_node_worker_get_worker(node);
+#define SIZE 256
+		static char output[SIZE];
+		snprintf(output, SIZE,"node worker %d %s",w->workerid,w->name);
+		return output;
+	}
+	if(_starpu_sched_node_is_work_stealing(node))
+		return "work stealing node";
+
+	return "unknown";
+}
+static void helper_display_scheduler(FILE* out, unsigned depth, struct _starpu_sched_node * node)
+{
+	if(!node)
+		return;
+	fprintf(out,"%*s-> %s : %s\n", depth * 2 , "", name_sched_node(node), name_hwloc_node(node));
+	int i;
+	for(i = 0; i < node->nchilds; i++)
+		helper_display_scheduler(out, depth + 1, node->childs[i]);
+}
+#endif //STARPU_DEVEL
+
 struct _starpu_sched_tree * _starpu_make_scheduler(unsigned sched_ctx_id, struct _starpu_sched_specs specs)
 {
 	struct _starpu_sched_tree * tree = malloc(sizeof(*tree));
@@ -261,7 +210,7 @@ struct _starpu_sched_tree * _starpu_make_scheduler(unsigned sched_ctx_id, struct
 		struct _starpu_worker * worker = _starpu_get_worker_struct(i);
 		struct _starpu_sched_node * worker_node = _starpu_sched_node_worker_get(i);
 		STARPU_ASSERT(worker);
-		_starpu_composed_sched_node_recipe_t recipe = specs.worker_composed_sched_node(worker->arch);
+		struct _starpu_composed_sched_node_recipe * recipe = specs.worker_composed_sched_node(worker->arch);
 		switch(worker->arch)
 		{
 		case STARPU_CPU_WORKER:
@@ -276,6 +225,10 @@ struct _starpu_sched_tree * _starpu_make_scheduler(unsigned sched_ctx_id, struct
 
 	_starpu_set_workers_bitmaps();
 	_starpu_tree_call_init_data(tree);
+#ifdef STARPU_DEVEL
+	fprintf(stderr, "scheduler created :\n");
+	helper_display_scheduler(stderr, 0, tree->root);
+#endif
 
 	return tree;
 }

+ 6 - 14
src/sched_policies/scheduler_maker.h

@@ -3,33 +3,25 @@
 #ifndef __SCHEDULER_MAKER_H__
 #define __SCHEDULER_MAKER_H__
 #include "node_sched.h"
+#include "node_composed.h"
 #include <common/list.h>
 
 
 
-typedef struct _starpu_composed_sched_node_recipe * _starpu_composed_sched_node_recipe_t;
-
-
-
-//variadic args are a null terminated sequence of function struct _starpu_sched_node *(*)(void)
-_starpu_composed_sched_node_recipe_t _starpu_create_composed_sched_node_recipe(struct _starpu_sched_node * (*create_sched_node_top)(void), ...);
-void _starpu_destroy_composed_sched_node_recipe(_starpu_composed_sched_node_recipe_t);
-
-
 //null pointer mean to ignore a level L of hierarchy, then nodes of levels > L become childs of level L - 1
 struct _starpu_sched_specs
 {
 	//hw_loc_machine_composed_sched_node must be set as its the root of the topology
-	_starpu_composed_sched_node_recipe_t hwloc_machine_composed_sched_node;
-	_starpu_composed_sched_node_recipe_t hwloc_node_composed_sched_node;
-	_starpu_composed_sched_node_recipe_t hwloc_socket_composed_sched_node;
-	_starpu_composed_sched_node_recipe_t hwloc_cache_composed_sched_node;
+	struct _starpu_composed_sched_node_recipe * hwloc_machine_composed_sched_node;
+	struct _starpu_composed_sched_node_recipe * hwloc_node_composed_sched_node;
+	struct _starpu_composed_sched_node_recipe * hwloc_socket_composed_sched_node;
+	struct _starpu_composed_sched_node_recipe * hwloc_cache_composed_sched_node;
 
 
 	/* this member should return a new allocated _starpu_composed_sched_node_recipe_t or NULL
 	 * the _starpu_composed_sched_node_recipe_t must not include the worker node
 	 */
-	_starpu_composed_sched_node_recipe_t (*worker_composed_sched_node)(enum starpu_worker_archtype);
+	struct _starpu_composed_sched_node_recipe * (*worker_composed_sched_node)(enum starpu_worker_archtype);
 };
 
 struct _starpu_sched_tree * _starpu_make_scheduler(unsigned sched_ctx_id, struct _starpu_sched_specs);