浏览代码

heft scheduler built according to hwloc topology

Simon Archipoff 12 年之前
父节点
当前提交
3a696fdc4a

+ 41 - 4
src/sched_policies/hierarchical_heft.c

@@ -144,10 +144,6 @@ static void remove_worker_heft(unsigned sched_ctx_id, int * workerids, unsigned
 	}
 	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
 }
-#else
-#endif
-
-
 
 static void initialize_heft_center_policy(unsigned sched_ctx_id)
 {
@@ -188,6 +184,47 @@ static void deinitialize_heft_center_policy(unsigned 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)
+{
+	return _starpu_create_composed_sched_node_recipe(_starpu_sched_node_fifo_create,NULL);
+}
+
+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_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.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);
+
+
+}
+
+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);
+}
+
+
+
+
+
 struct starpu_sched_policy _starpu_sched_tree_heft_policy =
 {
 	.init_sched = initialize_heft_center_policy,

+ 1 - 2
src/sched_policies/node_sched.h

@@ -91,9 +91,7 @@ struct _starpu_sched_node * _starpu_sched_node_create(void);
 
 /* free memory allocated by _starpu_sched_node_create, it does not call node->destroy_node(node)*/
 void _starpu_sched_node_destroy(struct _starpu_sched_node * node);
-
 void _starpu_sched_node_set_father(struct _starpu_sched_node *node, struct _starpu_sched_node *father_node, unsigned sched_ctx_id);
-
 void _starpu_sched_node_add_child(struct _starpu_sched_node* node, struct _starpu_sched_node * child);
 void _starpu_sched_node_remove_child(struct _starpu_sched_node * node, struct _starpu_sched_node * child);
 
@@ -103,6 +101,7 @@ int _starpu_sched_node_can_execute_task_with_impl(struct _starpu_sched_node * no
 
 /* no public create function for workers because we dont want to have several node_worker for a single workerid */
 struct _starpu_sched_node * _starpu_sched_node_worker_get(int workerid);
+struct _starpu_worker * _starpu_sched_node_worker_get_worker(struct _starpu_sched_node * worker_node);
 void _starpu_sched_node_worker_destroy(struct _starpu_sched_node *);
 
 /* this function compare the available function of the node with the standard available for worker nodes*/

+ 14 - 1
src/sched_policies/node_worker.c

@@ -16,7 +16,11 @@ struct _starpu_sched_node * _starpu_sched_node_worker_get(int workerid)
 		return _worker_nodes[workerid] = _starpu_sched_node_worker_create(workerid);
 }
 
-
+struct _starpu_worker * _starpu_sched_node_worker_get_worker(struct _starpu_sched_node * worker_node)
+{
+	STARPU_ASSERT(_starpu_sched_node_is_worker(worker_node));
+	return worker_node->data;
+}
 
 int _starpu_sched_node_worker_push_task(struct _starpu_sched_node * node, struct starpu_task *task)
 {
@@ -184,6 +188,15 @@ static struct _starpu_sched_node  * _starpu_sched_node_worker_create(int workeri
 	node->workers = _starpu_bitmap_create();
 	_starpu_bitmap_set(node->workers, workerid);
 	_worker_nodes[workerid] = node;
+
+#ifdef STARPU_HAVE_HWLOC
+	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);
+	node->obj = obj;
+#endif
+
 	return node;
 }
 

+ 126 - 4
src/sched_policies/scheduler_maker.c

@@ -18,7 +18,11 @@ struct _starpu_composed_sched_node_recipe
 _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);
@@ -26,7 +30,7 @@ _starpu_composed_sched_node_recipe_t _starpu_create_composed_sched_node_recipe(s
 	    create_node != NULL;
 	    create_node = va_arg(ap, struct _starpu_sched_node * (*)(void)))
 	{
-		struct fun_create_node * e = fun_create_node_new();
+		e = fun_create_node_new();
 		e->create_node = create_node;
 		fun_create_node_list_push_back(recipe->list, e);
 	}
@@ -38,6 +42,8 @@ _starpu_composed_sched_node_recipe_t _starpu_create_composed_sched_node_recipe(s
 
 void _starpu_destroy_composed_sched_node_recipe(_starpu_composed_sched_node_recipe_t 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);
@@ -53,9 +59,13 @@ struct composed_sched
 };
 struct composed_sched create_composed_sched(unsigned sched_ctx_id, hwloc_obj_t obj, _starpu_composed_sched_node_recipe_t recipe)
 {
-	struct fun_create_node_list * list = recipe->list;
-
 	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());
@@ -72,6 +82,7 @@ struct composed_sched create_composed_sched(unsigned sched_ctx_id, hwloc_obj_t o
 		_starpu_sched_node_set_father(node, c.bottom, sched_ctx_id);
 		c.bottom = node;
 	}
+	STARPU_ASSERT(!_starpu_sched_node_is_worker(c.bottom));
 	return c;
 }
 
@@ -144,10 +155,99 @@ static struct sched_node_list helper_make_scheduler(hwloc_obj_t obj, struct _sta
 	return l;
 }
 
+struct _starpu_sched_node * _find_deeper_sched_node_with_obj(struct _starpu_sched_node * root, hwloc_obj_t obj)
+{
+	STARPU_ASSERT(root);
+	if(root->obj == obj)
+		return root;
+	else
+		return NULL;
+	int i;
+	for(i = 0; i < root->nchilds; i++)
+	{
+		struct _starpu_sched_node * node = node->childs[i];
+		struct _starpu_sched_node * tmp = _find_deeper_sched_node_with_obj(node, obj);
+
+		if(tmp)
+		{
+			int j = 0;
+			while(j < tmp->nchilds)
+			{
+				if(tmp->childs[i]->obj == tmp->obj)
+				{
+					tmp = tmp->childs[i];
+					j = 0;
+				}
+				else
+					j++;
+			}
+				       
+			
+			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)
+{
+	hwloc_obj_t obj = worker->obj;
+	STARPU_ASSERT(!_find_deeper_sched_node_with_obj(root, obj));
+	while(obj)
+	{
+		obj = obj->parent;
+		struct _starpu_sched_node * tmp = _find_deeper_sched_node_with_obj(root, obj);
+		if(tmp)
+		{
+			plug_recipe_between(tmp, worker, obj, sched_ctx_id, cpu_composed_sched_node);
+			return;
+		}
+	}
+	STARPU_ABORT();
+}
+
+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)
+{
+	hwloc_obj_t obj = worker->obj;
+	while(obj)
+		if(obj->type == HWLOC_OBJ_NODE || obj->type == HWLOC_OBJ_MACHINE)
+			break;
+		else
+			obj = obj->parent;
+	STARPU_ASSERT(obj != NULL);
+
+	struct _starpu_sched_node * node = _find_deeper_sched_node_with_obj(root, obj);
+	if(node)
+	{
+		plug_recipe_between(node, worker, obj, sched_ctx_id, device_composed_sched_node);
+		return;
+	}
+	STARPU_ABORT();
+}
+
+
 struct _starpu_sched_tree * _starpu_make_scheduler(unsigned sched_ctx_id, struct _starpu_sched_specs specs)
 {
 	struct _starpu_sched_tree * tree = malloc(sizeof(*tree));
 	STARPU_PTHREAD_RWLOCK_INIT(&tree->lock,NULL);
+	tree->workers = _starpu_bitmap_create();
 	
 	struct _starpu_machine_config *config = _starpu_get_machine_config();
 	hwloc_topology_t topology = config->topology.hwtopology;
@@ -157,6 +257,28 @@ struct _starpu_sched_tree * _starpu_make_scheduler(unsigned sched_ctx_id, struct
 
 	tree->root = list.arr[0];
 	destroy_list(&list);
+	
+	unsigned i;
+	for(i = 0; i < starpu_worker_get_count(); i++)
+	{
+		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);
+		switch(worker->arch)
+		{
+		case STARPU_CPU_WORKER:
+			set_cpu_worker_leaf(tree->root, worker_node, sched_ctx_id, recipe);
+			break;
+		default:
+			set_other_worker_leaf(tree->root, worker_node, sched_ctx_id, recipe);
+			break;
+		}
+		_starpu_destroy_composed_sched_node_recipe(recipe);
+	}
+
+	_starpu_set_workers_bitmaps();
+	_starpu_tree_call_init_data(tree);
 
 	return tree;
 }

+ 4 - 5
src/sched_policies/scheduler_maker.h

@@ -25,11 +25,10 @@ struct _starpu_sched_specs
 	_starpu_composed_sched_node_recipe_t hwloc_cache_composed_sched_node;
 
 
-	//do not include the worker node
-	_starpu_composed_sched_node_recipe_t cpu_composed_sched_node;
-	_starpu_composed_sched_node_recipe_t opencl_composed_sched_node;
-	_starpu_composed_sched_node_recipe_t cuda_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_sched_tree * _starpu_make_scheduler(unsigned sched_ctx_id, struct _starpu_sched_specs);