Andra Hugo vor 13 Jahren
Ursprung
Commit
666a9677fc

+ 1 - 1
sched_ctx_hypervisor/examples/sched_ctx_utils/sched_ctx_utils.c

@@ -222,7 +222,7 @@ void start_2ndbench(void (*bench)(float*, unsigned, unsigned))
 
 void construct_contexts(void (*bench)(float*, unsigned, unsigned))
 {
-	struct starpu_sched_ctx_hypervisor_criteria *criteria = sched_ctx_hypervisor_init(SIMPLE_POLICY);
+	struct starpu_sched_ctx_hypervisor_criteria *criteria = sched_ctx_hypervisor_init(IDLE_POLICY);
 	int nworkers1 = cpu1 + gpu + gpu1;
 	int nworkers2 = cpu2 + gpu + gpu2;
 	unsigned n_all_gpus = gpu + gpu1 + gpu2;

+ 39 - 11
sched_ctx_hypervisor/include/sched_ctx_hypervisor.h

@@ -20,6 +20,41 @@ struct sched_ctx_hypervisor_reply{
 };
 pthread_mutex_t act_hypervisor_mutex;
 
+#define MAX_IDLE_TIME 5000000000
+#define MIN_WORKING_TIME 500
+
+struct policy_config {
+	/* underneath this limit we cannot resize */
+	int min_nworkers;
+
+	/* above this limit we cannot resize */
+	int max_nworkers;
+	
+	/*resize granularity */
+	int granularity;
+
+	/* priority for a worker to stay in this context */
+	/* the smaller the priority the faster it will be moved */
+	/* to another context */
+	int priority[STARPU_NMAXWORKERS];
+
+	/* above this limit the priority of the worker is reduced */
+	double max_idle[STARPU_NMAXWORKERS];
+
+	/* underneath this limit the priority of the worker is reduced */
+	double min_working[STARPU_NMAXWORKERS];
+
+	/* workers that will not move */
+	int fixed_workers[STARPU_NMAXWORKERS];
+
+	/* max idle for the workers that will be added during the resizing process*/
+	double new_workers_max_idle;
+
+	/* above this context we allow removing all workers */
+	double empty_ctx_max_idle[STARPU_NMAXWORKERS];
+};
+
+
 struct starpu_sched_ctx_hypervisor_criteria* sched_ctx_hypervisor_init(int type);
 
 void sched_ctx_hypervisor_shutdown(void);
@@ -38,7 +73,7 @@ void sched_ctx_hypervisor_start_resize(unsigned sched_ctx);
 
 void sched_ctx_hypervisor_set_config(unsigned sched_ctx, void *config);
 
-void* sched_ctx_hypervisor_get_config(unsigned sched_ctx);
+struct policy_config* sched_ctx_hypervisor_get_config(unsigned sched_ctx);
 
 void sched_ctx_hypervisor_ioctl(unsigned sched_ctx, ...);
 
@@ -48,8 +83,6 @@ int* sched_ctx_hypervisor_get_sched_ctxs();
 
 int sched_ctx_hypervisor_get_nsched_ctxs();
 
-double sched_ctx_hypervisor_get_debit(unsigned sched_ctx);
-
 double sched_ctx_hypervisor_get_exp_end(unsigned sched_ctx);
 
 double sched_ctx_hypervisor_get_flops_left_pct(unsigned sched_ctx);
@@ -59,17 +92,12 @@ double sched_ctx_hypervisor_get_idle_time(unsigned sched_ctx, int worker);
 double sched_ctx_hypervisor_get_bef_res_exp_end(unsigned sched_ctx);
 
 /* hypervisor policies */
-#define SIMPLE_POLICY 1
+#define IDLE_POLICY 1
+#define APP_DRIVEN_POLICY 2
+#define GFLOPS_RATE_POLICY 3
 
 struct hypervisor_policy {
-	void (*init)(void);
-	void (*deinit)(void);
-	void (*add_sched_ctx)(unsigned sched_ctx);
-	void(*remove_sched_ctx)(unsigned sched_ctx);
-	void* (*ioctl)(unsigned sched_ctx, va_list varg_list, unsigned later);
 	void (*manage_idle_time)(unsigned req_sched_ctx, int worker, double idle_time);
-	void (*manage_task_flux)(unsigned sched_ctx);
 	void (*manage_gflops_rate)(unsigned sched_ctx);
 	unsigned (*resize)(unsigned sched_ctx, int *sched_ctxs, unsigned nsched_ctxs);
-	void (*update_config)(void* old_config, void* new_config);
 };

+ 1 - 0
sched_ctx_hypervisor/src/Makefile.am

@@ -27,6 +27,7 @@ libsched_ctx_hypervisor_la_LIBADD = $(top_builddir)/src/libstarpu.la
 
 libsched_ctx_hypervisor_la_SOURCES = 	\
 	sched_ctx_hypervisor.c		\
+	sched_ctx_config.c		\
 	hypervisor_policies/simple_policy.c
 
 noinst_HEADERS = sched_ctx_hypervisor_intern.h

+ 21 - 286
sched_ctx_hypervisor/src/hypervisor_policies/simple_policy.c

@@ -1,85 +1,9 @@
 #include <sched_ctx_hypervisor.h>
 #include <pthread.h>
 
-#define MAX_IDLE_TIME 5000000000
-#define MIN_WORKING_TIME 500
-
-struct simple_policy_config {
-	/* underneath this limit we cannot resize */
-	int min_nworkers;
-
-	/* above this limit we cannot resize */
-	int max_nworkers;
-	
-	/*resize granularity */
-	int granularity;
-
-	/* priority for a worker to stay in this context */
-	/* the smaller the priority the faster it will be moved */
-	/* to another context */
-	int priority[STARPU_NMAXWORKERS];
-
-	/* above this limit the priority of the worker is reduced */
-	double max_idle[STARPU_NMAXWORKERS];
-
-	/* underneath this limit the priority of the worker is reduced */
-	double min_working[STARPU_NMAXWORKERS];
-
-	/* workers that will not move */
-	int fixed_workers[STARPU_NMAXWORKERS];
-
-	/* max idle for the workers that will be added during the resizing process*/
-	double new_workers_max_idle;
-
-	/* above this context we allow removing all workers */
-	double empty_ctx_max_idle[STARPU_NMAXWORKERS];
-};
-
-static struct simple_policy_config* _create_config(void)
-{
-	struct simple_policy_config *config = (struct simple_policy_config *)malloc(sizeof(struct simple_policy_config));
-	config->min_nworkers = -1;
-	config->max_nworkers = -1;	
-	config->new_workers_max_idle = -1.0;
-
-	int i;
-	for(i = 0; i < STARPU_NMAXWORKERS; i++)
-	{
-		config->granularity = -1;
-		config->priority[i] = -1;
-		config->fixed_workers[i] = -1;
-		config->max_idle[i] = -1.0;
-		config->empty_ctx_max_idle[i] = -1.0;
-		config->min_working[i] = -1.0;
-	}
-	
-	return config;
-}
-
-static void simple_add_sched_ctx(unsigned sched_ctx)
-{
-	struct simple_policy_config *config = _create_config();
-	config->min_nworkers = 0;
-	config->max_nworkers = 0;	
-	config->new_workers_max_idle = MAX_IDLE_TIME;
-
-	int i;
-	for(i = 0; i < STARPU_NMAXWORKERS; i++)
-	{
-		config->granularity = 1;
-		config->priority[i] = 0;
-		config->fixed_workers[i] = 0;
-		config->max_idle[i] = MAX_IDLE_TIME;
-		config->empty_ctx_max_idle[i] = MAX_IDLE_TIME;
-		config->min_working[i] = MIN_WORKING_TIME;
-	}
-
-	sched_ctx_hypervisor_set_config(sched_ctx, config);
-}
-
 static int _compute_priority(unsigned sched_ctx)
 {
-	struct simple_policy_config *config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(sched_ctx);
+	struct policy_config *config = sched_ctx_hypervisor_get_config(sched_ctx);
 
 	int total_priority = 0;
 
@@ -110,14 +34,14 @@ static unsigned _find_poor_sched_ctx(unsigned req_sched_ctx, int nworkers_to_mov
 	int nsched_ctxs = sched_ctx_hypervisor_get_nsched_ctxs();
 
 
-	struct simple_policy_config *config = NULL;
+	struct policy_config *config = NULL;
 
 	for(i = 0; i < nsched_ctxs; i++)
 	{
 		if(sched_ctxs[i] != STARPU_NMAX_SCHED_CTXS && sched_ctxs[i] != req_sched_ctx)
 		{
 			unsigned nworkers = starpu_get_nworkers_of_sched_ctx(sched_ctxs[i]);
-			config  = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(sched_ctxs[i]);
+			config  = sched_ctx_hypervisor_get_config(sched_ctxs[i]);
 			if((nworkers + nworkers_to_move) <= config->max_nworkers)
 			{
 				current_priority = _compute_priority(sched_ctxs[i]);
@@ -135,7 +59,7 @@ static unsigned _find_poor_sched_ctx(unsigned req_sched_ctx, int nworkers_to_mov
 
 int* _get_first_workers(unsigned sched_ctx, unsigned *nworkers)
 {
-	struct simple_policy_config *config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(sched_ctx);
+	struct policy_config *config = sched_ctx_hypervisor_get_config(sched_ctx);
 
 	int *curr_workers = (int*)malloc((*nworkers) * sizeof(int));
 	int i;
@@ -203,7 +127,7 @@ int* _get_first_workers(unsigned sched_ctx, unsigned *nworkers)
 	return curr_workers;
 }
 
-static unsigned _get_potential_nworkers(struct simple_policy_config *config, unsigned sched_ctx)
+static unsigned _get_potential_nworkers(struct policy_config *config, unsigned sched_ctx)
 {
 	struct worker_collection *workers = starpu_get_worker_collection_of_sched_ctx(sched_ctx);
 
@@ -226,7 +150,7 @@ static unsigned _get_potential_nworkers(struct simple_policy_config *config, uns
 
 static unsigned _get_nworkers_to_move(unsigned req_sched_ctx)
 {
-       	struct simple_policy_config *config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(req_sched_ctx);
+       	struct policy_config *config = sched_ctx_hypervisor_get_config(req_sched_ctx);
 	unsigned nworkers = starpu_get_nworkers_of_sched_ctx(req_sched_ctx);
 	unsigned nworkers_to_move = 0;
 	
@@ -268,48 +192,6 @@ static unsigned _get_nworkers_to_move(unsigned req_sched_ctx)
 	return nworkers_to_move;
 }
 
-static int _find_highest_debit_sched_ctx()
-{
-	int *sched_ctxs = sched_ctx_hypervisor_get_sched_ctxs();
-	int nsched_ctxs = sched_ctx_hypervisor_get_nsched_ctxs();
-
-	int fastest_sched_ctx = -1;
-	double fastest_debit = -1.0, curr_debit = 0.0;
-	int i;
-	for(i = 0; i < nsched_ctxs; i++)
-	{
-		curr_debit = sched_ctx_hypervisor_get_debit(sched_ctxs[i]);
-		if(fastest_debit < curr_debit)
-		{
-			fastest_debit = curr_debit;
-			fastest_sched_ctx = sched_ctxs[i];
-		}
-	}
-
-	return fastest_sched_ctx;
-}
-
-static int _find_slowest_debit_sched_ctx()
-{
-	int *sched_ctxs = sched_ctx_hypervisor_get_sched_ctxs();
-	int nsched_ctxs = sched_ctx_hypervisor_get_nsched_ctxs();
-
-	int slowest_sched_ctx = -1;
-	double slowest_debit = 1.0, curr_debit = 0.0;
-	int i;
-	for(i = 0; i < nsched_ctxs; i++)
-	{
-		curr_debit = sched_ctx_hypervisor_get_debit(sched_ctxs[i]);
-		if(slowest_debit > curr_debit)
-		{
-			slowest_debit = curr_debit;
-			slowest_sched_ctx = sched_ctxs[i];
-		}
-	}
-
-	return slowest_sched_ctx;
-}
-
 static unsigned _simple_resize(unsigned sender_sched_ctx, unsigned receiver_sched_ctx)
 {
 	int ret = pthread_mutex_trylock(&act_hypervisor_mutex);
@@ -325,7 +207,7 @@ static unsigned _simple_resize(unsigned sender_sched_ctx, unsigned receiver_sche
 			else
 			{
 				poor_sched_ctx = receiver_sched_ctx;
-				struct simple_policy_config *config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(poor_sched_ctx);
+				struct policy_config *config = sched_ctx_hypervisor_get_config(poor_sched_ctx);
 				unsigned nworkers = starpu_get_nworkers_of_sched_ctx(poor_sched_ctx);
 				if((nworkers+nworkers_to_move) > config->max_nworkers)
 					nworkers_to_move = nworkers > config->max_nworkers ? 0 : (config->max_nworkers - nworkers);
@@ -338,7 +220,7 @@ static unsigned _simple_resize(unsigned sender_sched_ctx, unsigned receiver_sche
 				int *workers_to_move = _get_first_workers(sender_sched_ctx, &nworkers_to_move);
 				sched_ctx_hypervisor_move_workers(sender_sched_ctx, poor_sched_ctx, workers_to_move, nworkers_to_move);
 				
-				struct simple_policy_config *new_config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(poor_sched_ctx);
+				struct policy_config *new_config = sched_ctx_hypervisor_get_config(poor_sched_ctx);
 				int i;
 				for(i = 0; i < nworkers_to_move; i++)
 					new_config->max_idle[workers_to_move[i]] = new_config->max_idle[workers_to_move[i]] !=MAX_IDLE_TIME ? new_config->max_idle[workers_to_move[i]] :  new_config->new_workers_max_idle;
@@ -360,40 +242,13 @@ static unsigned simple_resize(unsigned sender_sched_ctx)
 
 static void simple_manage_idle_time(unsigned req_sched_ctx, int worker, double idle_time)
 {
-       	struct simple_policy_config *config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(req_sched_ctx);
+       	struct policy_config *config = sched_ctx_hypervisor_get_config(req_sched_ctx);
 
 	if(config != NULL && idle_time > config->max_idle[worker])
 		simple_resize(req_sched_ctx);
 	return;
 }
 
-static void simple_manage_task_flux(unsigned curr_sched_ctx)
-{
-	double curr_debit = sched_ctx_hypervisor_get_debit(curr_sched_ctx);
-	
-	int slow_sched_ctx = _find_slowest_debit_sched_ctx();
-	int fast_sched_ctx = _find_highest_debit_sched_ctx();
-
-	if(slow_sched_ctx != fast_sched_ctx && slow_sched_ctx != -1 && fast_sched_ctx != -1)
-	{
-		if(curr_sched_ctx == slow_sched_ctx)
-		{
-			double debit_fast = sched_ctx_hypervisor_get_debit(fast_sched_ctx);
-			/* only if there is a difference of 30 % */
-			if(debit_fast != 0.0 && (debit_fast + debit_fast *0.2) > curr_debit)
-				_simple_resize(fast_sched_ctx, curr_sched_ctx);
-		}
-		
-		if(curr_sched_ctx == fast_sched_ctx)
-		{
-			double debit_slow = sched_ctx_hypervisor_get_debit(slow_sched_ctx);
-			/* only if there is a difference of 30 % */
-			if(curr_debit != 0.0 && (debit_slow + debit_slow *0.2) < curr_debit)
-				_simple_resize(curr_sched_ctx, slow_sched_ctx);
-		}
-	}
-}
-
 int _find_fastest_sched_ctx()
 {
 	int *sched_ctxs = sched_ctx_hypervisor_get_sched_ctxs();
@@ -457,7 +312,7 @@ static void simple_manage_gflops_rate(unsigned sched_ctx)
 			printf("ctx %d finished & gives away the res to %d; slow_left %lf\n", sched_ctx, slowest_sched_ctx, slowest_flops_left_pct);
 			if(slowest_flops_left_pct != 0.0f)
 			{
-				struct simple_policy_config* config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(sched_ctx);
+				struct policy_config* config = sched_ctx_hypervisor_get_config(sched_ctx);
 				config->min_nworkers = 0;
 				config->max_nworkers = 0;
 				_simple_resize(sched_ctx, slowest_sched_ctx);
@@ -485,141 +340,21 @@ static void simple_manage_gflops_rate(unsigned sched_ctx)
 	}
 }
 
-static void* simple_ioctl(unsigned sched_ctx, va_list varg_list, unsigned later)
-{
-	struct simple_policy_config *config = NULL;
-
-	if(later)
-		config = _create_config();
-	else
-		config = (struct simple_policy_config*)sched_ctx_hypervisor_get_config(sched_ctx);
-
-	assert(config != NULL);
-
-	int arg_type;
-	int i;
-	int *workerids;
-	int nworkers;
-
-	while ((arg_type = va_arg(varg_list, int)) != 0) 
-	{
-		switch(arg_type)
-		{
-		case HYPERVISOR_MAX_IDLE:
-			workerids = va_arg(varg_list, int*);
-			nworkers = va_arg(varg_list, int);
-			double max_idle = va_arg(varg_list, double);
-			for(i = 0; i < nworkers; i++)
-				config->max_idle[workerids[i]] = max_idle;
-
-			break;
-
-		case HYPERVISOR_EMPTY_CTX_MAX_IDLE:
-			workerids = va_arg(varg_list, int*);
-			nworkers = va_arg(varg_list, int);
-			double empty_ctx_max_idle = va_arg(varg_list, double);
-			
-			for(i = 0; i < nworkers; i++)
-				config->empty_ctx_max_idle[workerids[i]] = empty_ctx_max_idle;
-
-			break;
-
-		case HYPERVISOR_MIN_WORKING:
-			workerids = va_arg(varg_list, int*);
-			nworkers = va_arg(varg_list, int);
-			double min_working = va_arg(varg_list, double);
-
-			for(i = 0; i < nworkers; i++)
-				config->min_working[workerids[i]] = min_working;
-
-			break;
-
-		case HYPERVISOR_PRIORITY:
-			workerids = va_arg(varg_list, int*);
-			nworkers = va_arg(varg_list, int);
-			int priority = va_arg(varg_list, int);
-	
-			for(i = 0; i < nworkers; i++)
-				config->priority[workerids[i]] = priority;
-			break;
-
-		case HYPERVISOR_MIN_WORKERS:
-			config->min_nworkers = va_arg(varg_list, unsigned);
-			break;
-
-		case HYPERVISOR_MAX_WORKERS:
-			config->max_nworkers = va_arg(varg_list, unsigned);
-			break;
-
-		case HYPERVISOR_GRANULARITY:
-			config->granularity = va_arg(varg_list, unsigned);
-			break;
-
-		case HYPERVISOR_FIXED_WORKERS:
-			workerids = va_arg(varg_list, int*);
-			nworkers = va_arg(varg_list, int);
-
-			for(i = 0; i < nworkers; i++)
-				config->fixed_workers[workerids[i]] = 1;
-			break;
-
-		case HYPERVISOR_NEW_WORKERS_MAX_IDLE:
-			config->new_workers_max_idle = va_arg(varg_list, double);
-			break;
-
-/* not important for the strateg, needed just to jump these args in the iteration of the args */			
-		case HYPERVISOR_TIME_TO_APPLY:
-			va_arg(varg_list, int);
-			break;
-
-		case HYPERVISOR_MIN_TASKS:
-			va_arg(varg_list, int);
-			break;
-
-		}
-	}
-
-	va_end(varg_list);
-
-	return later ? (void*)config : NULL;
-}
-
-static void simple_update_config(void *old_config, void* config)
-{
-	struct simple_policy_config *old = (struct simple_policy_config*)old_config;
-	struct simple_policy_config *new = (struct simple_policy_config*)config;
-
-	printf("new = %d old = %d\n", new->max_nworkers, old->max_nworkers);
-	old->min_nworkers = new->min_nworkers != -1 ? new->min_nworkers : old->min_nworkers ;
-	old->max_nworkers = new->max_nworkers != -1 ? new->max_nworkers : old->max_nworkers ;
-	old->new_workers_max_idle = new->new_workers_max_idle != -1.0 ? new->new_workers_max_idle : old->new_workers_max_idle;
-	old->granularity = new->granularity != -1 ? new->granularity : old->granularity;
 
-	int i;
-	for(i = 0; i < STARPU_NMAXWORKERS; i++)
-	{
-		old->priority[i] = new->priority[i] != -1 ? new->priority[i] : old->priority[i];
-		old->fixed_workers[i] = new->fixed_workers[i] != -1 ? new->fixed_workers[i] : old->fixed_workers[i];
-		old->max_idle[i] = new->max_idle[i] != -1.0 ? new->max_idle[i] : old->max_idle[i];
-		old->empty_ctx_max_idle[i] = new->empty_ctx_max_idle[i] != -1.0 ? new->empty_ctx_max_idle[i] : old->empty_ctx_max_idle[i];
-		old->min_working[i] = new->min_working[i] != -1.0 ? new->min_working[i] : old->min_working[i];
-	}
-}
+struct hypervisor_policy idle_policy = {
+	.manage_idle_time = simple_manage_idle_time,
+	.manage_gflops_rate = simple_manage_gflops_rate,
+	.resize = simple_resize,
+};
 
-static void simple_remove_sched_ctx(unsigned sched_ctx)
-{
-	sched_ctx_hypervisor_set_config(sched_ctx, NULL);
-}
+struct hypervisor_policy app_driven_policy = {
+	.manage_idle_time = simple_manage_idle_time,
+	.manage_gflops_rate = simple_manage_gflops_rate,
+	.resize = simple_resize,
+};
 
-struct hypervisor_policy simple_policy = {
-	.init = NULL,
-	.deinit = NULL,
-	.add_sched_ctx = simple_add_sched_ctx,
-	.remove_sched_ctx = simple_remove_sched_ctx,
-	.ioctl = simple_ioctl,
+struct hypervisor_policy gflops_rate_policy = {
 	.manage_idle_time = simple_manage_idle_time,
-	.manage_task_flux = simple_manage_task_flux,
 	.manage_gflops_rate = simple_manage_gflops_rate,
 	.resize = simple_resize,
-	.update_config = simple_update_config
 };

+ 222 - 0
sched_ctx_hypervisor/src/sched_ctx_config.c

@@ -0,0 +1,222 @@
+#include <sched_ctx_hypervisor_intern.h>
+
+static struct policy_config* _create_config(void)
+{
+	struct policy_config *config = (struct policy_config *)malloc(sizeof(struct policy_config));
+	config->min_nworkers = -1;
+	config->max_nworkers = -1;	
+	config->new_workers_max_idle = -1.0;
+
+	int i;
+	for(i = 0; i < STARPU_NMAXWORKERS; i++)
+	{
+		config->granularity = -1;
+		config->priority[i] = -1;
+		config->fixed_workers[i] = -1;
+		config->max_idle[i] = -1.0;
+		config->empty_ctx_max_idle[i] = -1.0;
+		config->min_working[i] = -1.0;
+	}
+	
+	return config;
+}
+
+static void _update_config(struct policy_config *old, struct policy_config* new)
+{
+	printf("new = %d old = %d\n", new->max_nworkers, old->max_nworkers);
+	old->min_nworkers = new->min_nworkers != -1 ? new->min_nworkers : old->min_nworkers ;
+	old->max_nworkers = new->max_nworkers != -1 ? new->max_nworkers : old->max_nworkers ;
+	old->new_workers_max_idle = new->new_workers_max_idle != -1.0 ? new->new_workers_max_idle : old->new_workers_max_idle;
+	old->granularity = new->granularity != -1 ? new->granularity : old->granularity;
+
+	int i;
+	for(i = 0; i < STARPU_NMAXWORKERS; i++)
+	{
+		old->priority[i] = new->priority[i] != -1 ? new->priority[i] : old->priority[i];
+		old->fixed_workers[i] = new->fixed_workers[i] != -1 ? new->fixed_workers[i] : old->fixed_workers[i];
+		old->max_idle[i] = new->max_idle[i] != -1.0 ? new->max_idle[i] : old->max_idle[i];
+		old->empty_ctx_max_idle[i] = new->empty_ctx_max_idle[i] != -1.0 ? new->empty_ctx_max_idle[i] : old->empty_ctx_max_idle[i];
+		old->min_working[i] = new->min_working[i] != -1.0 ? new->min_working[i] : old->min_working[i];
+	}
+}
+
+void sched_ctx_hypervisor_set_config(unsigned sched_ctx, void *config)
+{
+	printf("%d: ", sched_ctx );
+	if(hypervisor.sched_ctx_w[sched_ctx].config != NULL && config != NULL)
+	{
+		_update_config(hypervisor.sched_ctx_w[sched_ctx].config, config);
+	}
+	else
+		hypervisor.sched_ctx_w[sched_ctx].config = config;
+	
+	return;
+}
+
+void add_config(unsigned sched_ctx)
+{
+	struct policy_config *config = _create_config();
+	config->min_nworkers = 0;
+	config->max_nworkers = 0;	
+	config->new_workers_max_idle = MAX_IDLE_TIME;
+
+	int i;
+	for(i = 0; i < STARPU_NMAXWORKERS; i++)
+	{
+		config->granularity = 1;
+		config->priority[i] = 0;
+		config->fixed_workers[i] = 0;
+		config->max_idle[i] = MAX_IDLE_TIME;
+		config->empty_ctx_max_idle[i] = MAX_IDLE_TIME;
+		config->min_working[i] = MIN_WORKING_TIME;
+	}
+
+	sched_ctx_hypervisor_set_config(sched_ctx, config);
+}
+
+void remove_config(unsigned sched_ctx)
+{
+	sched_ctx_hypervisor_set_config(sched_ctx, NULL);
+}
+
+struct policy_config* sched_ctx_hypervisor_get_config(unsigned sched_ctx)
+{
+	return hypervisor.sched_ctx_w[sched_ctx].config;
+}
+
+static struct policy_config* _ioctl(unsigned sched_ctx, va_list varg_list, unsigned later)
+{
+	struct policy_config *config = NULL;
+
+	if(later)
+		config = _create_config();
+	else
+		config = sched_ctx_hypervisor_get_config(sched_ctx);
+
+	assert(config != NULL);
+
+	int arg_type;
+	int i;
+	int *workerids;
+	int nworkers;
+
+	while ((arg_type = va_arg(varg_list, int)) != 0) 
+	{
+		switch(arg_type)
+		{
+		case HYPERVISOR_MAX_IDLE:
+			workerids = va_arg(varg_list, int*);
+			nworkers = va_arg(varg_list, int);
+			double max_idle = va_arg(varg_list, double);
+			for(i = 0; i < nworkers; i++)
+				config->max_idle[workerids[i]] = max_idle;
+
+			break;
+
+		case HYPERVISOR_EMPTY_CTX_MAX_IDLE:
+			workerids = va_arg(varg_list, int*);
+			nworkers = va_arg(varg_list, int);
+			double empty_ctx_max_idle = va_arg(varg_list, double);
+			
+			for(i = 0; i < nworkers; i++)
+				config->empty_ctx_max_idle[workerids[i]] = empty_ctx_max_idle;
+
+			break;
+
+		case HYPERVISOR_MIN_WORKING:
+			workerids = va_arg(varg_list, int*);
+			nworkers = va_arg(varg_list, int);
+			double min_working = va_arg(varg_list, double);
+
+			for(i = 0; i < nworkers; i++)
+				config->min_working[workerids[i]] = min_working;
+
+			break;
+
+		case HYPERVISOR_PRIORITY:
+			workerids = va_arg(varg_list, int*);
+			nworkers = va_arg(varg_list, int);
+			int priority = va_arg(varg_list, int);
+	
+			for(i = 0; i < nworkers; i++)
+				config->priority[workerids[i]] = priority;
+			break;
+
+		case HYPERVISOR_MIN_WORKERS:
+			config->min_nworkers = va_arg(varg_list, unsigned);
+			break;
+
+		case HYPERVISOR_MAX_WORKERS:
+			config->max_nworkers = va_arg(varg_list, unsigned);
+			break;
+
+		case HYPERVISOR_GRANULARITY:
+			config->granularity = va_arg(varg_list, unsigned);
+			break;
+
+		case HYPERVISOR_FIXED_WORKERS:
+			workerids = va_arg(varg_list, int*);
+			nworkers = va_arg(varg_list, int);
+
+			for(i = 0; i < nworkers; i++)
+				config->fixed_workers[workerids[i]] = 1;
+			break;
+
+		case HYPERVISOR_NEW_WORKERS_MAX_IDLE:
+			config->new_workers_max_idle = va_arg(varg_list, double);
+			break;
+
+/* not important for the strateg, needed just to jump these args in the iteration of the args */			
+		case HYPERVISOR_TIME_TO_APPLY:
+			va_arg(varg_list, int);
+			break;
+
+		case HYPERVISOR_MIN_TASKS:
+			va_arg(varg_list, int);
+			break;
+
+		}
+	}
+
+	va_end(varg_list);
+
+	return later ? config : NULL;
+}
+
+
+void sched_ctx_hypervisor_ioctl(unsigned sched_ctx, ...)
+{
+	va_list varg_list;
+	va_start(varg_list, sched_ctx);
+
+	int arg_type;
+	int stop = 0;
+	int task_tag = -1;
+
+	while ((arg_type = va_arg(varg_list, int)) != 0) 
+	{
+		switch(arg_type)
+		{
+		case HYPERVISOR_TIME_TO_APPLY:
+			task_tag = va_arg(varg_list, int);
+			stop = 1;
+			break;
+
+		case HYPERVISOR_MIN_TASKS:
+			hypervisor.min_tasks = va_arg(varg_list, int);
+			break;
+
+		}
+		if(stop) break;
+	}
+
+	va_end(varg_list);
+	va_start(varg_list, sched_ctx);
+
+	/* if config not null => save hypervisor configuration and consider it later */
+	struct policy_config *config = _ioctl(sched_ctx, varg_list, (task_tag > 0));
+	if(config != NULL)
+		_starpu_htbl_insert_32(&hypervisor.configurations[sched_ctx], (uint32_t)task_tag, config);
+
+	return;
+}

+ 21 - 95
sched_ctx_hypervisor/src/sched_ctx_hypervisor.c

@@ -3,7 +3,9 @@
 unsigned imposed_resize = 0;
 struct starpu_sched_ctx_hypervisor_criteria* criteria = NULL;
 
-extern struct hypervisor_policy simple_policy;
+extern struct hypervisor_policy idle_policy;
+extern struct hypervisor_policy app_driven_policy;
+extern struct hypervisor_policy gflops_rate_policy;
 
 static void idle_time_cb(unsigned sched_ctx, int worker, double idle_time);
 static void pushed_task_cb(unsigned sched_ctx, int worker);
@@ -12,23 +14,28 @@ static void post_exec_hook_cb(unsigned sched_ctx, int taskid);
 static void reset_idle_time_cb(unsigned sched_ctx, int  worker);
 
 static void _set_elapsed_flops_per_sched_ctx(unsigned sched_ctx, double val);
+
 static void _load_hypervisor_policy(int type)
 {
+	struct hypervisor_policy *policy = NULL;
+
 	switch(type)
 	{
-	case SIMPLE_POLICY:
-		hypervisor.policy.init = simple_policy.init;
-		hypervisor.policy.deinit = simple_policy.deinit;
-		hypervisor.policy.add_sched_ctx = simple_policy.add_sched_ctx;
-		hypervisor.policy.remove_sched_ctx = simple_policy.remove_sched_ctx;
-		hypervisor.policy.ioctl = simple_policy.ioctl;
-		hypervisor.policy.manage_idle_time = simple_policy.manage_idle_time;
-		hypervisor.policy.update_config = simple_policy.update_config;
-		hypervisor.policy.resize = simple_policy.resize;
-		hypervisor.policy.manage_task_flux = simple_policy.manage_task_flux;
-		hypervisor.policy.manage_gflops_rate = simple_policy.manage_gflops_rate;
+	case IDLE_POLICY:
+		policy = &idle_policy;
+		break;
+	case APP_DRIVEN_POLICY:
+		policy = &app_driven_policy;
 		break;
+	case GFLOPS_RATE_POLICY:
+		policy = &gflops_rate_policy;
+		break;
+
 	}
+
+	hypervisor.policy.manage_idle_time = policy->manage_idle_time;
+	hypervisor.policy.resize = policy->resize;
+	hypervisor.policy.manage_gflops_rate = policy->manage_gflops_rate;
 }
 
 struct starpu_sched_ctx_hypervisor_criteria** sched_ctx_hypervisor_init(int type)
@@ -119,7 +126,7 @@ void sched_ctx_hypervisor_handle_ctx(unsigned sched_ctx, double total_flops)
 	hypervisor.steal_requests[sched_ctx] = (struct starpu_htbl32_node_s*)malloc(sizeof(struct starpu_htbl32_node_s));
 	hypervisor.resize_requests[sched_ctx] = (struct starpu_htbl32_node_s*)malloc(sizeof(struct starpu_htbl32_node_s));
 
-	hypervisor.policy.add_sched_ctx(sched_ctx);
+	add_config(sched_ctx);
 	hypervisor.sched_ctx_w[sched_ctx].sched_ctx = sched_ctx;
 	hypervisor.sched_ctxs[hypervisor.nsched_ctxs++] = sched_ctx;
 
@@ -174,68 +181,13 @@ void sched_ctx_hypervisor_ignore_ctx(unsigned sched_ctx)
         _rearange_sched_ctxs(hypervisor.sched_ctxs, hypervisor.nsched_ctxs);
 	hypervisor.nsched_ctxs--;
 	hypervisor.sched_ctx_w[sched_ctx].sched_ctx = STARPU_NMAX_SCHED_CTXS;
-	hypervisor.policy.remove_sched_ctx(sched_ctx);
+	remove_config(sched_ctx);
 
 	free(hypervisor.configurations[sched_ctx]);
 	free(hypervisor.steal_requests[sched_ctx]);
 	free(hypervisor.resize_requests[sched_ctx]);
 }
 
-void sched_ctx_hypervisor_set_config(unsigned sched_ctx, void *config)
-{
-	printf("%d: ", sched_ctx );
-	if(hypervisor.sched_ctx_w[sched_ctx].config != NULL && config != NULL)
-	{
-		hypervisor.policy.update_config(hypervisor.sched_ctx_w[sched_ctx].config, config);
-	}
-	else
-		hypervisor.sched_ctx_w[sched_ctx].config = config;
-	
-	return;
-}
-
-void* sched_ctx_hypervisor_get_config(unsigned sched_ctx)
-{
-	return hypervisor.sched_ctx_w[sched_ctx].config;
-}
-
-void sched_ctx_hypervisor_ioctl(unsigned sched_ctx, ...)
-{
-	va_list varg_list;
-	va_start(varg_list, sched_ctx);
-
-	int arg_type;
-	int stop = 0;
-	int task_tag = -1;
-
-	while ((arg_type = va_arg(varg_list, int)) != 0) 
-	{
-		switch(arg_type)
-		{
-		case HYPERVISOR_TIME_TO_APPLY:
-			task_tag = va_arg(varg_list, int);
-			stop = 1;
-			break;
-
-		case HYPERVISOR_MIN_TASKS:
-			hypervisor.min_tasks = va_arg(varg_list, int);
-			break;
-
-		}
-		if(stop) break;
-	}
-
-	va_end(varg_list);
-	va_start(varg_list, sched_ctx);
-
-	/* if config not null => save hypervisor configuration and consider it later */
-	void *config = hypervisor.policy.ioctl(sched_ctx, varg_list, (task_tag > 0));
-	if(config != NULL)
-		_starpu_htbl_insert_32(&hypervisor.configurations[sched_ctx], (uint32_t)task_tag, config);
-
-	return;
-}
-
 static int get_ntasks( int *tasks)
 {
 	int ntasks = 0;
@@ -257,13 +209,6 @@ static void reset_ntasks( int *tasks)
 	return;
 }
 
-static unsigned check_tasks_of_sched_ctx(unsigned sched_ctx)
-{
-	int ntasks = get_ntasks(hypervisor.sched_ctx_w[sched_ctx].pushed_tasks);
-	
-	return ntasks > hypervisor.min_tasks;
-}
-
 void sched_ctx_hypervisor_move_workers(unsigned sender_sched_ctx, unsigned receiver_sched_ctx, int* workers_to_move, unsigned nworkers_to_move)
 {
 	if(hypervisor.resize[sender_sched_ctx])
@@ -454,24 +399,6 @@ int sched_ctx_hypervisor_get_nsched_ctxs()
 	return hypervisor.nsched_ctxs;
 }
 
-double sched_ctx_hypervisor_get_debit(unsigned sched_ctx)
-{
-	unsigned nworkers = starpu_get_nworkers_of_sched_ctx(sched_ctx);
-	if(nworkers == 0)
-		return 0.0;
-
-	int npushed_tasks = get_ntasks(hypervisor.sched_ctx_w[sched_ctx].pushed_tasks);
-	int npoped_tasks = get_ntasks(hypervisor.sched_ctx_w[sched_ctx].poped_tasks);
-	STARPU_ASSERT(npoped_tasks <= npushed_tasks);
-	if(npushed_tasks > 0 && npoped_tasks > 0)
-	{
-		double debit = (((double)npoped_tasks)*1.0)/((double)npushed_tasks * 1.0);
-		return debit;
-	}
-	
-	return 0.0;
-}
-
 static double _get_total_elapsed_flops_per_sched_ctx(unsigned sched_ctx)
 {
 	double ret_val = 0.0;
@@ -550,7 +477,6 @@ static void poped_task_cb(unsigned sched_ctx, int worker, double elapsed_flops)
 			_check_for_resize_ack(sched_ctx, sc_w->resize_ack.receiver_sched_ctx, 
 					      sc_w->resize_ack.moved_workers, sc_w->resize_ack.nmoved_workers);
 		}
-
 	}
 }
 

+ 6 - 1
sched_ctx_hypervisor/src/sched_ctx_hypervisor_intern.h

@@ -9,7 +9,7 @@ struct resize_ack{
 
 struct sched_ctx_wrapper {
 	unsigned sched_ctx;
-	void *config;
+	struct policy_config *config;
 	double current_idle_time[STARPU_NMAXWORKERS];
 	int pushed_tasks[STARPU_NMAXWORKERS];
 	int poped_tasks[STARPU_NMAXWORKERS];
@@ -42,3 +42,8 @@ struct sched_ctx_hypervisor_adjustment {
 };
 
 struct sched_ctx_hypervisor hypervisor;
+
+
+void add_config(unsigned sched_ctx);
+
+void remove_config(unsigned sched_ctx);