Forráskód Böngészése

size the context for the user

Andra Hugo 13 éve
szülő
commit
669304da11

+ 9 - 0
sched_ctx_hypervisor/include/sched_ctx_hypervisor.h

@@ -93,6 +93,7 @@ struct sched_ctx_wrapper {
 struct hypervisor_policy {
 	const char* name;
 	unsigned custom;
+	void (*size_ctxs)(int *sched_ctxs, int nsched_ctxs , int *workers, int nworkers);
 	void (*handle_idle_cycle)(unsigned sched_ctx, int worker);
 	void (*handle_pushed_task)(unsigned sched_ctx, int worker);
 	void (*handle_poped_task)(unsigned sched_ctx, int worker);
@@ -139,3 +140,11 @@ char* sched_ctx_hypervisor_get_policy();
 void sched_ctx_hypervisor_add_workers_to_sched_ctx(int* workers_to_add, unsigned nworkers_to_add, unsigned sched_ctx);
 
 void sched_ctx_hypervisor_remove_workers_from_sched_ctx(int* workers_to_remove, unsigned nworkers_to_remove, unsigned sched_ctx);
+
+void sched_ctx_hypervisor_size_ctxs(int *sched_ctxs, int nsched_ctxs, int *workers, int nworkers);
+
+unsigned sched_ctx_hypervisor_get_size_req(int **sched_ctxs, int* nsched_ctxs, int **workers, int *nworkers);	
+
+void sched_ctx_hypervisor_save_size_req(int *sched_ctxs, int nsched_ctxs, int *workers, int nworkers);	
+
+void sched_ctx_hypervisor_free_size_req(void);

+ 1 - 0
sched_ctx_hypervisor/src/hypervisor_policies/app_driven_policy.c

@@ -28,6 +28,7 @@ void app_driven_handle_post_exec_hook(unsigned sched_ctx, struct starpu_htbl32_n
 }
 
 struct hypervisor_policy app_driven_policy = {
+	.size_ctxs = NULL,
 	.handle_poped_task = NULL,
 	.handle_pushed_task = NULL,
 	.handle_idle_cycle = NULL,

+ 1 - 0
sched_ctx_hypervisor/src/hypervisor_policies/gflops_rate_policy.c

@@ -295,6 +295,7 @@ void gflops_rate_handle_poped_task(unsigned sched_ctx, int worker)
 }
 
 struct hypervisor_policy gflops_rate_policy = {
+	.size_ctxs = NULL,
 	.handle_poped_task = gflops_rate_handle_poped_task,
 	.handle_pushed_task = NULL,
 	.handle_idle_cycle = NULL,

+ 1 - 0
sched_ctx_hypervisor/src/hypervisor_policies/idle_policy.c

@@ -25,6 +25,7 @@ void idle_handle_idle_cycle(unsigned sched_ctx, int worker)
 }
 
 struct hypervisor_policy idle_policy = {
+	.size_ctxs = NULL,
 	.handle_poped_task = NULL,
 	.handle_pushed_task = NULL,
 	.handle_idle_cycle = idle_handle_idle_cycle,

+ 1 - 0
sched_ctx_hypervisor/src/hypervisor_policies/lp2_policy.c

@@ -479,6 +479,7 @@ void lp2_handle_poped_task(unsigned sched_ctx, int worker)
 }
 
 struct hypervisor_policy lp2_policy = {
+	.size_ctxs = NULL,
 	.handle_poped_task = lp2_handle_poped_task,
 	.handle_pushed_task = NULL,
 	.handle_idle_cycle = NULL,

+ 154 - 87
sched_ctx_hypervisor/src/hypervisor_policies/lp3_policy.c

@@ -21,6 +21,49 @@ static struct bound_task_pool *task_pools = NULL;
 
 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
 
+static void _size_ctxs(int *sched_ctxs, int nsched_ctxs , int *workers, int nworkers)
+{
+	printf("~~~~~~~~~~~~~~~~~~~~~~~~size\n");
+	int ns = sched_ctxs == NULL ? sched_ctx_hypervisor_get_nsched_ctxs() : nsched_ctxs;
+	int nw = workers == NULL ? starpu_worker_get_count() : nworkers; /* Number of different workers */
+	int nt = 0; /* Number of different kinds of tasks */
+	struct bound_task_pool * tp;
+	for (tp = task_pools; tp; tp = tp->next)
+		nt++;
+	
+	double w_in_s[ns][nw];
+	
+	unsigned found_sol = _compute_task_distribution_over_ctxs(ns, nw, nt, w_in_s, sched_ctxs, workers);
+	/* if we did find at least one solution redistribute the resources */
+	if(found_sol)
+		_redistribute_resources_in_ctxs(ns, nw, nt, w_in_s, 1, sched_ctxs, workers);
+}
+
+static void size_if_required()
+{
+	int nsched_ctxs, nworkers;
+	int *sched_ctxs, *workers;
+	unsigned has_req = sched_ctx_hypervisor_get_size_req(&sched_ctxs, &nsched_ctxs, &workers, &nworkers);	
+
+	if(has_req)
+	{
+		struct sched_ctx_wrapper* sc_w = NULL;
+		unsigned ready_to_size = 1;
+		int s;
+		pthread_mutex_lock(&act_hypervisor_mutex);
+		for(s = 0; s < nsched_ctxs; s++)
+		{
+			sc_w = sched_ctx_hypervisor_get_wrapper(sched_ctxs[s]);
+			if(sc_w->submitted_flops < sc_w->total_flops)
+				ready_to_size = 0;
+		}
+
+		if(ready_to_size)
+			_size_ctxs(sched_ctxs, nsched_ctxs, workers, nworkers);
+		pthread_mutex_unlock(&act_hypervisor_mutex);
+	}
+}
+
 static void lp3_handle_submitted_job(struct starpu_task *task, uint32_t footprint)
 {
 	/* count the tasks of the same type */
@@ -47,9 +90,11 @@ static void lp3_handle_submitted_job(struct starpu_task *task, uint32_t footprin
 	/* One more task of this kind */
 	tp->n++;
 	pthread_mutex_unlock(&mutex);
+
+	size_if_required();
 }
 
-static void _starpu_get_tasks_times(int nw, int nt, double times[nw][nt])
+static void _starpu_get_tasks_times(int nw, int nt, double times[nw][nt], int *workers)
 {
         struct bound_task_pool *tp;
         int w, t;
@@ -57,7 +102,8 @@ static void _starpu_get_tasks_times(int nw, int nt, double times[nw][nt])
         {
                 for (t = 0, tp = task_pools; tp; t++, tp = tp->next)
                 {
-                        enum starpu_perf_archtype arch = starpu_worker_get_perf_archtype(w);
+                        enum starpu_perf_archtype arch = workers == NULL ? starpu_worker_get_perf_archtype(w) :
+				starpu_worker_get_perf_archtype(workers[w]);
                         double length = starpu_history_based_job_expected_perf(tp->cl->model, arch, tp->footprint);
 
                         if (isnan(length))
@@ -77,7 +123,7 @@ static void _starpu_get_tasks_times(int nw, int nt, double times[nw][nt])
  */
 #ifdef HAVE_GLPK_H
 #include <glpk.h>
-static double _glp_resolve(int ns, int nw, int nt, double tasks[nw][nt], double tmax, double w_in_s[ns][nw])
+static double _glp_resolve(int ns, int nw, int nt, double tasks[nw][nt], double tmax, double w_in_s[ns][nw], int *in_sched_ctxs, int *workers)
 {
 	struct bound_task_pool * tp;
 	int t, w, s;
@@ -99,7 +145,7 @@ static double _glp_resolve(int ns, int nw, int nt, double tasks[nw][nt], double
 		int ia[ne], ja[ne];
 		double ar[ne];
 
-		_starpu_get_tasks_times(nw, nt, times);
+		_starpu_get_tasks_times(nw, nt, times, workers);
 
 		/* Variables: number of tasks i assigned to worker j, and tmax */
 		glp_add_cols(lp, nw*nt+ns*nw);
@@ -125,7 +171,7 @@ static double _glp_resolve(int ns, int nw, int nt, double tasks[nw][nt], double
 				glp_set_col_bnds(lp, nw*nt+s*nw+w+1, GLP_DB, 0.0, 1.0);
 			}
 
-		int *sched_ctxs = sched_ctx_hypervisor_get_sched_ctxs();
+		int *sched_ctxs = in_sched_ctxs == NULL ? sched_ctx_hypervisor_get_sched_ctxs() : in_sched_ctxs;
 
 		int curr_row_idx = 0;
 		/* Total worker execution time */
@@ -253,9 +299,9 @@ static double _glp_resolve(int ns, int nw, int nt, double tasks[nw][nt], double
 	return res;
 }
 
-static void _redistribute_resources_in_ctxs(int ns, int nw, int nt, double w_in_s[ns][nw])
+static void _redistribute_resources_in_ctxs(int ns, int nw, int nt, double w_in_s[ns][nw], unsigned first_time, int *in_sched_ctxs, int *workers)
 {
-	int *sched_ctxs = sched_ctx_hypervisor_get_sched_ctxs();
+	int *sched_ctxs = in_sched_ctxs == NULL ? sched_ctx_hypervisor_get_sched_ctxs() : in_sched_ctxs;
         struct bound_task_pool * tp;
 	int s, s2, w, t;
 
@@ -273,12 +319,18 @@ static void _redistribute_resources_in_ctxs(int ns, int nw, int nt, double w_in_
 		for(w = 0; w < nw; w++)
 		{
 			if(w_in_s[s][w] >= 0.5)
-				workers_to_add[nadd++] = w;
+				workers_to_add[nadd++] = workers == NULL ? w : workers[w];
 			else
-				workers_to_remove[nremove++] = w;
+				workers_to_remove[nremove++] = workers == NULL ? w : workers[w];
 		}
 		
-		sched_ctx_hypervisor_remove_workers_from_sched_ctx(workers_to_remove, nremove, sched_ctxs[s]);
+		if(!first_time)
+		{
+			printf("********resize \n");
+			sched_ctx_hypervisor_remove_workers_from_sched_ctx(workers_to_remove, nremove, sched_ctxs[s]);
+		}
+		else
+			printf("*********size \n");
 	
 		sched_ctx_hypervisor_add_workers_to_sched_ctx(workers_to_add, nadd, sched_ctxs[s]);
 		struct policy_config *new_config = sched_ctx_hypervisor_get_config(sched_ctxs[s]);
@@ -294,6 +346,88 @@ static double _find_tmax(double t1, double t2)
 	return t1 + ((t2 - t1)/2);
 }
 
+static unsigned _compute_task_distribution_over_ctxs(int ns, int nw, int nt, double w_in_s[ns][nw], int *sched_ctxs, int *workers)
+{	
+	double tasks[nw][nt];
+	double draft_tasks[nw][nt];
+	double draft_w_in_s[ns][nw];
+	
+	int w,t, s;
+	for(w = 0; w < nw; w++)
+		for(t = 0; t < nt; t++)
+		{
+			tasks[w][t] = 0.0;
+			draft_tasks[w][t] == 0.0;
+		}
+	
+	for(s = 0; s < ns; s++)
+		for(w = 0; w < nw; w++)
+		{
+			w_in_s[s][w] = 0.0;
+			draft_w_in_s[s][w] = 0.0;
+		}
+
+	/* smallest possible tmax, difficult to obtain as we 
+	   compute the nr of flops and not the tasks */
+	double smallest_tmax = _lp_get_tmax(nw, workers);
+	double tmax = smallest_tmax * ns;
+	printf("tmax = %lf\n", tmax);
+	
+	double res = 1.0;
+	unsigned has_sol = 0;
+	double tmin = 0.0;
+	double old_tmax = 0.0;
+	unsigned found_sol;
+	/* we fix tmax and we do not treat it as an unknown
+	   we just vary by dichotomy its values*/
+	while(tmax > 1.0)
+	{
+		/* find solution and save the values in draft tables
+		   only if there is a solution for the system we save them
+		   in the proper table */
+		res = _glp_resolve(ns, nw, nt, draft_tasks, tmax, draft_w_in_s, sched_ctxs, workers);
+		if(res != 0.0)
+		{
+			for(w = 0; w < nw; w++)
+				for(t = 0; t < nt; t++)
+					tasks[w][t] = draft_tasks[w][t];
+			for(s = 0; s < ns; s++)
+				for(w = 0; w < nw; w++)
+					w_in_s[s][w] = draft_w_in_s[s][w];
+			has_sol = 1;
+			found_sol = 1;
+		}
+		else
+			has_sol = 0;
+		
+		/* if we have a solution with this tmax try a smaller value
+		   bigger than the old min */
+		if(has_sol)
+		{
+			printf("%lf: has sol\n", tmax);
+			if(old_tmax != 0.0 && (old_tmax - tmax) < 0.5)
+				break;
+			old_tmax = tmax;
+		}
+		else /*else try a bigger one but smaller than the old tmax */
+		{
+			printf("%lf: no sol\n", tmax);
+			tmin = tmax;
+			if(old_tmax != 0.0)
+				tmax = old_tmax;
+		}
+		if(tmin == tmax) break;
+		tmax = _find_tmax(tmin, tmax);
+		
+		if(tmax < smallest_tmax)
+		{
+			found_sol = 0;
+			break;
+		}
+	}
+	return found_sol;
+}
+
 static int done = 0;
 static void lp3_handle_poped_task(unsigned sched_ctx, int worker)
 {
@@ -317,96 +451,29 @@ static void lp3_handle_poped_task(unsigned sched_ctx, int worker)
 			for (tp = task_pools; tp; tp = tp->next)
 				nt++;
 			
-			double tasks[nw][nt];
-			double draft_tasks[nw][nt];
 			double w_in_s[ns][nw];
-			double draft_w_in_s[ns][nw];
 
- 			int w,t, s;
-			for(w = 0; w < nw; w++)
-				for(t = 0; t < nt; t++)
-				{
-					tasks[w][t] = 0.0;
-					draft_tasks[w][t] == 0.0;
-				}
-
-			for(s = 0; s < ns; s++)
-				for(w = 0; w < nw; w++)
-				{
-					w_in_s[s][w] = 0.0;
-					draft_w_in_s[s][w] = 0.0;
-				}
-
-			/* smallest possible tmax, difficult to obtain as we 
-			   compute the nr of flops and not the tasks */
-			double smallest_tmax = _lp_get_tmax();
-			double tmax = smallest_tmax * ns;
-			printf("tmax = %lf\n", tmax);
-
-			double res = 1.0;
-			unsigned has_sol = 0;
-			double tmin = 0.0;
-			double old_tmax = 0.0;
-			unsigned found_sol;
-			/* we fix tmax and we do not treat it as an unknown
-			   we just vary by dichotomy its values*/
-			while(tmax > 1.0)
-			{
-				/* find solution and save the values in draft tables
-				   only if there is a solution for the system we save them
-				   in the proper table */
-				res = _glp_resolve(ns, nw, nt, draft_tasks, tmax, draft_w_in_s);
-				if(res != 0.0)
-				{
-					for(w = 0; w < nw; w++)
-						for(t = 0; t < nt; t++)
-							tasks[w][t] = draft_tasks[w][t];
-					for(s = 0; s < ns; s++)
-						for(w = 0; w < nw; w++)
-							w_in_s[s][w] = draft_w_in_s[s][w];
-					has_sol = 1;
-					found_sol = 1;
-				}
-				else
-					has_sol = 0;
-				
-				/* if we have a solution with this tmax try a smaller value
-				   bigger than the old min */
-				if(has_sol)
-				{
-					printf("%lf: has sol\n", tmax);
-					if(old_tmax != 0.0 && (old_tmax - tmax) < 0.5)
-						break;
-					old_tmax = tmax;
-				}
-				else /*else try a bigger one but smaller than the old tmax */
-				{
-					printf("%lf: no sol\n", tmax);
-					tmin = tmax;
-					if(old_tmax != 0.0)
-						tmax = old_tmax;
-				}
-				if(tmin == tmax) break;
-				tmax = _find_tmax(tmin, tmax);
-
-				if(tmax < smallest_tmax)
-				{
-					found_sol = 0;
-					break;
-				}
-			}
+			unsigned found_sol = _compute_task_distribution_over_ctxs(ns, nw, nt, w_in_s, NULL, NULL);
 			/* if we did find at least one solution redistribute the resources */
 			if(found_sol)
 			{
 				done = 1;
-				_redistribute_resources_in_ctxs(ns, nw, nt, w_in_s);
+				_redistribute_resources_in_ctxs(ns, nw, nt, w_in_s, 0, NULL, NULL);
 			}
 		}
 		pthread_mutex_unlock(&act_hypervisor_mutex);
 	}		
 }
 
+
+static void lp3_size_ctxs(int *sched_ctxs, int nsched_ctxs , int *workers, int nworkers)
+{
+	printf("require size !!!!!!!!!!!!!!\n");
+	sched_ctx_hypervisor_save_size_req(sched_ctxs, nsched_ctxs, workers, nworkers);
+}
+
 struct hypervisor_policy lp3_policy = {
+	.size_ctxs = lp3_size_ctxs,
 	.handle_poped_task = lp3_handle_poped_task,
 	.handle_pushed_task = NULL,
 	.handle_idle_cycle = NULL,

+ 134 - 23
sched_ctx_hypervisor/src/hypervisor_policies/lp_policy.c

@@ -142,35 +142,37 @@ static void _redistribute_resources_in_ctxs(int ns, int nw, int res_rounded[ns][
 						int x = floor(nworkers_to_move);
 						double x_double = (double)x;
 						double diff = nworkers_to_move - x_double;
-						if(diff == 0)
+						if(diff == 0.0)
 						{
 							int *workers_to_move = _get_first_workers(sched_ctxs[s], &x, arch);
-							sched_ctx_hypervisor_move_workers(sched_ctxs[s], receiving_s, workers_to_move, x);
-							struct policy_config *new_config = sched_ctx_hypervisor_get_config(receiving_s);
-							int i;
-							for(i = 0; i < x; 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;
-							
+							if(x > 0)
+							{
+								sched_ctx_hypervisor_move_workers(sched_ctxs[s], receiving_s, workers_to_move, x);
+
+								struct policy_config *new_config = sched_ctx_hypervisor_get_config(receiving_s);
+								int i;
+								for(i = 0; i < x; 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;
+							}
 							free(workers_to_move);
 						}
 						else
 						{
 							x+=1;
 							int *workers_to_move = _get_first_workers(sched_ctxs[s], &x, arch);
-							sched_ctx_hypervisor_remove_workers_from_sched_ctx(workers_to_move, x-1, sched_ctxs[s]);
-							if(diff > 0.3)
-								sched_ctx_hypervisor_add_workers_to_sched_ctx(workers_to_move, x, receiving_s);
-							else
-								sched_ctx_hypervisor_add_workers_to_sched_ctx(workers_to_move, x-1, receiving_s);
-
-							struct policy_config *new_config = sched_ctx_hypervisor_get_config(receiving_s);
-							int i;
-							for(i = 0; i < x-1; 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;
-
+							if(x > 0)
+							{
+								if(diff > 0.3)
+									sched_ctx_hypervisor_add_workers_to_sched_ctx(workers_to_move, x, receiving_s);
+								else
+									sched_ctx_hypervisor_add_workers_to_sched_ctx(workers_to_move, x-1, receiving_s);
+								
+								struct policy_config *new_config = sched_ctx_hypervisor_get_config(receiving_s);
+								int i;
+								for(i = 0; i < x-1; 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;
+							}
 							free(workers_to_move);
-							
-
 						}
 					}
 				}
@@ -180,6 +182,82 @@ static void _redistribute_resources_in_ctxs(int ns, int nw, int res_rounded[ns][
 	}
 }
 
+static void _distribute_resources_in_ctxs(int* sched_ctxs, int ns, int nw, int res_rounded[ns][nw], double res[ns][nw], int *workers, int nworkers)
+{
+	int current_nworkers = workers == NULL ? starpu_worker_get_count() : nworkers;
+	int *current_sched_ctxs = sched_ctxs == NULL ? sched_ctx_hypervisor_get_sched_ctxs() : sched_ctxs;
+
+	int s, s2, w;
+	for(s = 0; s < ns; s++)
+	{
+		for(w = 0; w < nw; w++)
+		{
+			enum starpu_archtype arch;
+			if(w == 0) arch = STARPU_CUDA_WORKER;
+			if(w == 1) arch = STARPU_CPU_WORKER;
+
+			if(w == 1)
+			{
+				int nworkers_to_add = res_rounded[s][w];
+				int *workers_to_add = _get_first_workers_in_list(workers, current_nworkers, &nworkers_to_add, arch);
+
+				if(nworkers_to_add > 0)
+				{
+					sched_ctx_hypervisor_add_workers_to_sched_ctx(workers_to_add, nworkers_to_add, current_sched_ctxs[s]);
+					sched_ctx_hypervisor_start_resize(current_sched_ctxs[s]);
+					struct policy_config *new_config = sched_ctx_hypervisor_get_config(current_sched_ctxs[s]);
+					int i;
+					for(i = 0; i < nworkers_to_add; i++)
+						new_config->max_idle[workers_to_add[i]] = new_config->max_idle[workers_to_add[i]] != MAX_IDLE_TIME ? new_config->max_idle[workers_to_add[i]] :  new_config->new_workers_max_idle;
+				}
+				free(workers_to_add);
+			}
+			else
+			{
+				double nworkers_to_add = res[s][w];
+				int x = floor(nworkers_to_add);
+				double x_double = (double)x;
+				double diff = nworkers_to_add - x_double;
+				if(diff == 0.0)
+				{
+					int *workers_to_add = _get_first_workers_in_list(workers, current_nworkers, &x, arch);
+					if(x > 0)
+					{
+						sched_ctx_hypervisor_add_workers_to_sched_ctx(workers_to_add, x, current_sched_ctxs[s]);
+						sched_ctx_hypervisor_start_resize(current_sched_ctxs[s]);
+						struct policy_config *new_config = sched_ctx_hypervisor_get_config(current_sched_ctxs[s]);
+						int i;
+						for(i = 0; i < x; i++)
+							new_config->max_idle[workers_to_add[i]] = new_config->max_idle[workers_to_add[i]] != MAX_IDLE_TIME ? new_config->max_idle[workers_to_add[i]] :  new_config->new_workers_max_idle;
+						
+					}
+					free(workers_to_add);
+				}
+				else
+				{
+					x+=1;
+					int *workers_to_add = _get_first_workers_in_list(workers, current_nworkers, &x, arch);
+					if(x > 0)
+					{
+						if(diff >= 0.3)
+							sched_ctx_hypervisor_add_workers_to_sched_ctx(workers_to_add, x, current_sched_ctxs[s]);
+						else
+							sched_ctx_hypervisor_add_workers_to_sched_ctx(workers_to_add, x-1, current_sched_ctxs[s]);
+						sched_ctx_hypervisor_start_resize(current_sched_ctxs[s]);
+						struct policy_config *new_config = sched_ctx_hypervisor_get_config(current_sched_ctxs[s]);
+						int i;
+						for(i = 0; i < x-1; i++)
+							new_config->max_idle[workers_to_add[i]] = new_config->max_idle[workers_to_add[i]] != MAX_IDLE_TIME ? new_config->max_idle[workers_to_add[i]] :  new_config->new_workers_max_idle;
+					}
+					free(workers_to_add);			
+				}
+			}
+			
+		}
+		sched_ctx_hypervisor_stop_resize(current_sched_ctxs[s]);
+	}
+}
+
 static void lp_handle_poped_task(unsigned sched_ctx, int worker)
 {
 	if(_velocity_gap_btw_ctxs())
@@ -192,9 +270,12 @@ static void lp_handle_poped_task(unsigned sched_ctx, int worker)
 		int ret = pthread_mutex_trylock(&act_hypervisor_mutex);
 		if(ret != EBUSY)
 		{ 
-			double vmax = _lp_get_nworkers_per_ctx(nsched_ctxs, 2, res);
+			int total_nw[2];
+			_get_total_nw(NULL, -1, 2, total_nw);
+			double vmax = _lp_get_nworkers_per_ctx(nsched_ctxs, 2, res, total_nw);
 			if(vmax != 0.0)
 			{
+//				printf("********resize\n");
 /* 			for( i = 0; i < nsched_ctxs; i++) */
 /* 			{ */
 /* 				printf("ctx %d/worker type %d: n = %lf \n", i, 0, res[i][0]); */
@@ -209,15 +290,45 @@ static void lp_handle_poped_task(unsigned sched_ctx, int worker)
 /* 			} */
 				
 				_redistribute_resources_in_ctxs(nsched_ctxs, 2, res_rounded, res);
-				
-				pthread_mutex_unlock(&act_hypervisor_mutex);
 			}
+			pthread_mutex_unlock(&act_hypervisor_mutex);
 		}
 	}		
 }
+static void lp_size_ctxs(int *sched_ctxs, int ns, int *workers, int nworkers)
+{	
+	int nsched_ctxs = sched_ctxs == NULL ? sched_ctx_hypervisor_get_nsched_ctxs() : ns;
+	double res[nsched_ctxs][2];
+	int total_nw[2];
+	_get_total_nw(workers, nworkers, 2, total_nw);
+
+	pthread_mutex_lock(&act_hypervisor_mutex);
+	double vmax = _lp_get_nworkers_per_ctx(nsched_ctxs, 2, res, total_nw);
+	if(vmax != 0.0)
+	{
+		int i;
+		printf("********size\n");
+/* 		for( i = 0; i < nsched_ctxs; i++) */
+/* 		{ */
+/* 			printf("ctx %d/worker type %d: n = %lf \n", i, 0, res[i][0]); */
+/* 			printf("ctx %d/worker type %d: n = %lf \n", i, 1, res[i][1]); */
+/* 		} */
+		int res_rounded[nsched_ctxs][2];
+		_round_double_to_int(nsched_ctxs, 2, res, res_rounded);
+/*       		for( i = 0; i < nsched_ctxs; i++) */
+/* 		{ */
+/* 			printf("ctx %d/worker type %d: n = %d \n", i, 0, res_rounded[i][0]); */
+/* 			printf("ctx %d/worker type %d: n = %d \n", i, 1, res_rounded[i][1]); */
+/* 		} */
+		
+		_distribute_resources_in_ctxs(sched_ctxs, nsched_ctxs, 2, res_rounded, res, workers, nworkers);
+	}
+	pthread_mutex_unlock(&act_hypervisor_mutex);
+}
 
 #ifdef HAVE_GLPK_H
 struct hypervisor_policy lp_policy = {
+	.size_ctxs = lp_size_ctxs,
 	.handle_poped_task = lp_handle_poped_task,
 	.handle_pushed_task = NULL,
 	.handle_idle_cycle = NULL,

+ 12 - 8
sched_ctx_hypervisor/src/hypervisor_policies/lp_tools.c

@@ -2,7 +2,7 @@
 
 #ifdef HAVE_GLPK_H
 
-static double _glp_get_nworkers_per_ctx(int ns, int nw, double v[ns][nw], double flops[ns], double res[ns][nw])
+static double _glp_get_nworkers_per_ctx(int ns, int nw, double v[ns][nw], double flops[ns], double res[ns][nw], double total_nw[nw])
 {
 	int s, w;
 	glp_prob *lp;
@@ -122,11 +122,11 @@ static double _glp_get_nworkers_per_ctx(int ns, int nw, double v[ns][nw], double
 
 		/*sum(all gpus) = 3*/
 		if(w == 0)
-			glp_set_row_bnds(lp, ns+w+1, GLP_FX, 3., 3.);
+			glp_set_row_bnds(lp, ns+w+1, GLP_FX, total_nw[0], total_nw[0]);
 
 		/*sum(all cpus) = 9*/
 		if(w == 1) 
-			glp_set_row_bnds(lp, ns+w+1, GLP_FX, 9., 9.);
+			glp_set_row_bnds(lp, ns+w+1, GLP_FX, total_nw[1], total_nw[1]);
 	}
 
 	STARPU_ASSERT(n == ne);
@@ -156,7 +156,7 @@ static double _glp_get_nworkers_per_ctx(int ns, int nw, double v[ns][nw], double
 
 #endif //HAVE_GLPK_H
 
-double _lp_get_nworkers_per_ctx(int nsched_ctxs, int ntypes_of_workers, double res[nsched_ctxs][ntypes_of_workers])
+double _lp_get_nworkers_per_ctx(int nsched_ctxs, int ntypes_of_workers, double res[nsched_ctxs][ntypes_of_workers], int total_nw[ntypes_of_workers])
 {
 	int *sched_ctxs = sched_ctx_hypervisor_get_sched_ctxs();
 	double v[nsched_ctxs][ntypes_of_workers];
@@ -173,16 +173,20 @@ double _lp_get_nworkers_per_ctx(int nsched_ctxs, int ntypes_of_workers, double r
 	}
 
 #ifdef HAVE_GLPK_H	
-	return 1/_glp_get_nworkers_per_ctx(nsched_ctxs, ntypes_of_workers, v, flops, res);
+	return 1/_glp_get_nworkers_per_ctx(nsched_ctxs, ntypes_of_workers, v, flops, res, total_nw);
 #else
 	return 0.0;
 #endif
 }
 
-double _lp_get_tmax()
+double _lp_get_tmax(int nw, int *workers)
 {
+	int ntypes_of_workers = 2;
+	int total_nw[ntypes_of_workers];
+	_get_total_nw(workers, nw, 2, total_nw);
+
 	int nsched_ctxs = sched_ctx_hypervisor_get_nsched_ctxs();
 	
-	double res[nsched_ctxs][2];
-	return _lp_get_nworkers_per_ctx(nsched_ctxs, 2, res) * 1000;
+	double res[nsched_ctxs][ntypes_of_workers];
+	return _lp_get_nworkers_per_ctx(nsched_ctxs, ntypes_of_workers, res, total_nw) * 1000;
 }

+ 2 - 2
sched_ctx_hypervisor/src/hypervisor_policies/lp_tools.h

@@ -7,7 +7,7 @@
 #endif //HAVE_GLPK_H
 
 /* returns tmax, and computes in table res the nr of workers needed by each context st the system ends up in the smallest tmax*/
-double _lp_get_nworkers_per_ctx(int nsched_ctxs, int ntypes_of_workers, double res[nsched_ctxs][ntypes_of_workers]);
+double _lp_get_nworkers_per_ctx(int nsched_ctxs, int ntypes_of_workers, double res[nsched_ctxs][ntypes_of_workers], int total_nw[ntypes_of_workers]);
 
 /* returns tmax of the system */
-double _lp_get_tmax();
+double _lp_get_tmax(int nw, int *workers);

+ 39 - 0
sched_ctx_hypervisor/src/hypervisor_policies/policy_tools.c

@@ -60,6 +60,28 @@ unsigned _find_poor_sched_ctx(unsigned req_sched_ctx, int nworkers_to_move)
 	return sched_ctx;
 }
 
+int* _get_first_workers_in_list(int *workers, int nall_workers,  unsigned *nworkers, enum starpu_archtype arch)
+{
+	int *curr_workers = (int*)malloc((*nworkers)*sizeof(int));
+	
+	int w, worker;
+	int nfound_workers = 0;
+	for(w = 0; w < nall_workers; w++)
+	{
+		worker = workers == NULL ? w : workers[w];
+		enum starpu_archtype curr_arch = starpu_worker_get_type(worker);
+		if(arch == STARPU_ALL || curr_arch == arch)
+		{
+			curr_workers[nfound_workers++] = worker;
+		}
+		if(nfound_workers == *nworkers)
+			break;
+	}
+	if(nfound_workers < *nworkers)
+		*nworkers = nfound_workers;
+	return curr_workers;
+}
+
 /* get first nworkers with the highest idle time in the context */
 int* _get_first_workers(unsigned sched_ctx, unsigned *nworkers, enum starpu_archtype arch)
 {
@@ -357,3 +379,20 @@ int _velocity_gap_btw_ctxs()
 }
 
 
+void _get_total_nw(int *workers, int nworkers, int ntypes_of_workers, double total_nw[ntypes_of_workers])
+{
+	int current_nworkers = workers == NULL ? starpu_worker_get_count() : nworkers;
+	int w;
+	for(w = 0; w < ntypes_of_workers; w++)
+		total_nw[w] = 0.0;
+
+	for(w = 0; w < current_nworkers; w++)
+	{
+		enum starpu_perf_archtype arch = workers == NULL ? starpu_worker_get_type(w) :
+			starpu_worker_get_type(workers[w]);
+		if(arch == STARPU_CPU_WORKER)
+			total_nw[1]++;
+		else
+			total_nw[0]++;
+	}
+}

+ 4 - 0
sched_ctx_hypervisor/src/hypervisor_policies/policy_tools.h

@@ -19,6 +19,8 @@ unsigned _find_poor_sched_ctx(unsigned req_sched_ctx, int nworkers_to_move);
 
 int* _get_first_workers(unsigned sched_ctx, unsigned *nworkers, enum starpu_archtype arch);
 
+int* _get_first_workers_in_list(int *workers, int nall_workers,  unsigned *nworkers, enum starpu_archtype arch);
+
 unsigned _get_potential_nworkers(struct policy_config *config, unsigned sched_ctx, enum starpu_archtype arch);
 
 unsigned _get_nworkers_to_move(unsigned req_sched_ctx);
@@ -32,3 +34,5 @@ double _get_ctx_velocity(struct sched_ctx_wrapper* sc_w);
 double _get_velocity_per_worker_type(struct sched_ctx_wrapper* sc_w, enum starpu_archtype arch);
 
 int _velocity_gap_btw_ctxs(void);
+
+void _get_total_nw(int *workers, int nworkers, int ntypes_of_workers, double total_nw[ntypes_of_workers]);

+ 45 - 1
sched_ctx_hypervisor/src/sched_ctx_hypervisor.c

@@ -57,6 +57,7 @@ static void _load_hypervisor_policy(struct hypervisor_policy *policy)
         }
 #endif
 	hypervisor.policy.name = policy->name;
+	hypervisor.policy.size_ctxs = policy->size_ctxs;
 	hypervisor.policy.handle_poped_task = policy->handle_poped_task;
 	hypervisor.policy.handle_pushed_task = policy->handle_pushed_task;
 	hypervisor.policy.handle_idle_cycle = policy->handle_idle_cycle;
@@ -134,6 +135,7 @@ struct starpu_performance_counters* sched_ctx_hypervisor_init(struct hypervisor_
 	{
 		hypervisor.resize[i] = 0;
 		hypervisor.configurations[i] = NULL;
+		hypervisor.sr = NULL;
 		hypervisor.sched_ctxs[i] = STARPU_NMAX_SCHED_CTXS;
 		hypervisor.sched_ctx_w[i].sched_ctx = STARPU_NMAX_SCHED_CTXS;
 		hypervisor.sched_ctx_w[i].config = NULL;
@@ -426,7 +428,6 @@ void sched_ctx_hypervisor_remove_workers_from_sched_ctx(int* workers_to_remove,
 		printf("\n");
 
 		starpu_remove_workers_from_sched_ctx(workers_to_remove, nworkers_to_remove, sched_ctx);
-
 /* 		hypervisor.sched_ctx_w[sched_ctx].resize_ack.receiver_sched_ctx = sched_ctx; */
 /* 		hypervisor.sched_ctx_w[sched_ctx].resize_ack.moved_workers = (int*)malloc(nworkers_to_remove * sizeof(int)); */
 /* 		hypervisor.sched_ctx_w[sched_ctx].resize_ack.nmoved_workers = nworkers_to_remove; */
@@ -672,6 +673,18 @@ static void notify_submitted_job(struct starpu_task *task, uint32_t footprint)
 		hypervisor.policy.handle_submitted_job(task, footprint);
 }
 
+void sched_ctx_hypervisor_size_ctxs(int *sched_ctxs, int nsched_ctxs, int *workers, int nworkers)
+{
+	int curr_nsched_ctxs = sched_ctxs == NULL ? hypervisor.nsched_ctxs : nsched_ctxs;
+	int *curr_sched_ctxs = sched_ctxs == NULL ? hypervisor.sched_ctxs : sched_ctxs;
+	int s;
+	for(s = 0; s < curr_nsched_ctxs; s++)
+		hypervisor.resize[curr_sched_ctxs[s]] = 1;
+
+	if(hypervisor.policy.size_ctxs)
+		hypervisor.policy.size_ctxs(curr_sched_ctxs, curr_nsched_ctxs, workers, nworkers);
+}
+
 struct sched_ctx_wrapper* sched_ctx_hypervisor_get_wrapper(unsigned sched_ctx)
 {
 	return &hypervisor.sched_ctx_w[sched_ctx];
@@ -686,3 +699,34 @@ int sched_ctx_hypervisor_get_nsched_ctxs()
 {
 	return hypervisor.nsched_ctxs;
 }
+
+void sched_ctx_hypervisor_save_size_req(int *sched_ctxs, int nsched_ctxs, int *workers, int nworkers)
+{
+	hypervisor.sr = (struct size_request*)malloc(sizeof(struct size_request));
+	hypervisor.sr->sched_ctxs = sched_ctxs;
+	hypervisor.sr->nsched_ctxs = nsched_ctxs;
+	hypervisor.sr->workers = workers;
+	hypervisor.sr->nworkers = nworkers;
+}
+
+unsigned sched_ctx_hypervisor_get_size_req(int **sched_ctxs, int* nsched_ctxs, int **workers, int *nworkers)
+{
+	if(hypervisor.sr != NULL)
+	{
+		*sched_ctxs = hypervisor.sr->sched_ctxs;
+		*nsched_ctxs = hypervisor.sr->nsched_ctxs;
+		*workers = hypervisor.sr->workers;
+		*nworkers = hypervisor.sr->nworkers;
+		return 1;
+	}
+	return 0;
+}
+
+void sched_ctx_hypervisor_free_size_req(void)
+{
+	if(hypervisor.sr != NULL)
+	{
+		free(hypervisor.sr);
+		hypervisor.sr = NULL;
+	}
+}

+ 8 - 0
sched_ctx_hypervisor/src/sched_ctx_hypervisor_intern.h

@@ -17,6 +17,13 @@
 #include <sched_ctx_hypervisor.h>
 #include <common/htable32.h>
 
+struct size_request {
+	int *workers;
+	int nworkers;
+	int *sched_ctxs;
+	int nsched_ctxs;
+};
+
 struct sched_ctx_hypervisor {
 	struct sched_ctx_wrapper sched_ctx_w[STARPU_NMAX_SCHED_CTXS];
 	int sched_ctxs[STARPU_NMAX_SCHED_CTXS];
@@ -26,6 +33,7 @@ struct sched_ctx_hypervisor {
 	struct hypervisor_policy policy;
 	struct starpu_htbl32_node *configurations[STARPU_NMAX_SCHED_CTXS];
 	struct starpu_htbl32_node *resize_requests[STARPU_NMAX_SCHED_CTXS];
+	struct size_request *sr;
 };
 
 struct sched_ctx_hypervisor_adjustment {

+ 11 - 11
src/core/sched_policy.c

@@ -339,21 +339,21 @@ int _starpu_push_task(struct _starpu_job *j)
 		
 		if(nworkers == 0)
 		{
-			if(workerid == -1)
-			{
-				_STARPU_PTHREAD_MUTEX_LOCK(&sched_ctx->no_workers_mutex);
-				_STARPU_PTHREAD_COND_WAIT(&sched_ctx->no_workers_cond, &sched_ctx->no_workers_mutex);
-				_STARPU_PTHREAD_MUTEX_UNLOCK(&sched_ctx->no_workers_mutex);
-				nworkers = _starpu_nworkers_able_to_execute_task(task, sched_ctx);
-				if(nworkers == 0) return _starpu_push_task(j);
-			}
-			else
-			{
+/* 			if(workerid == -1) */
+/* 			{ */
+/* 				_STARPU_PTHREAD_MUTEX_LOCK(&sched_ctx->no_workers_mutex); */
+/* 				_STARPU_PTHREAD_COND_WAIT(&sched_ctx->no_workers_cond, &sched_ctx->no_workers_mutex); */
+/* 				_STARPU_PTHREAD_MUTEX_UNLOCK(&sched_ctx->no_workers_mutex); */
+/* 				nworkers = _starpu_nworkers_able_to_execute_task(task, sched_ctx); */
+/* 				if(nworkers == 0) return _starpu_push_task(j); */
+/* 			} */
+/* 			else */
+//			{
 				_STARPU_PTHREAD_MUTEX_LOCK(&sched_ctx->empty_ctx_mutex);
 				starpu_task_list_push_front(&sched_ctx->empty_ctx_tasks, task);
 				_STARPU_PTHREAD_MUTEX_UNLOCK(&sched_ctx->empty_ctx_mutex);
 				return 0;
-			}
+//			}
 		}
 	}