Browse Source

big modifications of the nodes interface
bitmap for worker sets in subtrees
heft is not ported yet with new interface

Simon Archipoff 12 years ago
parent
commit
0e6004646d

+ 5 - 5
src/Makefile.am

@@ -226,13 +226,13 @@ libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES = 						\
 	sched_policies/node_worker.c				\
 	sched_policies/node_worker.c				\
 	sched_policies/node_sched.c				\
 	sched_policies/node_sched.c				\
 	sched_policies/node_eager.c				\
 	sched_policies/node_eager.c				\
-	sched_policies/node_random.c				\
-	sched_policies/node_work_stealing.c			\
 	sched_policies/node_fifo.c 				\
 	sched_policies/node_fifo.c 				\
-	sched_policies/node_heft.c				\
-	sched_policies/hierarchical_heft.c			\
+	sched_policies/node_work_stealing.c			\
 	sched_policies/prio_deque.c				\
 	sched_policies/prio_deque.c				\
-	sched_policies/bitmap.c
+	sched_policies/bitmap.c					\
+	sched_policies/node_random.c				
+#	sched_policies/node_heft.c				\
+	sched_policies/hierarchical_heft.c
 if STARPU_USE_CPU
 if STARPU_USE_CPU
 libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES += drivers/cpu/driver_cpu.c
 libstarpu_@STARPU_EFFECTIVE_VERSION@_la_SOURCES += drivers/cpu/driver_cpu.c
 endif
 endif

+ 1 - 1
src/core/sched_policy.c

@@ -36,7 +36,7 @@ static struct starpu_sched_policy *predefined_policies[] =
 	&_starpu_sched_tree_eager_policy,
 	&_starpu_sched_tree_eager_policy,
 	&_starpu_sched_tree_random_policy,
 	&_starpu_sched_tree_random_policy,
 	&_starpu_sched_tree_ws_policy,
 	&_starpu_sched_tree_ws_policy,
-	&_starpu_sched_tree_heft_policy,
+//	&_starpu_sched_tree_heft_policy,
 	&_starpu_sched_eager_policy,
 	&_starpu_sched_eager_policy,
 	&_starpu_sched_prio_policy,
 	&_starpu_sched_prio_policy,
 	&_starpu_sched_random_policy,
 	&_starpu_sched_random_policy,

+ 1 - 1
src/core/sched_policy.h

@@ -68,5 +68,5 @@ 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_eager_policy;
 extern struct starpu_sched_policy _starpu_sched_tree_random_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_ws_policy;
-extern struct starpu_sched_policy _starpu_sched_tree_heft_policy;
+//extern struct starpu_sched_policy _starpu_sched_tree_heft_policy;
 #endif // __SCHED_POLICY_H__
 #endif // __SCHED_POLICY_H__

+ 123 - 25
src/sched_policies/bitmap.c

@@ -1,9 +1,12 @@
 #include <limits.h>
 #include <limits.h>
 #include <string.h>
 #include <string.h>
 #include <stdlib.h>
 #include <stdlib.h>
+#include <starpu.h>
+#include "bitmap.h"
 struct _starpu_bitmap{
 struct _starpu_bitmap{
 	unsigned long * bits;
 	unsigned long * bits;
 	int size;
 	int size;
+	int cardinal;
 };
 };
 
 
 struct _starpu_bitmap * _starpu_bitmap_create(void)
 struct _starpu_bitmap * _starpu_bitmap_create(void)
@@ -18,45 +21,53 @@ void _starpu_bitmap_destroy(struct _starpu_bitmap * b)
 	free(b);
 	free(b);
 }
 }
 
 
-
-struct tuple {
-	int nb_long;
-	int nb_bit;
-};
-
-static inline struct tuple get_tuple(int e)
-{
-	int i;
-	for(i = 0; e > LONG_BIT; e -= LONG_BIT, i++)
-		;
-	struct tuple t = {i, e};
-	return t;
-}
-
 void _starpu_bitmap_set(struct _starpu_bitmap * b, int e)
 void _starpu_bitmap_set(struct _starpu_bitmap * b, int e)
 {
 {
-	struct tuple t = get_tuple(e);
-	if(t.nb_long + 1 > b->size)
+	if(!_starpu_bitmap_get(b, e))
+		b->cardinal++;
+	if((e/LONG_BIT) + 1 > b->size)
 	{
 	{
-		b->bits = realloc(b->bits, sizeof(unsigned long) * (t.nb_long + 1));
-		b->size = t.nb_long + 1;
+		b->bits = realloc(b->bits, sizeof(unsigned long) * ((e/LONG_BIT) + 1));
+		memset(b->bits + b->size, 0, sizeof(unsigned long) * ((e/LONG_BIT + 1) - b->size));
+		b->size = (e/LONG_BIT) + 1;
 	}
 	}
-	b->bits[t.nb_long] |= (1ul << t.nb_bit);
+	b->bits[e/LONG_BIT] |= (1ul << (e%LONG_BIT));
 }
 }
 void _starpu_bitmap_unset(struct _starpu_bitmap *b, int e)
 void _starpu_bitmap_unset(struct _starpu_bitmap *b, int e)
 {
 {
-	struct tuple t = get_tuple(e);
+	if(!_starpu_bitmap_get(b, e))
+		b->cardinal--;
 	if(e / LONG_BIT > b->size)
 	if(e / LONG_BIT > b->size)
 		return;
 		return;
-	b->bits[t.nb_long] ^= ~(1ul << t.nb_bit);
+	b->bits[e/LONG_BIT] ^= ~(1ul << (e%LONG_BIT));
+}
+
+void _starpu_bitmap_unset_all(struct _starpu_bitmap * b)
+{
+	free(b->bits);
+	b->bits = NULL;
+	b->size = 0;
 }
 }
 
 
 int _starpu_bitmap_get(struct _starpu_bitmap * b, int e)
 int _starpu_bitmap_get(struct _starpu_bitmap * b, int e)
 {
 {
-	if(e / LONG_BIT > b->size)
+	if(e / LONG_BIT >= b->size)
 		return 0;
 		return 0;
-	struct tuple t = get_tuple(e);
-	return b->bits[t.nb_long] & (1 << t.nb_bit);
+	return b->bits[e/LONG_BIT] & (1 << (e%LONG_BIT));
+}
+
+void _starpu_bitmap_or(struct _starpu_bitmap * a, struct _starpu_bitmap * b)
+{
+	if(a->size < b->size)
+	{
+		a->bits = realloc(a->bits, b->size * sizeof(unsigned long));
+		a->size = b->size;
+	}
+	int i;
+	for(i = 0; i < b->size; i++)
+	{
+		a->bits[i] |= b->bits[i];
+	}
 }
 }
 
 
 
 
@@ -65,4 +76,91 @@ int _starpu_bitmap_and_get(struct _starpu_bitmap * b1, struct _starpu_bitmap * b
 	return _starpu_bitmap_get(b1,e) && _starpu_bitmap_get(b2,e);
 	return _starpu_bitmap_get(b1,e) && _starpu_bitmap_get(b2,e);
 }
 }
 
 
+int _starpu_bitmap_cardinal(struct _starpu_bitmap * b)
+{
+	return b->cardinal;
+}
+
+
+static inline int get_first_bit_rank(unsigned long ms)
+{
+	STARPU_ASSERT(ms != 0);
+	unsigned long m = 1ul;
+	int i = 0;
+	while(!(m&ms))
+		i++,m<<=1;
+	return i;
+}
+
+
+int _starpu_bitmap_first(struct _starpu_bitmap * b)
+{
+	int i = 0;
+	while(i < b->size && !b->bits[i])
+		i++;
+	if( i == b->size)
+		return -1;
+	int nb_long = i;
+	unsigned long ms = b->bits[i];
+	int m = 1;
+	i = 0;
+	while(!(m&ms))
+		i++,m<<=1;
+	return (nb_long * LONG_BIT) + i;
+}
+
+int _starpu_bitmap_has_next(struct _starpu_bitmap * b, int e)
+{
+	int nb_long = e / LONG_BIT;
+	int nb_bit = e % LONG_BIT;
+	unsigned long mask = (~0ul) << (nb_bit + 1);
+	if(b->bits[nb_long] & mask)
+		return 1;
+	for(nb_long++; nb_long < b->size; nb_long++)
+		if(b->bits[nb_long])
+			return 1;
+	return 0;
+}
+
+int _starpu_bitmap_last(struct _starpu_bitmap * b)
+{
+	if(b->cardinal == 0)
+		return -1;
+	int ilong;
+	for(ilong = b->size - 1; ilong >= 0; ilong--)
+	{
+		if(b->bits[ilong])
+			break;
+	}
+	STARPU_ASSERT(ilong >= 0);
+	unsigned long l = b->bits[ilong];
+	int ibit = LONG_BIT - 1;
+	while((!(1ul << ibit)) & l)
+		ibit--;
+	STARPU_ASSERT(ibit >= 0);
+	return ilong * LONG_BIT + ibit;
+}
+
+int _starpu_bitmap_next(struct _starpu_bitmap *b, int e)
+{
+	int nb_long = e / LONG_BIT;
+	int nb_bit = e % LONG_BIT;
+	if((~0ul << (nb_bit + 1)) & b->bits[nb_long])
+	{
+		unsigned long mask = 1ul<<nb_bit;
+		int i = nb_bit + 1;
+		while(1)
+		{
+			if(b->bits[nb_long] & (mask<<i))
+				return (nb_long * LONG_BIT) + nb_bit + i;
+			i++;
+		}
+	}
+
+	for(nb_long++;nb_long < b->size; nb_long++)
+		if(b->bits[nb_long])
+			return nb_long * LONG_BIT + get_first_bit_rank(b->bits[nb_long]);
+	return -1;
+}
+
 
 

+ 11 - 0
src/sched_policies/bitmap.h

@@ -8,14 +8,25 @@ void _starpu_bitmap_destroy(struct _starpu_bitmap *);
 
 
 void _starpu_bitmap_set(struct _starpu_bitmap *, int);
 void _starpu_bitmap_set(struct _starpu_bitmap *, int);
 void _starpu_bitmap_unset(struct _starpu_bitmap *, int);
 void _starpu_bitmap_unset(struct _starpu_bitmap *, int);
+void _starpu_bitmap_unset_all(struct _starpu_bitmap *);
 
 
 int _starpu_bitmap_get(struct _starpu_bitmap *, int);
 int _starpu_bitmap_get(struct _starpu_bitmap *, int);
 
 
+//this is basically compute a |= b;
+void _starpu_bitmap_or(struct _starpu_bitmap * a,
+		       struct _starpu_bitmap * b);
+
 //return 1 iff e set in b1 AND e set in b2
 //return 1 iff e set in b1 AND e set in b2
 int _starpu_bitmap_and_get(struct _starpu_bitmap * b1,
 int _starpu_bitmap_and_get(struct _starpu_bitmap * b1,
 			   struct _starpu_bitmap * b2,
 			   struct _starpu_bitmap * b2,
 			   int e);
 			   int e);
 
 
+int _starpu_bitmap_cardinal(struct _starpu_bitmap *);
 
 
+//return the index of first bit, -1 if none
+int _starpu_bitmap_first(struct _starpu_bitmap *);
+int _starpu_bitmap_last(struct _starpu_bitmap *);
+//return the index of bit right after e, -1 if none
+int _starpu_bitmap_next(struct _starpu_bitmap *, int e);
 
 
 #endif
 #endif

+ 1 - 2
src/sched_policies/hierarchical_heft.c

@@ -1,7 +1,7 @@
 #include "node_sched.h"
 #include "node_sched.h"
 #include <core/workers.h>
 #include <core/workers.h>
 
 
-#ifdef STARPU_HAVE_HWLOC
+#if 0//def STARPU_HAVE_HWLOC
 #include <hwloc.h>
 #include <hwloc.h>
 /*
 /*
  * this function attempt to create a scheduler with a heft node at top,
  * this function attempt to create a scheduler with a heft node at top,
@@ -40,7 +40,6 @@ struct _starpu_sched_node * _starpu_heft_eager_scheduler_add_worker(unsigned sch
 	for(i = 0; i < root->nchilds; i++)
 	for(i = 0; i < root->nchilds; i++)
 	{
 	{
 		struct _starpu_sched_node * child = root->childs[i];
 		struct _starpu_sched_node * child = root->childs[i];
-		STARPU_ASSERT(child->nworkers > 0);
 		int wid = child->workerids[0];
 		int wid = child->workerids[0];
 		hwloc_bitmap_t b = get_nodeset(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))
 		if(hwloc_bitmap_intersects(b,node) && starpu_worker_get_type(wid) == starpu_worker_get_type(workerid))

+ 14 - 32
src/sched_policies/node_eager.c

@@ -11,54 +11,36 @@ static void initialize_eager_center_policy(unsigned sched_ctx_id)
 	struct _starpu_sched_tree *data = malloc(sizeof(struct _starpu_sched_tree));
 	struct _starpu_sched_tree *data = malloc(sizeof(struct _starpu_sched_tree));
 	STARPU_PTHREAD_RWLOCK_INIT(&data->lock,NULL);
 	STARPU_PTHREAD_RWLOCK_INIT(&data->lock,NULL);
  	data->root = _starpu_sched_node_fifo_create();
  	data->root = _starpu_sched_node_fifo_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;
+		node->fathers[sched_ctx_id] = data->root;
+		_starpu_sched_node_add_child(data->root, node);
+	}
+	_starpu_set_workers_bitmaps();
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)data);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)data);
 }
 }
 
 
 static void deinitialize_eager_center_policy(unsigned sched_ctx_id)
 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);
 	struct _starpu_sched_tree *tree = (struct _starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
+	_starpu_bitmap_destroy(tree->workers);
 	_starpu_tree_destroy(tree, sched_ctx_id);
 	_starpu_tree_destroy(tree, sched_ctx_id);
 	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
 	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
 }
 }
 
 
-static void add_worker_eager(unsigned sched_ctx_id, int * workerids, unsigned nworkers)
-{
-	struct _starpu_sched_tree *t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-
-	STARPU_PTHREAD_RWLOCK_WRLOCK(&t->lock);
-	unsigned i;
-	for(i = 0; i < nworkers; i++)
-	{
-		t->root->add_child(t->root, _starpu_sched_node_worker_get(workerids[i]), sched_ctx_id);
-		_starpu_sched_node_worker_get(workerids[i])->fathers[sched_ctx_id] = t->root;
-	}
-	_starpu_tree_update_after_modification(t);
-	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
-}
-
-static void remove_worker_eager(unsigned sched_ctx_id, int * workerids, unsigned nworkers)
-{
-	struct _starpu_sched_tree *t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	STARPU_PTHREAD_RWLOCK_WRLOCK(&t->lock);
-	unsigned i;	
-	for(i = 0; i < nworkers; i++)
-	{
-		t->root->remove_child(t->root, _starpu_sched_node_worker_get(workerids[i]), sched_ctx_id);
-		_starpu_sched_node_worker_get(workerids[i])->fathers[sched_ctx_id] = NULL;
-	}
-	_starpu_tree_update_after_modification(t);
-	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
-}
-
 
 
 
 
 struct starpu_sched_policy _starpu_sched_tree_eager_policy =
 struct starpu_sched_policy _starpu_sched_tree_eager_policy =
 {
 {
 	.init_sched = initialize_eager_center_policy,
 	.init_sched = initialize_eager_center_policy,
 	.deinit_sched = deinitialize_eager_center_policy,
 	.deinit_sched = deinitialize_eager_center_policy,
-	.add_workers = add_worker_eager,
-	.remove_workers = remove_worker_eager,
+	.add_workers = _starpu_tree_add_workers,
+	.remove_workers = _starpu_tree_remove_workers,
 	.push_task = _starpu_tree_push_task,
 	.push_task = _starpu_tree_push_task,
 	.pop_task = _starpu_tree_pop_task,
 	.pop_task = _starpu_tree_pop_task,
 	.pre_exec_hook = NULL,
 	.pre_exec_hook = NULL,

+ 33 - 13
src/sched_policies/node_fifo.c

@@ -38,16 +38,34 @@ static struct _starpu_task_execute_preds estimated_execute_preds(struct _starpu_
 
 
 static double estimated_load(struct _starpu_sched_node * node)
 static double estimated_load(struct _starpu_sched_node * node)
 {
 {
+	struct _starpu_fifo_data * data = node->data;
+	struct _starpu_prio_deque * fifo = &data->fifo;
+	starpu_pthread_mutex_t * mutex = &data->mutex;
 	double relative_speedup = 0.0;
 	double relative_speedup = 0.0;
+	double load;
+
+	if(node->is_homogeneous)
+	{
+		relative_speedup = starpu_worker_get_relative_speedup(starpu_worker_get_perf_archtype(_starpu_bitmap_first(node->workers)));
+		STARPU_PTHREAD_MUTEX_LOCK(mutex);
+		load = fifo->ntasks / relative_speedup;
+		STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
+		return load;
+	}
+	else
+	{
+		int i;
+		for(i = _starpu_bitmap_first(node->workers);
+		    i != -1;
+		    i = _starpu_bitmap_next(node->workers, i))
+			relative_speedup += starpu_worker_get_relative_speedup(starpu_worker_get_perf_archtype(i));
+		relative_speedup /= _starpu_bitmap_cardinal(node->workers);
+			STARPU_ASSERT(!_STARPU_IS_ZERO(relative_speedup));
+			STARPU_PTHREAD_MUTEX_LOCK(mutex);
+			load = fifo->ntasks / relative_speedup;
+			STARPU_PTHREAD_MUTEX_UNLOCK(mutex);
+	}
 	int i;
 	int i;
-	STARPU_ASSERT(node->nworkers > 0);
-	int nworkers = node->is_homogeneous ? 1 : node->nworkers;
-	for(i = 0; i < nworkers; i++)
-		relative_speedup += starpu_worker_get_relative_speedup(starpu_worker_get_perf_archtype(node->workerids[i]));
-	relative_speedup /= nworkers;
-	struct _starpu_prio_deque * fifo = node->data;
-	STARPU_ASSERT(!_STARPU_IS_ZERO(relative_speedup));
-	double load = fifo->ntasks / relative_speedup; 
 	for(i = 0; i < node->nchilds; i++)
 	for(i = 0; i < node->nchilds; i++)
 	{
 	{
 		struct _starpu_sched_node * c = node->childs[i];
 		struct _starpu_sched_node * c = node->childs[i];
@@ -56,9 +74,9 @@ static double estimated_load(struct _starpu_sched_node * node)
 	return load;
 	return load;
 }
 }
 
 
-static int push_task(struct _starpu_sched_node * node, struct starpu_task * task)
+static int push_task(struct _starpu_sched_node * node, struct starpu_task * task, struct _starpu_bitmap * worker_mask)
 {
 {
-	STARPU_ASSERT(node->nworkers > 0);
+	STARPU_ASSERT(_starpu_sched_node_can_execute_task(node,task, worker_mask));
 	struct _starpu_fifo_data * data = node->data;
 	struct _starpu_fifo_data * data = node->data;
 	struct _starpu_prio_deque * fifo = &data->fifo;
 	struct _starpu_prio_deque * fifo = &data->fifo;
 	starpu_pthread_mutex_t * mutex = &data->mutex;
 	starpu_pthread_mutex_t * mutex = &data->mutex;
@@ -69,7 +87,8 @@ static int push_task(struct _starpu_sched_node * node, struct starpu_task * task
 	int ret = _starpu_prio_deque_push_task(fifo, task);
 	int ret = _starpu_prio_deque_push_task(fifo, task);
 	if(!isnan(task->predicted))
 	if(!isnan(task->predicted))
 	{
 	{
-		fifo->exp_len += task->predicted/node->nworkers;
+		task->predicted /= _starpu_bitmap_cardinal(node->workers);
+		fifo->exp_len += task->predicted;
 		fifo->exp_end = fifo->exp_start + fifo->exp_len;
 		fifo->exp_end = fifo->exp_start + fifo->exp_len;
 	}
 	}
 	STARPU_ASSERT(!isnan(fifo->exp_end));
 	STARPU_ASSERT(!isnan(fifo->exp_end));
@@ -96,9 +115,8 @@ static struct starpu_task * pop_task(struct _starpu_sched_node * node, unsigned
 	if(task)
 	if(task)
 	{
 	{
 		fifo->exp_start = starpu_timing_now();
 		fifo->exp_start = starpu_timing_now();
-		STARPU_ASSERT(node->nworkers > 0);
 		if(!isnan(task->predicted))
 		if(!isnan(task->predicted))
-			fifo->exp_len -= task->predicted/node->nworkers;
+			fifo->exp_len -= task->predicted;
 		fifo->exp_end = fifo->exp_start + fifo->exp_len;
 		fifo->exp_end = fifo->exp_start + fifo->exp_len;
 	}
 	}
 	STARPU_ASSERT(!isnan(fifo->exp_end));
 	STARPU_ASSERT(!isnan(fifo->exp_end));
@@ -135,6 +153,8 @@ struct starpu_task_list  _starpu_sched_node_fifo_get_non_executable_tasks(struct
 	return list;
 	return list;
 }
 }
 */
 */
+
+
 int _starpu_sched_node_is_fifo(struct _starpu_sched_node * node)
 int _starpu_sched_node_is_fifo(struct _starpu_sched_node * node)
 {
 {
 	return node->estimated_execute_preds == estimated_execute_preds
 	return node->estimated_execute_preds == estimated_execute_preds

+ 33 - 77
src/sched_policies/node_random.c

@@ -22,45 +22,34 @@ static double compute_relative_speedup(struct _starpu_sched_node * node)
 	return sum;
 	return sum;
 }
 }
 
 
-static void update_relative_childs_speedup(struct _starpu_sched_node * node)
+static void init_data_random(struct _starpu_sched_node * node)
 {
 {
-	struct _starpu_random_data * rd = node->data;
-	rd->relative_speedup = realloc(rd->relative_speedup,sizeof(double) * node->nchilds);
+	struct _starpu_random_data * rd = malloc(sizeof(struct _starpu_random_data));
+	node->data = rd;
+	rd->relative_speedup = malloc(sizeof(double) * node->nchilds);
 	int i;
 	int i;
 	for(i = 0; i < node->nchilds; i++)
 	for(i = 0; i < node->nchilds; i++)
 		rd->relative_speedup[i] = compute_relative_speedup(node->childs[i]);
 		rd->relative_speedup[i] = compute_relative_speedup(node->childs[i]);
 }
 }
 
 
-static void add_child(struct _starpu_sched_node *node,
-		      struct _starpu_sched_node *child,
-		      unsigned sched_ctx_id)
-{
-//	STARPU_PTHREAD_RWLOCK_WRLOCK(&node->mutex);
-	_starpu_sched_node_add_child(node, child, sched_ctx_id);
-	update_relative_childs_speedup(node);
-//	STARPU_PTHREAD_RWLOCK_UNLOCK(&node->mutex);
-}
-static void remove_child(struct _starpu_sched_node *node,
-			 struct _starpu_sched_node *child,
-			 unsigned sched_ctx_id)
+static void deinit_data_random(struct _starpu_sched_node * node)
 {
 {
-//	STARPU_PTHREAD_RWLOCK_WRLOCK(&node->mutex);
-	_starpu_sched_node_remove_child(node, child, sched_ctx_id);
-	update_relative_childs_speedup(node);
-//	STARPU_PTHREAD_RWLOCK_UNLOCK(&node->mutex);
+	struct _starpu_random_data * rd = node->data;
+	free(rd->relative_speedup);
+	free(rd);
+	
 }
 }
 
 
-
-static int push_task(struct _starpu_sched_node * node, struct starpu_task * task)
+static int push_task(struct _starpu_sched_node * node, struct starpu_task * task, struct _starpu_bitmap * worker_mask)
 {
 {
 	struct _starpu_random_data * rd = node->data;
 	struct _starpu_random_data * rd = node->data;
-//	STARPU_PTHREAD_RWLOCK_RDLOCK(&node->mutex);
+
 	int indexes_nodes[node->nchilds];
 	int indexes_nodes[node->nchilds];
 	int size=0,i;
 	int size=0,i;
 	double alpha_sum = 0.0;
 	double alpha_sum = 0.0;
 	for(i = 0; i < node->nchilds ; i++)
 	for(i = 0; i < node->nchilds ; i++)
 	{
 	{
-		if(_starpu_sched_node_can_execute_task(node->childs[i],task))
+		if(_starpu_sched_node_can_execute_task(node->childs[i],task, worker_mask))
 		{
 		{
 			indexes_nodes[size++] = i;
 			indexes_nodes[size++] = i;
 			alpha_sum += rd->relative_speedup[i];
 			alpha_sum += rd->relative_speedup[i];
@@ -82,32 +71,20 @@ static int push_task(struct _starpu_sched_node * node, struct starpu_task * task
 		alpha += rd->relative_speedup[index];
 		alpha += rd->relative_speedup[index];
 	}
 	}
 	STARPU_ASSERT(select != NULL);
 	STARPU_ASSERT(select != NULL);
-	int ret_val = select->push_task(select,task);
+	int ret_val = select->push_task(select,task, worker_mask);
 	node->available(node);
 	node->available(node);
-//	STARPU_PTHREAD_RWLOCK_UNLOCK(&node->mutex);
-	return ret_val;
-}
 
 
-static void destroy_random_node(struct _starpu_sched_node * node)
-{
-	struct _starpu_random_data * rd = node->data;
-	free(rd->relative_speedup);
-	free(rd);
-	_starpu_sched_node_destroy(node);
+	return ret_val;
 }
 }
 
 
 
 
 struct _starpu_sched_node * _starpu_sched_node_random_create(void)
 struct _starpu_sched_node * _starpu_sched_node_random_create(void)
 {
 {
 	struct _starpu_sched_node * node = _starpu_sched_node_create();
 	struct _starpu_sched_node * node = _starpu_sched_node_create();
-	struct _starpu_random_data * rd = malloc(sizeof(struct _starpu_random_data));
-
-	rd->relative_speedup = NULL;
-	node->data = rd;
-	node->destroy_node = destroy_random_node;
+	node->data = NULL;
+	node->init_data = init_data_random;
+	node->deinit_data = deinit_data_random;
 	node->push_task = push_task;
 	node->push_task = push_task;
-	node->add_child = add_child;
-	node->remove_child = remove_child;
 	starpu_srand48(time(NULL));
 	starpu_srand48(time(NULL));
 	return node;
 	return node;
 }
 }
@@ -118,57 +95,36 @@ static void initialize_random_center_policy(unsigned sched_ctx_id)
 	struct _starpu_sched_tree *data = malloc(sizeof(struct _starpu_sched_tree));
 	struct _starpu_sched_tree *data = malloc(sizeof(struct _starpu_sched_tree));
 	STARPU_PTHREAD_RWLOCK_INIT(&data->lock,NULL);
 	STARPU_PTHREAD_RWLOCK_INIT(&data->lock,NULL);
  	data->root = _starpu_sched_node_random_create();
  	data->root = _starpu_sched_node_random_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;
+		node->fathers[sched_ctx_id] = data->root;
+		_starpu_sched_node_add_child(data->root, node);
+	}
+	_starpu_set_workers_bitmaps();
+	_starpu_call_init_data(data);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)data);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)data);
 }
 }
 static void deinitialize_random_center_policy(unsigned sched_ctx_id)
 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);
 	struct _starpu_sched_tree *tree = (struct _starpu_sched_tree*)starpu_sched_ctx_get_policy_data(sched_ctx_id);
+	_starpu_bitmap_destroy(tree->workers);
 	_starpu_tree_destroy(tree, sched_ctx_id);
 	_starpu_tree_destroy(tree, sched_ctx_id);
 	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
 	starpu_sched_ctx_delete_worker_collection(sched_ctx_id);
 }
 }
 
 
 
 
- static void add_worker_random(unsigned sched_ctx_id, int * workerids, unsigned nworkers)
-{
-	struct _starpu_sched_tree *t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-		struct _starpu_sched_node * random_node = t->root;
-	STARPU_PTHREAD_RWLOCK_WRLOCK(&t->lock);
-	unsigned i;
-	for(i = 0; i < nworkers; i++)
-	{
-		struct _starpu_sched_node * worker = _starpu_sched_node_worker_get(workerids[i]);
-		t->root->add_child(random_node, _starpu_sched_node_worker_get(workerids[i]), sched_ctx_id);
-		_starpu_sched_node_set_father(worker, random_node, sched_ctx_id);
-	}
-	_starpu_tree_update_after_modification(t);
-	update_relative_childs_speedup(random_node);
-	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
-}
-
-static void remove_worker_random(unsigned sched_ctx_id, int * workerids, unsigned nworkers)
-{
-	struct _starpu_sched_tree * t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-
-	STARPU_PTHREAD_RWLOCK_WRLOCK(&t->lock);
-	struct _starpu_sched_node * random_node = t->root;
-	unsigned i;
-	for(i = 0; i < nworkers; i++)
-	{
-		struct _starpu_sched_node * worker = _starpu_sched_node_worker_get(workerids[i]);
-		random_node->remove_child(random_node, worker, sched_ctx_id);
-		_starpu_sched_node_set_father(worker, NULL, sched_ctx_id);
-	}
-	_starpu_tree_update_after_modification(t);
-	update_relative_childs_speedup(t->root);
-	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
-}
-
 struct starpu_sched_policy _starpu_sched_tree_random_policy =
 struct starpu_sched_policy _starpu_sched_tree_random_policy =
 {
 {
 	.init_sched = initialize_random_center_policy,
 	.init_sched = initialize_random_center_policy,
 	.deinit_sched = deinitialize_random_center_policy,
 	.deinit_sched = deinitialize_random_center_policy,
-	.add_workers = add_worker_random,
-	.remove_workers = remove_worker_random,
+	.add_workers = _starpu_tree_add_workers,
+	.remove_workers = _starpu_tree_remove_workers,
 	.push_task = _starpu_tree_push_task,
 	.push_task = _starpu_tree_push_task,
 	.pop_task = _starpu_tree_pop_task,
 	.pop_task = _starpu_tree_pop_task,
 	.pre_exec_hook = NULL,
 	.pre_exec_hook = NULL,

+ 97 - 89
src/sched_policies/node_sched.c

@@ -71,11 +71,32 @@ int push_task(struct starpu_task * task)
 	unsigned sched_ctx_id = task->sched_ctx;
 	unsigned sched_ctx_id = task->sched_ctx;
 	struct _starpu_sched_tree * t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
 	struct _starpu_sched_tree * t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
 	STARPU_PTHREAD_RWLOCK_RDLOCK(&t->lock);
 	STARPU_PTHREAD_RWLOCK_RDLOCK(&t->lock);
-	int ret = t->root->push_task(t->root, task);
+	int ret = t->root->push_task(t->root, task, t->workers);
 	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
 	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
 	return ret;
 	return ret;
 }
 }
 
 
+void _starpu_tree_add_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers)
+{
+	struct _starpu_sched_tree * t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
+	STARPU_PTHREAD_RWLOCK_WRLOCK(&t->lock);
+	unsigned i;
+	for(i = 0; i < nworkers; i++)
+		_starpu_bitmap_set(t->workers, workerids[i]);
+	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
+}
+
+void _starpu_tree_remove_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers)
+{
+	struct _starpu_sched_tree * t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
+	STARPU_PTHREAD_RWLOCK_WRLOCK(&t->lock);
+	unsigned i;
+	for(i = 0; i < nworkers; i++)
+		_starpu_bitmap_unset(t->workers, workerids[i]);
+	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
+}
+
+
 void _starpu_node_destroy_rec(struct _starpu_sched_node * node, unsigned sched_ctx_id)
 void _starpu_node_destroy_rec(struct _starpu_sched_node * node, unsigned sched_ctx_id)
 {
 {
 	if(node == NULL)
 	if(node == NULL)
@@ -119,7 +140,8 @@ void _starpu_node_destroy_rec(struct _starpu_sched_node * node, unsigned sched_c
 			if(!shared)//if not shared we want to destroy it and his childs
 			if(!shared)//if not shared we want to destroy it and his childs
 				PUSH(child);
 				PUSH(child);
 		}
 		}
-		n->destroy_node(n);
+		n->deinit_data(n);
+		_starpu_sched_node_destroy(n);
 	}
 	}
 	free(stack);
 	free(stack);
 }
 }
@@ -129,7 +151,7 @@ void _starpu_tree_destroy(struct _starpu_sched_tree * tree, unsigned sched_ctx_i
 	STARPU_PTHREAD_RWLOCK_DESTROY(&tree->lock);
 	STARPU_PTHREAD_RWLOCK_DESTROY(&tree->lock);
 	free(tree);
 	free(tree);
 }
 }
-void _starpu_sched_node_add_child(struct _starpu_sched_node* node, struct _starpu_sched_node * child,unsigned sched_ctx_id STARPU_ATTRIBUTE_UNUSED)
+void _starpu_sched_node_add_child(struct _starpu_sched_node* node, struct _starpu_sched_node * child)
 {
 {
 	STARPU_ASSERT(!_starpu_sched_node_is_worker(node));
 	STARPU_ASSERT(!_starpu_sched_node_is_worker(node));
 	int i;
 	int i;
@@ -142,7 +164,7 @@ void _starpu_sched_node_add_child(struct _starpu_sched_node* node, struct _starp
 	node->childs[node->nchilds] = child;
 	node->childs[node->nchilds] = child;
 	node->nchilds++;
 	node->nchilds++;
 }
 }
-void _starpu_sched_node_remove_child(struct _starpu_sched_node * node, struct _starpu_sched_node * child,unsigned sched_ctx_id STARPU_ATTRIBUTE_UNUSED)
+void _starpu_sched_node_remove_child(struct _starpu_sched_node * node, struct _starpu_sched_node * child)
 {
 {
 	int pos;
 	int pos;
 	for(pos = 0; pos < node->nchilds; pos++)
 	for(pos = 0; pos < node->nchilds; pos++)
@@ -158,7 +180,7 @@ int _starpu_tree_push_task(struct starpu_task * task)
 	unsigned sched_ctx_id = task->sched_ctx;
 	unsigned sched_ctx_id = task->sched_ctx;
 	struct _starpu_sched_tree *tree = starpu_sched_ctx_get_policy_data(sched_ctx_id);
 	struct _starpu_sched_tree *tree = starpu_sched_ctx_get_policy_data(sched_ctx_id);
 	STARPU_PTHREAD_RWLOCK_RDLOCK(&tree->lock);
 	STARPU_PTHREAD_RWLOCK_RDLOCK(&tree->lock);
-	int ret_val = tree->root->push_task(tree->root,task); 
+	int ret_val = tree->root->push_task(tree->root,task,tree->workers);
 	STARPU_PTHREAD_RWLOCK_UNLOCK(&tree->lock);
 	STARPU_PTHREAD_RWLOCK_UNLOCK(&tree->lock);
 	return ret_val;
 	return ret_val;
 }
 }
@@ -263,48 +285,62 @@ static double estimated_transfer_length(struct _starpu_sched_node * node, struct
 	return sum;
 	return sum;
 }
 }
 */
 */
-int _starpu_sched_node_can_execute_task(struct _starpu_sched_node * node, struct starpu_task * task)
+int _starpu_sched_node_can_execute_task(struct _starpu_sched_node * node, struct starpu_task * task, struct _starpu_bitmap * worker_mask)
 {
 {
 	unsigned nimpl;
 	unsigned nimpl;
 	int worker;
 	int worker;
 	STARPU_ASSERT(task);
 	STARPU_ASSERT(task);
 	STARPU_ASSERT(node);
 	STARPU_ASSERT(node);
 	for (nimpl = 0; nimpl < STARPU_MAXIMPLEMENTATIONS; nimpl++)
 	for (nimpl = 0; nimpl < STARPU_MAXIMPLEMENTATIONS; nimpl++)
-		for(worker = 0; worker < node->nworkers; worker++)
-			if (starpu_worker_can_execute_task(node->workerids[worker], task, nimpl))
+		for(worker = _starpu_bitmap_first(node->workers);
+		    -1 != worker;
+		    worker = _starpu_bitmap_next(node->workers, worker))
+			if (_starpu_bitmap_get(worker_mask, worker)
+			    && starpu_worker_can_execute_task(worker, task, nimpl))
 				return 1;
 				return 1;
+
 	return 0;
 	return 0;
 }
 }
 
 
-int _starpu_sched_node_can_execute_task_with_impl(struct _starpu_sched_node * node, struct starpu_task * task, unsigned nimpl)
+int _starpu_sched_node_can_execute_task_with_impl(struct _starpu_sched_node * node, struct starpu_task * task, unsigned nimpl, struct _starpu_bitmap * worker_mask)
 {
 {
 
 
 	int worker;
 	int worker;
 	STARPU_ASSERT(task);
 	STARPU_ASSERT(task);
 	STARPU_ASSERT(nimpl < STARPU_MAXIMPLEMENTATIONS);
 	STARPU_ASSERT(nimpl < STARPU_MAXIMPLEMENTATIONS);
-	for(worker = 0; worker < node->nworkers; worker++)
-		if (starpu_worker_can_execute_task(worker, task, nimpl))
+	for(worker = _starpu_bitmap_first(node->workers);
+	    worker != -1;
+	    worker = _starpu_bitmap_next(node->workers, worker))
+		if (_starpu_bitmap_get(worker_mask, worker)
+		    && starpu_worker_can_execute_task(worker, task, nimpl))
 			return 1;
 			return 1;
 	return 0;
 	return 0;
 
 
 }
 }
 
 
+void take_node_and_does_nothing(struct _starpu_sched_node * node STARPU_ATTRIBUTE_UNUSED)
+{
+}
+
 struct _starpu_sched_node * _starpu_sched_node_create(void)
 struct _starpu_sched_node * _starpu_sched_node_create(void)
 {
 {
 	struct _starpu_sched_node * node = malloc(sizeof(*node));
 	struct _starpu_sched_node * node = malloc(sizeof(*node));
 	memset(node,0,sizeof(*node));
 	memset(node,0,sizeof(*node));
+	node->workers = _starpu_bitmap_create();
 	node->available = available;
 	node->available = available;
+	node->init_data = take_node_and_does_nothing;
+	node->deinit_data = take_node_and_does_nothing;
 	node->pop_task = pop_task_node;
 	node->pop_task = pop_task_node;
 	node->estimated_load = estimated_load;
 	node->estimated_load = estimated_load;
 	node->estimated_execute_preds = estimated_execute_preds;
 	node->estimated_execute_preds = estimated_execute_preds;
-	node->destroy_node = _starpu_sched_node_destroy;
-	node->add_child = _starpu_sched_node_add_child;
-	node->remove_child = _starpu_sched_node_remove_child;
 
 
 	return node;
 	return node;
 }
 }
 void _starpu_sched_node_destroy(struct _starpu_sched_node *node)
 void _starpu_sched_node_destroy(struct _starpu_sched_node *node)
 {
 {
+	if(_starpu_sched_node_is_worker(node))
+		return;
+
 	int i,j;
 	int i,j;
 	for(i = 0; i < node->nchilds; i++)
 	for(i = 0; i < node->nchilds; i++)
 	{
 	{
@@ -315,103 +351,70 @@ void _starpu_sched_node_destroy(struct _starpu_sched_node *node)
 
 
 	}
 	}
 	free(node->childs);
 	free(node->childs);
+	_starpu_bitmap_destroy(node->workers);
+
 	free(node);
 	free(node);
 }
 }
 
 
 
 
-static int is_homogeneous(int * workerids, int nworkers)
+static void set_is_homogeneous(struct _starpu_sched_node * node)
 {
 {
-	if(nworkers < 2)
-		return 1;
-	int i = 0;
-	uint32_t last_worker = _starpu_get_worker_struct(workerids[i])->worker_mask;
-	for(i = 1; i < nworkers; i++)
+	STARPU_ASSERT(_starpu_bitmap_cardinal(node->workers) > 0);
+	if(_starpu_bitmap_cardinal(node->workers) == 1)
+		node->is_homogeneous = 1;
+	int worker = _starpu_bitmap_first(node->workers);
+	uint32_t last_worker = _starpu_get_worker_struct(worker)->worker_mask;
+	for(;
+	    worker != -1;
+	    worker = _starpu_bitmap_next(node->workers, worker))
+		
 	{
 	{
-		if(last_worker != _starpu_get_worker_struct(workerids[i])->worker_mask)
-		   return 0;
-		last_worker = _starpu_get_worker_struct(workerids[i])->worker_mask;
+		if(last_worker != _starpu_get_worker_struct(worker)->worker_mask)
+		{
+			node->is_homogeneous = 0;
+			return;
+		}
+		last_worker = _starpu_get_worker_struct(worker)->worker_mask;
 	}
 	}
-	return 1;
+	node->is_homogeneous = 1;
 }
 }
 
 
 
 
-static int in_tab(int elem, int * tab, int size)
+static void add_worker_bit(struct _starpu_sched_node * node, int worker)
 {
 {
-	for(size--;size >= 0; size--)
-		if(tab[size] == elem)
-			return 1;
-	return 0;
-}
-static void _update_workerids_after_tree_modification(struct _starpu_sched_node * node)
-{
-	if(_starpu_sched_node_is_worker(node))
-	{
-		node->nworkers = 1;
-		node->workerids[0] =  _starpu_sched_node_worker_get_workerid(node);
-	}
-	else
-	{
-		int i;
-		node->nworkers = 0;
-		for(i = 0; i < node->nchilds; i++)
+	STARPU_ASSERT(node);
+	_starpu_bitmap_set(node->workers, worker);
+	int i;
+	for(i = 0; i < STARPU_NMAX_SCHED_CTXS; i++)
+		if(node->fathers[i])
 		{
 		{
-			struct _starpu_sched_node * child = node->childs[i];
-			_update_workerids_after_tree_modification(child);
-			int j;
-			for(j = 0; j < child->nworkers; j++)
-			{
-				int id = child->workerids[j];
-				if(!in_tab(id, node->workerids, node->nworkers))
-					node->workerids[node->nworkers++] = id;
-			}
+			add_worker_bit(node->fathers[i], worker);
+			set_is_homogeneous(node->fathers[i]);
 		}
 		}
-	}
-	node->is_homogeneous = is_homogeneous(node->workerids, node->nworkers);
 }
 }
 
 
-
-void _starpu_tree_update_after_modification(struct _starpu_sched_tree * tree)
+void _starpu_set_workers_bitmaps(void)
 {
 {
-	_update_workerids_after_tree_modification(tree->root);
+	unsigned worker;	
+	for(worker = 0; worker < starpu_worker_get_count(); worker++)
+	{
+		struct _starpu_sched_node * worker_node = _starpu_sched_node_worker_get(worker);
+		add_worker_bit(worker_node, worker);
+	}
 }
 }
 
 
-
-static struct _starpu_sched_node * _starpu_sched_node_remove_worker(struct _starpu_sched_node * node, int workerid, int sched_ctx_id)
+static void helper_starpu_call_init_data(struct _starpu_sched_node *node)
 {
 {
-	if(node == NULL)
-		return NULL;
-	if(node->nworkers == 1 && node->workerids[0] == workerid)//special case if there is only one worker left
-		return node;
 	int i;
 	int i;
 	for(i = 0; i < node->nchilds; i++)
 	for(i = 0; i < node->nchilds; i++)
-	{
-
-		struct _starpu_sched_node * child = node->childs[i];
-		if(in_tab(workerid, child->workerids, child->nworkers))
-		{
-			if(child->nworkers == 1)//we wants to remove this subtree
-			{
-				node->remove_child(node, child, sched_ctx_id);
-//				if(childs->fathers[sched_ctx_id] == node)
-//					_starpu_sched_node_set_father(child, NULL, sched_ctx_id);
-				return child;
-			}
-			else//we have several worker in this subtree
-			{
-				return _starpu_sched_node_remove_worker(child, workerid, sched_ctx_id);
-			}
-		}
-	}
-	return NULL;
+		helper_starpu_call_init_data(node->childs[i]);
+	if(!node->data)
+		node->init_data(node);
 }
 }
 
 
-struct _starpu_sched_node * _starpu_sched_tree_remove_worker(struct _starpu_sched_tree * t, int workerid, int sched_ctx_id)
+void _starpu_call_init_data(struct _starpu_sched_tree * t)
 {
 {
-	struct _starpu_sched_node * node = _starpu_sched_node_remove_worker(t->root, workerid, sched_ctx_id);
-	_starpu_tree_update_after_modification(t);
-	if(node == t->root)
-		t->root = NULL;
-	return node;
+	helper_starpu_call_init_data(t->root);
 }
 }
 
 
 
 
@@ -419,14 +422,18 @@ static int push_task_to_first_suitable_parent(struct _starpu_sched_node * node,
 {
 {
 	if(node == NULL || node->fathers[sched_ctx_id] == NULL)
 	if(node == NULL || node->fathers[sched_ctx_id] == NULL)
 		return 1;
 		return 1;
+
+	struct _starpu_sched_tree *t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
+
 	
 	
 	struct _starpu_sched_node * father = node->fathers[sched_ctx_id];
 	struct _starpu_sched_node * father = node->fathers[sched_ctx_id];
-	if(_starpu_sched_node_can_execute_task(father,task))
-		return father->push_task(father, task);
+	if(_starpu_sched_node_can_execute_task(father,task,t->workers))
+		return father->push_task(father, task, t->workers);
 	else
 	else
 		return push_task_to_first_suitable_parent(father, task, sched_ctx_id);
 		return push_task_to_first_suitable_parent(father, task, sched_ctx_id);
 }
 }
 
 
+
 int _starpu_sched_node_push_tasks_to_firsts_suitable_parent(struct _starpu_sched_node * node, struct starpu_task_list *list, int sched_ctx_id)
 int _starpu_sched_node_push_tasks_to_firsts_suitable_parent(struct _starpu_sched_node * node, struct starpu_task_list *list, int sched_ctx_id)
 {
 {
 	while(!starpu_task_list_empty(list))
 	while(!starpu_task_list_empty(list))
@@ -441,3 +448,4 @@ int _starpu_sched_node_push_tasks_to_firsts_suitable_parent(struct _starpu_sched
 	}
 	}
 	return 0;
 	return 0;
 }
 }
+

+ 28 - 26
src/sched_policies/node_sched.h

@@ -2,9 +2,12 @@
 #define __SCHED_NODE_H__
 #define __SCHED_NODE_H__
 #include <starpu.h>
 #include <starpu.h>
 #include <common/starpu_spinlock.h>
 #include <common/starpu_spinlock.h>
+#include "bitmap.h"
 struct _starpu_sched_node
 struct _starpu_sched_node
 {
 {
-	int (*push_task)(struct _starpu_sched_node *, struct starpu_task *);
+	int (*push_task)(struct _starpu_sched_node *,
+			 struct starpu_task *,
+			 struct _starpu_bitmap * sched_ctx_workers_mask);
 	struct starpu_task * (*pop_task)(struct _starpu_sched_node *,
 	struct starpu_task * (*pop_task)(struct _starpu_sched_node *,
 					 unsigned sched_ctx_id);
 					 unsigned sched_ctx_id);
 	void (*available)(struct _starpu_sched_node *);
 	void (*available)(struct _starpu_sched_node *);
@@ -19,9 +22,8 @@ struct _starpu_sched_node
 	struct _starpu_sched_node ** childs;
 	struct _starpu_sched_node ** childs;
 
 
 
 
-	//the list of workers in the node's subtree
-	int workerids[STARPU_NMAXWORKERS];
-	int nworkers;
+	//the set of workers in the node's subtree
+	struct _starpu_bitmap * workers;
 
 
 	//is_homogeneous is 0 iff workers in the node's subtree are heterogeneous,
 	//is_homogeneous is 0 iff workers in the node's subtree are heterogeneous,
 	//this field is set and updated automaticaly, you shouldn't write on it
 	//this field is set and updated automaticaly, you shouldn't write on it
@@ -33,17 +35,14 @@ struct _starpu_sched_node
 	 */
 	 */
 	struct _starpu_sched_node * fathers[STARPU_NMAX_SCHED_CTXS];
 	struct _starpu_sched_node * fathers[STARPU_NMAX_SCHED_CTXS];
 
 
+	
+	/* this function is called after all childs has been set
+	 */
+	void (*init_data)(struct _starpu_sched_node *);
+	/* this function is called to free init_data malloc
+	 */
+	void (*deinit_data)(struct _starpu_sched_node *);
 
 
-	void (*add_child)(struct _starpu_sched_node *node,
-			  struct _starpu_sched_node *child,
-			  unsigned sched_ctx_id);
-
-	void (*remove_child)(struct _starpu_sched_node *node,
-			     struct _starpu_sched_node *child,
-			     unsigned sched_ctx_id);
-	/* this function is called to free node (it must call _starpu_sched_node_destroy(node));
-	*/
-	void (*destroy_node)(struct _starpu_sched_node *);
 };
 };
 
 
 struct _starpu_task_execute_preds
 struct _starpu_task_execute_preds
@@ -69,6 +68,7 @@ struct _starpu_task_execute_preds
 struct _starpu_sched_tree
 struct _starpu_sched_tree
 {
 {
 	struct _starpu_sched_node * root;
 	struct _starpu_sched_node * root;
+	struct _starpu_bitmap * workers;
 	//this lock is used to protect the scheduler during modifications of his structure
 	//this lock is used to protect the scheduler during modifications of his structure
 	starpu_pthread_rwlock_t lock;
 	starpu_pthread_rwlock_t lock;
 };
 };
@@ -91,12 +91,12 @@ 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_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, unsigned sched_ctx_id);
-void _starpu_sched_node_remove_child(struct _starpu_sched_node * node, struct _starpu_sched_node * child, 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);
 
 
 
 
-int _starpu_sched_node_can_execute_task(struct _starpu_sched_node * node, struct starpu_task * task);
-int _starpu_sched_node_can_execute_task_with_impl(struct _starpu_sched_node * node, struct starpu_task * task, unsigned nimpl);
+int _starpu_sched_node_can_execute_task(struct _starpu_sched_node * node, struct starpu_task * task, struct _starpu_bitmap * worker_mask);
+int _starpu_sched_node_can_execute_task_with_impl(struct _starpu_sched_node * node, struct starpu_task * task, unsigned nimpl, struct _starpu_bitmap * worker_mask);
 
 
 /* no public create function for workers because we dont want to have several node_worker for a single workerid */
 /* 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_sched_node * _starpu_sched_node_worker_get(int workerid);
@@ -134,17 +134,19 @@ void _starpu_node_destroy_rec(struct _starpu_sched_node * node, unsigned sched_c
 
 
 int _starpu_tree_push_task(struct starpu_task * task);
 int _starpu_tree_push_task(struct starpu_task * task);
 struct starpu_task * _starpu_tree_pop_task(unsigned sched_ctx_id);
 struct starpu_task * _starpu_tree_pop_task(unsigned sched_ctx_id);
+void _starpu_tree_remove_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
+void _starpu_tree_remove_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
+
+void _starpu_tree_add_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
+void _starpu_tree_remove_workers(unsigned sched_ctx_id, int *workerids, unsigned nworkers);
 
 
-/* this function must be called after all modification of tree
- * this function make a top bottom traversal , ence dont use .fathers field
- * if the tree is partialy shared between contexts, this function have to be called in thoses contexts
+/* this function fill all the node->workers member
  */
  */
-void _starpu_tree_update_after_modification(struct _starpu_sched_tree * tree);
-/* remove and return a subtree that contain only this worker and call starpu_tree_update_after_modification
- * this function may be called several time
- * this function dont update father fields in subtree
+void _starpu_set_workers_bitmaps(void);
+/* this function call init data on all nodes in postfix order
  */
  */
-struct _starpu_sched_node * _starpu_sched_tree_remove_worker(struct _starpu_sched_tree * tree, int workerid, int sched_ctx_id);
+void _starpu_call_init_data(struct _starpu_sched_tree * t);
+
 
 
 /* push task of list lower as possible in the tree, a non null value is returned if some task couldn't be pushed
 /* push task of list lower as possible in the tree, a non null value is returned if some task couldn't be pushed
  */
  */

+ 42 - 104
src/sched_policies/node_work_stealing.c

@@ -1,7 +1,7 @@
 #include "node_sched.h"
 #include "node_sched.h"
 #include "fifo_queues.h"
 #include "fifo_queues.h"
 #include <starpu_scheduler.h>
 #include <starpu_scheduler.h>
-
+#include <starpu.h>
 
 
 struct _starpu_work_stealing_data
 struct _starpu_work_stealing_data
 {
 {
@@ -89,13 +89,7 @@ static inline unsigned select_worker(struct _starpu_sched_node * node)
 
 
 static int is_worker_of_node(struct _starpu_sched_node * node, int workerid)
 static int is_worker_of_node(struct _starpu_sched_node * node, int workerid)
 {
 {
-	int j;
-	for(j = 0; j < node->nworkers; j++)
-	{
-		if(node->workerids[j] == workerid)
-			return 1;
-	}
-	return 0;
+	return _starpu_bitmap_get(node->workers, workerid);
 }
 }
 
 
 
 
@@ -132,7 +126,7 @@ static struct starpu_task * pop_task(struct _starpu_sched_node * node, unsigned
 
 
 
 
 
 
-static int push_task(struct _starpu_sched_node * node, struct starpu_task * task)
+static int push_task(struct _starpu_sched_node * node, struct starpu_task * task, struct _starpu_bitmap * worker_mask)
 {
 {
 	struct _starpu_work_stealing_data * wsd = node->data;
 	struct _starpu_work_stealing_data * wsd = node->data;
 	int ret = -1;
 	int ret = -1;
@@ -141,7 +135,7 @@ static int push_task(struct _starpu_sched_node * node, struct starpu_task * task
 	for(i = (start+1)%node->nchilds; i != start; i = (i+1)%node->nchilds)
 	for(i = (start+1)%node->nchilds; i != start; i = (i+1)%node->nchilds)
 	{
 	{
 		struct _starpu_sched_node * child = node->childs[i];
 		struct _starpu_sched_node * child = node->childs[i];
-		if(_starpu_sched_node_can_execute_task(child,task))
+		if(_starpu_sched_node_can_execute_task(child,task, worker_mask))
 		{
 		{
 			ret = _starpu_fifo_push_sorted_task(wsd->fifos[i], task);
 			ret = _starpu_fifo_push_sorted_task(wsd->fifos[i], task);
 			break;
 			break;
@@ -153,12 +147,6 @@ static int push_task(struct _starpu_sched_node * node, struct starpu_task * task
 }
 }
 
 
 
 
-static void add_child(struct _starpu_sched_node *node,
-		      struct _starpu_sched_node *child,
-		      unsigned sched_ctx_id);
-
-
-
 //this function is special, when a worker call it, we want to push the task in his fifo
 //this function is special, when a worker call it, we want to push the task in his fifo
 int _starpu_ws_push_task(struct starpu_task *task)
 int _starpu_ws_push_task(struct starpu_task *task)
 {
 {
@@ -202,83 +190,54 @@ int _starpu_ws_push_task(struct starpu_task *task)
 }
 }
 
 
 
 
-static void add_child(struct _starpu_sched_node *node,
-		      struct _starpu_sched_node *child,
-		      unsigned sched_ctx_id STARPU_ATTRIBUTE_UNUSED)
+static void init_ws_data(struct _starpu_sched_node *node)
 {
 {
+	struct _starpu_work_stealing_data * wsd = malloc(sizeof(*wsd));
+	memset(wsd, 0, sizeof(*wsd));
+	node->data = wsd;
 	int i;
 	int i;
 	for(i = 0; i < node->nchilds; i++){
 	for(i = 0; i < node->nchilds; i++){
 		STARPU_ASSERT(node->childs[i] != node);
 		STARPU_ASSERT(node->childs[i] != node);
 		STARPU_ASSERT(node->childs[i] != NULL);
 		STARPU_ASSERT(node->childs[i] != NULL);
 	}
 	}
-	struct _starpu_work_stealing_data * wsd = node->data;
-	int new_size = node->nchilds + 1;
-	node->childs = realloc(node->childs,
-			       sizeof(struct _starpu_sched_node*)
-			       * new_size);
-	wsd->fifos = realloc(wsd->fifos,
-			     sizeof(struct _starpu_fifo_taskq*)
-			     * new_size);
-	wsd->mutexes = realloc(wsd->mutexes,
-			     sizeof(starpu_pthread_rwlock_t)
-			     * new_size);
-	node->childs[new_size - 1] = child;
-	wsd->fifos[new_size - 1] = _starpu_create_fifo();
-	STARPU_PTHREAD_MUTEX_INIT(wsd->mutexes + (new_size - 1), NULL);
-	node->nchilds = new_size;
-}
+	int size = node->nchilds;
+	wsd->fifos = malloc(sizeof(struct _starpu_fifo_taskq*) * size);
+	wsd->mutexes = malloc(sizeof(starpu_pthread_rwlock_t) * size);
 
 
+	for(i = 0; i < size; i++)
+	{
+		wsd->fifos[i] = _starpu_create_fifo();
+		STARPU_PTHREAD_MUTEX_INIT(wsd->mutexes + i, NULL);
+	}
+}
 
 
-static void remove_child(struct _starpu_sched_node *node,
-			 struct _starpu_sched_node *child,
-			 unsigned sched_ctx_id STARPU_ATTRIBUTE_UNUSED)
+static void deinit_ws_data(struct _starpu_sched_node *node)
 {
 {
-	int pos;
-	for(pos = 0; pos < node->nchilds; pos++)
-		if(node->childs[pos] == child)
-			break;
-	STARPU_ASSERT(pos != node->nchilds);
 	struct _starpu_work_stealing_data * wsd = node->data;
 	struct _starpu_work_stealing_data * wsd = node->data;
-	struct _starpu_fifo_taskq * fifo = wsd->fifos[pos];
-	wsd->fifos[pos] = wsd->fifos[node->nchilds - 1];
-	node->childs[pos] = node->childs[node->nchilds - 1];
-	STARPU_PTHREAD_MUTEX_DESTROY(wsd->mutexes + pos);
-	wsd->mutexes[pos] = wsd->mutexes[node->nchilds - 1];
-	node->nchilds--;
 	int i;
 	int i;
-	struct starpu_task * task = fifo->taskq.head;
-	_starpu_destroy_fifo(fifo);
-	for(i = 0; task; i = (i + 1)%node->nchilds)
+	for(i = 0; i < node->nchilds; i++)
 	{
 	{
-		struct starpu_task * next = task->next;
-		STARPU_PTHREAD_MUTEX_LOCK(wsd->mutexes + i);
-		_starpu_fifo_push_sorted_task(wsd->fifos[i],task);
-		STARPU_PTHREAD_MUTEX_UNLOCK(wsd->mutexes + i);
-		task = next;
+		STARPU_PTHREAD_MUTEX_DESTROY(wsd->mutexes + i);
+		_starpu_destroy_fifo(wsd->fifos[i]);
 	}
 	}
+	free(wsd);
+	node->data = NULL;
 }
 }
 
 
 
 
-
 struct _starpu_sched_node * _starpu_sched_node_work_stealing_create(void)
 struct _starpu_sched_node * _starpu_sched_node_work_stealing_create(void)
 {
 {
 	struct _starpu_sched_node * node = _starpu_sched_node_create();
 	struct _starpu_sched_node * node = _starpu_sched_node_create();
-	struct _starpu_work_stealing_data * wsd = malloc(sizeof(*wsd));
-	memset(wsd, 0, sizeof(*wsd));
-	node->data = wsd;
 	node->pop_task = pop_task;
 	node->pop_task = pop_task;
+	node->init_data = init_ws_data;
+	node->deinit_data = deinit_ws_data;
 	node->push_task = push_task;
 	node->push_task = push_task;
-	node->add_child = add_child;
-	node->remove_child = remove_child;
 	return node;
 	return node;
 }
 }
 
 
 int _starpu_sched_node_is_work_stealing(struct _starpu_sched_node * node)
 int _starpu_sched_node_is_work_stealing(struct _starpu_sched_node * node)
 {
 {
-	return node->add_child == add_child
-		|| node->remove_child == remove_child
-		|| node->pop_task == pop_task
-		|| node->push_task == push_task;//...
+	return node->init_data == init_ws_data;
 }
 }
 
 
 
 
@@ -288,7 +247,20 @@ static void initialize_ws_center_policy(unsigned sched_ctx_id)
 	starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
 	starpu_sched_ctx_create_worker_collection(sched_ctx_id, STARPU_WORKER_LIST);
 	struct _starpu_sched_tree *data = malloc(sizeof(struct _starpu_sched_tree));
 	struct _starpu_sched_tree *data = malloc(sizeof(struct _starpu_sched_tree));
 	STARPU_PTHREAD_RWLOCK_INIT(&data->lock,NULL);
 	STARPU_PTHREAD_RWLOCK_INIT(&data->lock,NULL);
- 	data->root = _starpu_sched_node_work_stealing_create();
+	struct _starpu_sched_node * ws;
+ 	data->root = ws = _starpu_sched_node_work_stealing_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;
+		node->fathers[sched_ctx_id] = ws;
+		_starpu_sched_node_add_child(ws, node);
+	}
+	_starpu_set_workers_bitmaps();
+	_starpu_call_init_data(data);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)data);
 	starpu_sched_ctx_set_policy_data(sched_ctx_id, (void*)data);
 }
 }
 
 
@@ -300,46 +272,12 @@ static void deinitialize_ws_center_policy(unsigned sched_ctx_id)
 }
 }
 
 
 
 
-static void add_worker_ws(unsigned sched_ctx_id, int * workerids, unsigned nworkers)
-{
-	struct _starpu_sched_tree *t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	STARPU_PTHREAD_RWLOCK_WRLOCK(&t->lock);
-	unsigned i;
-	struct _starpu_sched_node * ws_node = t->root;
-	for(i = 0; i < nworkers; i++)
-	{
-		struct _starpu_sched_node * worker =_starpu_sched_node_worker_get(workerids[i]);
-		ws_node->add_child(ws_node,
-				   worker,
-				   sched_ctx_id);
-		_starpu_sched_node_set_father(worker, ws_node, sched_ctx_id);
-	}
-	_starpu_tree_update_after_modification(t);
-	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
-}
-
-static void remove_worker_ws(unsigned sched_ctx_id, int * workerids, unsigned nworkers)
-{
-	struct _starpu_sched_tree *t = starpu_sched_ctx_get_policy_data(sched_ctx_id);
-	STARPU_PTHREAD_RWLOCK_WRLOCK(&t->lock);
-	struct _starpu_sched_node * ws_node = t->root;
-	unsigned i;
-	for(i = 0; i < nworkers; i++)
-	{
-		struct _starpu_sched_node * worker =_starpu_sched_node_worker_get(workerids[i]);
-		ws_node->remove_child(ws_node, worker, sched_ctx_id);
-		_starpu_sched_node_set_father(worker,NULL,sched_ctx_id);
-	}
-	STARPU_PTHREAD_RWLOCK_UNLOCK(&t->lock);
-}
-
-
 struct starpu_sched_policy _starpu_sched_tree_ws_policy =
 struct starpu_sched_policy _starpu_sched_tree_ws_policy =
 {
 {
 	.init_sched = initialize_ws_center_policy,
 	.init_sched = initialize_ws_center_policy,
 	.deinit_sched = deinitialize_ws_center_policy,
 	.deinit_sched = deinitialize_ws_center_policy,
-	.add_workers = add_worker_ws,
-	.remove_workers = remove_worker_ws,
+	.add_workers = _starpu_tree_add_workers,
+	.remove_workers = _starpu_tree_remove_workers,
 	.push_task = _starpu_ws_push_task,
 	.push_task = _starpu_ws_push_task,
 	.pop_task = _starpu_tree_pop_task,
 	.pop_task = _starpu_tree_pop_task,
 	.pre_exec_hook = NULL,
 	.pre_exec_hook = NULL,

+ 7 - 6
src/sched_policies/node_worker.c

@@ -18,7 +18,7 @@ struct _starpu_sched_node * _starpu_sched_node_worker_get(int workerid)
 
 
 
 
 
 
-int _starpu_sched_node_worker_push_task(struct _starpu_sched_node * node, struct starpu_task *task)
+int _starpu_sched_node_worker_push_task(struct _starpu_sched_node * node, struct starpu_task *task, struct _starpu_bitmap * worker_mask STARPU_ATTRIBUTE_UNUSED)
 {
 {
 	/*this function take the worker's mutex */
 	/*this function take the worker's mutex */
 	
 	
@@ -67,7 +67,7 @@ static double estimated_transfer_length(struct _starpu_sched_node * node,
 					struct starpu_task * task)
 					struct starpu_task * task)
 {
 {
 	STARPU_ASSERT(_starpu_sched_node_is_worker(node));
 	STARPU_ASSERT(_starpu_sched_node_is_worker(node));
-	unsigned memory_node = starpu_worker_get_memory_node(node->workerids[0]);
+	unsigned memory_node = starpu_worker_get_memory_node(_starpu_bitmap_first(node->workers));
 	double d = starpu_task_expected_data_transfer_time(memory_node, task);
 	double d = starpu_task_expected_data_transfer_time(memory_node, task);
 	return d;
 	return d;
 }
 }
@@ -159,7 +159,7 @@ static double estimated_load(struct _starpu_sched_node * node)
 		nb_task++;
 		nb_task++;
 	STARPU_PTHREAD_MUTEX_UNLOCK(&worker->mutex);
 	STARPU_PTHREAD_MUTEX_UNLOCK(&worker->mutex);
 	return (double) nb_task
 	return (double) nb_task
-		/ starpu_worker_get_relative_speedup(starpu_worker_get_perf_archtype(node->workerids[0]));
+		/ starpu_worker_get_relative_speedup(_starpu_bitmap_first(node->workers));
 }
 }
 
 
 
 
@@ -172,16 +172,17 @@ static struct _starpu_sched_node  * _starpu_sched_node_worker_create(int workeri
 		return _worker_nodes[workerid];
 		return _worker_nodes[workerid];
 
 
 	struct _starpu_worker * worker = _starpu_get_worker_struct(workerid);
 	struct _starpu_worker * worker = _starpu_get_worker_struct(workerid);
+	if(worker == NULL)
+		return NULL;
 	struct _starpu_sched_node * node = _starpu_sched_node_create();
 	struct _starpu_sched_node * node = _starpu_sched_node_create();
 	node->data = worker;
 	node->data = worker;
 	node->push_task = _starpu_sched_node_worker_push_task;
 	node->push_task = _starpu_sched_node_worker_push_task;
 	node->pop_task = _starpu_sched_node_worker_pop_task;
 	node->pop_task = _starpu_sched_node_worker_pop_task;
 	node->estimated_execute_preds = estimated_execute_preds;
 	node->estimated_execute_preds = estimated_execute_preds;
 	node->estimated_load = estimated_load;
 	node->estimated_load = estimated_load;
-	node->destroy_node = _starpu_sched_node_worker_destroy;
 	node->available = available;
 	node->available = available;
-	node->workerids[0] = workerid;
-	node->nworkers = 1;
+	node->workers = _starpu_bitmap_create();
+	_starpu_bitmap_set(node->workers, workerid);
 	_worker_nodes[workerid] = node;
 	_worker_nodes[workerid] = node;
 	return node;
 	return node;
 }
 }

+ 2 - 2
src/sched_policies/prio_deque.c

@@ -127,8 +127,8 @@ static inline int pred_can_execute(struct starpu_task * t, void * pworkerid)
 
 
 struct starpu_task * _starpu_prio_deque_pop_task(struct _starpu_prio_deque * pdeque)
 struct starpu_task * _starpu_prio_deque_pop_task(struct _starpu_prio_deque * pdeque)
 {
 {
-	struct starpu_task * t = REMOVE_TASK(pdeque, head, prev, pred_true, STARPU_POISON_PTR);
-	return t;
+	struct starpu_task * task = REMOVE_TASK(pdeque, head, prev, pred_true, STARPU_POISON_PTR);
+	return task;
 }
 }
 struct starpu_task * _starpu_prio_deque_pop_task_for_worker(struct _starpu_prio_deque * pdeque, int workerid)
 struct starpu_task * _starpu_prio_deque_pop_task_for_worker(struct _starpu_prio_deque * pdeque, int workerid)
 {
 {