|
@@ -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;
|
|
|
}
|