Ver código fonte

mic: merge trunk

Thibaud Lambert 12 anos atrás
pai
commit
bdea9cea87

+ 1 - 1
doc/doxygen/chapters/api/scheduling_contexts.doxy

@@ -1,4 +1,4 @@
-*
+/*
  * This file is part of the StarPU Handbook.
  * Copyright (C) 2009--2011  Universit@'e de Bordeaux 1
  * Copyright (C) 2010, 2011, 2012, 2013  Centre National de la Recherche Scientifique

+ 1 - 1
doc/doxygen/chapters/api/scheduling_policy.doxy

@@ -27,7 +27,7 @@ starpu_init().
         Insert a task into the scheduler.
 \var starpu_sched_policy::push_task_notify
         Notify the scheduler that a task was pushed on a given worker.
-	This method is called when a task that was explicitely
+	This method is called when a task that was explicitly
 	assigned to a worker becomes ready and is about to be executed
 	by the worker. This method therefore permits to keep the state
 	of the scheduler coherent even when StarPU bypasses the

+ 65 - 15
doc/doxygen/chapters/scheduling_context_hypervisor.doxy

@@ -10,8 +10,8 @@
 
 \section WhatIsTheHypervisor What Is The Hypervisor
 
-StarPU proposes a platform for constructing Scheduling Contexts, for
-deleting and modifying them dynamically. A parallel kernel, can thus
+StarPU proposes a platform to construct Scheduling Contexts, to
+deleting and modify them dynamically. A parallel kernel, can thus
 be isolated into a scheduling context and interferences between
 several parallel kernels are avoided. If the user knows exactly how
 many workers each scheduling context needs, he can assign them to the
@@ -31,11 +31,11 @@ platform for implementing additional custom ones is available.
 
 \section StartTheHypervisor Start the Hypervisor
 
-The Hypervisor must be initialised once at the beging of the
+The Hypervisor must be initialized once at the beginning of the
 application. At this point a resizing policy should be indicated. This
 strategy depends on the information the application is able to provide
 to the hypervisor as well as on the accuracy needed for the resizing
-procedure. For exemple, the application may be able to provide an
+procedure. For example, the application may be able to provide an
 estimation of the workload of the contexts. In this situation the
 hypervisor may decide what resources the contexts need. However, if no
 information is provided the hypervisor evaluates the behavior of the
@@ -46,17 +46,25 @@ The hypervisor resizes only the registered contexts.
 
 The runtime provides the hypervisor with information concerning the
 behavior of the resources and the application. This is done by using
-the performance_counters, some callbacks indicating when the resources
-are idle or not efficient, when the application submits tasks or when
-it becames to slow.
+the <c>performance_counters</c> which represent callbacks indicating 
+when the resources are idle or not efficient, when the application 
+submits tasks or when it becomes to slow.
 
 \section TriggerTheHypervisor Trigger the Hypervisor
 
-The resizing is triggered either when the application requires it or
+The resizing is triggered either when the application requires it 
+(<c> sc_hypervisor_resize_ctxs </c>) or
 when the initials distribution of resources alters the performance of
-the application( the application is to slow or the resource are idle
-for too long time, threashold indicated by the user). When this
-happens different resizing strategy are applied that target minimising
+the application (the application is to slow or the resource are idle
+for too long time). If the environment 
+variable <c>SC_HYPERVISOR_TRIGGER_RESIZE</c> is set to <c>speed</c> 
+the monitored speed of the contexts is compared to a theoretical value
+computed with a linear program, and the resizing is triggered
+whenever the two values do not correspond. Otherwise, if the environment 
+variable is set to <c>idle</c> the hypervisor triggers the resizing algorithm
+whenever the workers are idle for a period longer than the threshold 
+indicated by the programmer. When this
+happens different resizing strategy are applied that target minimizing
 the total execution of the application, the instant speed or the idle
 time of the resources.
 
@@ -100,8 +108,7 @@ sc_hypervisor_ctl(sched_ctx,
 \endcode
 
 
-The <b>Idleness</b> based strategy resizes the scheduling contexts every time one of their workers stays idle
-for a period longer than the one imposed by the user
+The <b>Idleness</b> based strategy moves workers unused in a certain context to another one needing them.
 (see \ref UsersInputInTheResizingProcess "Users’ Input In The Resizing Process")
 
 \code{.c}
@@ -114,7 +121,7 @@ sc_hypervisor_ctl(sched_ctx_id,
 \endcode
 
 The <b>Gflops rate</b> based strategy resizes the scheduling contexts such that they all finish at the same time.
-The speed of each of them is considered and once one of them is significantly slower the resizing process is triggered.
+The speed of each of them is computed and once one of them is significantly slower the resizing process is triggered.
 In order to do these computations the user has to input the total number of instructions needed to be executed by the
 parallel kernels and the number of instruction to be executed by each
 task.
@@ -142,4 +149,47 @@ starpu_insert_task(&codelet,
                     0);
 \endcode
 
-*/
+The <b>Feft</b> strategy uses a linear program to predict the best distribution of resources
+such that the application finishes in a minimum amount of time. As for the <b>Gflops rate </b>
+strategy the programmers has to indicate the total number of flops to be executed
+when registering the context. This number of flops may be updated dynamically during the execution
+of the application whenever this information is not very accurate from the beginning.
+The function <c>sc_hypervisor_update_diff_total_flop </c> is called in order add or remove
+a difference to the flops left to be executed.
+Tasks are provided also the number of flops corresponding to each one of them. During the 
+execution of the application the hypervisor monitors the consumed flops and recomputes
+the time left and the number of resources to use. The speed of each type of resource
+is (re)evaluated and inserter in the linear program in order to better adapt to the 
+needs of the application.
+
+The <b>Teft</b> strategy uses a linear program too, that considers all the types of tasks
+and the number of each of them and it tries to allocates resources such that the application
+finishes in a minimum amount of time. A previous calibration of StarPU would be useful
+in order to have good predictions of the execution time of each type of task.
+
+The types of tasks may be determines directly by the hypervisor when they are submitted.
+However there are applications that do not expose all the graph of tasks from the beginning.
+In this case in order to let the hypervisor know about all the tasks the function
+<c> sc_hypervisor_set_type_of_task </c> will just inform the hypervisor about future tasks
+without submitting them right away.
+
+The <b>Ispeed </b> strategy divides the execution of the application in several frames.
+For each frame the hypervisor computes the speed of the contexts and tries making them
+run at the same speed. The strategy requires less contribution from the user as
+the hypervisor requires only the size of the frame in terms of flops.
+
+\code{.c}
+int workerids[3] = {1, 3, 10};
+int workerids2[9] = {0, 2, 4, 5, 6, 7, 8, 9, 11};
+sc_hypervisor_ctl(sched_ctx_id,
+                  SC_HYPERVISOR_ISPEED_W_SAMPLE, workerids, 3, 2000000000.0,
+                  SC_HYPERVISOR_ISPEED_W_SAMPLE, workerids2, 9, 200000000000.0,
+                  SC_HYPERVISOR_ISPEED_CTX_SAMPLE, 60000000000.0,
+            NULL);
+\endcode
+
+The <b>Throughput </b> strategy focuses on maximizing the throughput of the resources
+and resizes the contexts such that the machine is running at its maximum efficiency
+(maximum instant speed of the workers).
+
+*/

+ 43 - 20
doc/doxygen/chapters/scheduling_contexts.doxy

@@ -1,6 +1,6 @@
 /*
  * This file is part of the StarPU Handbook.
- * Copyright (C) 2009--2011  Universit@'e de Bordeaux 1
+//  * Copyright (C) 2009--2011  Universit@'e de Bordeaux 1
  * Copyright (C) 2010, 2011, 2012, 2013  Centre National de la Recherche Scientifique
  * Copyright (C) 2011, 2012 Institut National de Recherche en Informatique et Automatique
  * See the file version.doxy for copying conditions.
@@ -19,34 +19,44 @@ to minimize interferences between the execution of multiple parallel
 kernels, by partitioning the underlying pool of workers using
 contexts.
 
+
 \section CreatingAContext Creating A Context
 
 By default, the application submits tasks to an initial context, which
-disposes of all the computation ressources available to StarPU (all
+disposes of all the computation resources available to StarPU (all
 the workers). If the application programmer plans to launch several
-parallel kernels simultaneusly, by default these kernels will be
+parallel kernels simultaneously, by default these kernels will be
 executed within this initial context, using a single scheduler
 policy(see \ref TaskSchedulingPolicy). Meanwhile, if the application
 programmer is aware of the demands of these kernels and of the
 specificity of the machine used to execute them, the workers can be
 divided between several contexts. These scheduling contexts will
 isolate the execution of each kernel and they will permit the use of a
-scheduling policy proper to each one of them. In order to create the
-contexts, you have to know the indentifiers of the workers running
-within StarPU. By passing a set of workers together with the
-scheduling policy to the function starpu_sched_ctx_create(), you will
-get an identifier of the context created which you will use to
+scheduling policy proper to each one of them. 
+
+Scheduling Contexts may be created in two ways: either the programmers indicates
+the set of workers corresponding to each context (providing he knows the 
+identifiers of the workers running within StarPU), or the programmer
+does not provide any worker list and leaves the Hypervisor assign
+workers to each context according to their needs (\ref SchedulingContextHypervisor)
+
+Both cases require a call to the function <c>starpu_sched_ctx_create</c>, which 
+requires as input the worker list (the exact list or a NULL pointer) and the scheduling
+policy. The latter one can be a character list corresponding to the name of a StarPU
+predefined policy or the pointer to a custom policy. The function returns 
+an identifier of the context created which you will use to
 indicate the context you want to submit the tasks to.
 
+
 \code{.c}
-/* the list of ressources the context will manage */
+/* the list of resources the context will manage */
 int workerids[3] = {1, 3, 10};
 
 /* indicate the scheduling policy to be used within the context, the list of
    workers assigned to it, the number of workers, the name of the context */
 int id_ctx = starpu_sched_ctx_create("dmda", workerids, 3, "my_ctx");
 
-/* let StarPU know that the folowing tasks will be submitted to this context */
+/* let StarPU know that the following tasks will be submitted to this context */
 starpu_sched_ctx_set_task_context(id);
 
 /* submit the task to StarPU */
@@ -77,19 +87,32 @@ starpu_sched_ctx_add_workers(workerids, 3, sched_ctx2);
 starpu_sched_ctx_remove_workers(workerids, 3, sched_ctx1);
 \endcode
 
+\section SubmittingTasksToAContext Submitting Tasks To A Context
+The application may submit tasks to several contexts either 
+simultaneously or sequnetially. If several threads of submission
+are used the function <c>starpu_sched_ctx_set_context</c> may be called just
+before <c>starpu_task_submit</c>. Thus StarPU considers that 
+the current thread will submit tasks to the coresponding context.
+ 
+When the application may not assign a thread of submission to each
+context, the id of the context must be indicated by using the
+function <c>starpu_task_submit_to_ctx</c> or the field <c>STARPU_SCHED_CTX</c> 
+for <c>starpu_insert_task</c>.
+
 \section DeletingAContext Deleting A Context
 
 When a context is no longer needed it must be deleted. The application
 can indicate which context should keep the resources of a deleted one.
-All the tasks of the context should be executed before doing this. If
-the application need to avoid a barrier before moving the resources
-from the deleted context to the inheritor one, the application can
-just indicate when the last task was submitted. Thus, when this last
-task was submitted the resources will be move, but the context should
-still be deleted at some point of the application.
+All the tasks of the context should be executed before doing this. 
+Thus, the programmer may use either a barrier and then delete the context 
+directly, or just indicate
+that other tasks will not be submitted later on to the context (such that when 
+the last task is executed its workers will be moved to the inheritor)
+and delete the context at the end of the execution (when a barrier will
+be used eventually).
 
 \code{.c}
-/* when the context 2 will be deleted context 1 will be keep its resources */
+/* when the context 2 is deleted context 1 inherits its resources */
 starpu_sched_ctx_set_inheritor(sched_ctx2, sched_ctx1);
 
 /* submit tasks to context 2 */
@@ -98,7 +121,7 @@ for (i = 0; i < ntasks; i++)
 
 /* indicate that context 2 finished submitting and that */
 /* as soon as the last task of context 2 finished executing */
-/* its workers can be mobed to the inheritor context */
+/* its workers can be moved to the inheritor context */
 starpu_sched_ctx_finished_submit(sched_ctx1);
 
 /* wait for the tasks of both contexts to finish */
@@ -120,7 +143,7 @@ of tasks pending to be executed is kept and when workers are added to
 the contexts the tasks are submitted. However, if no resources are
 allocated the program will not terminate. If these tasks have not much
 priority the programmer can forbid the application to submitted them
-by calling the function starpu_sched_ctx_stop_task_submission().
+by calling the function <c>starpu_sched_ctx_stop_task_submission()</c>.
 
 \section ContextsSharingWorkers Contexts Sharing Workers
 
@@ -129,7 +152,7 @@ efficiently enough alone on these workers or when the application
 decides to express a hierarchy of contexts. The workers apply an
 alogrithm of ``Round-Robin'' to chose the context on which they will
 ``pop'' next. By using the function
-starpu_sched_ctx_set_turn_to_other_ctx(), the programmer can impose
+<c>starpu_sched_ctx_set_turn_to_other_ctx</c>, the programmer can impose
 the <c>workerid</c> to ``pop'' in the context <c>sched_ctx_id</c>
 next.
 

+ 1 - 1
sc_hypervisor/src/Makefile.am

@@ -37,7 +37,7 @@ libsc_hypervisor_la_SOURCES = 				\
 	hypervisor_policies/teft_lp_policy.c		\
 	hypervisor_policies/ispeed_policy.c		\
 	hypervisor_policies/ispeed_lp_policy.c		\
-	hypervisor_policies/debit_lp_policy.c
+	hypervisor_policies/throughput_lp_policy.c
 
 noinst_HEADERS = sc_hypervisor_intern.h		
 

+ 10 - 10
sc_hypervisor/src/hypervisor_policies/debit_lp_policy.c

@@ -282,7 +282,7 @@ static void _try_resizing(unsigned *sched_ctxs, int nsched_ctxs , int *workers,
 	}
 }
 
-static void debit_lp_handle_poped_task(__attribute__((unused))unsigned sched_ctx, __attribute__((unused))int worker, 
+static void throughput_lp_handle_poped_task(__attribute__((unused))unsigned sched_ctx, __attribute__((unused))int worker, 
 				       __attribute__((unused))struct starpu_task *task, __attribute__((unused))uint32_t footprint)
 {
 	int ret = starpu_pthread_mutex_trylock(&act_hypervisor_mutex);
@@ -300,7 +300,7 @@ static void debit_lp_handle_poped_task(__attribute__((unused))unsigned sched_ctx
 	}
 }
 
-static void debit_lp_handle_idle_cycle(unsigned sched_ctx, int worker)
+static void throughput_lp_handle_idle_cycle(unsigned sched_ctx, int worker)
 {
 	int ret = starpu_pthread_mutex_trylock(&act_hypervisor_mutex);
         if(ret != EBUSY)
@@ -319,7 +319,7 @@ static void debit_lp_handle_idle_cycle(unsigned sched_ctx, int worker)
         }
 }
 
-static void debit_lp_resize_ctxs(unsigned *sched_ctxs, int nsched_ctxs , int *workers, int nworkers)
+static void throughput_lp_resize_ctxs(unsigned *sched_ctxs, int nsched_ctxs , int *workers, int nworkers)
 {
 	int ret = starpu_pthread_mutex_trylock(&act_hypervisor_mutex);
 	if(ret != EBUSY)
@@ -329,7 +329,7 @@ static void debit_lp_resize_ctxs(unsigned *sched_ctxs, int nsched_ctxs , int *wo
 	}
 }
 
-static void debit_lp_end_ctx(__attribute__((unused))unsigned sched_ctx)
+static void throughput_lp_end_ctx(__attribute__((unused))unsigned sched_ctx)
 {
 /* 	struct sc_hypervisor_wrapper* sc_w = sc_hypervisor_get_wrapper(sched_ctx); */
 /* 	int worker; */
@@ -339,18 +339,18 @@ static void debit_lp_end_ctx(__attribute__((unused))unsigned sched_ctx)
 	return;
 }
 
-struct sc_hypervisor_policy debit_lp_policy = {
+struct sc_hypervisor_policy throughput_lp_policy = {
 	.size_ctxs = NULL,
-	.resize_ctxs = debit_lp_resize_ctxs,
-	.handle_poped_task = debit_lp_handle_poped_task,
+	.resize_ctxs = throughput_lp_resize_ctxs,
+	.handle_poped_task = throughput_lp_handle_poped_task,
 	.handle_pushed_task = NULL,
-	.handle_idle_cycle = debit_lp_handle_idle_cycle,
+	.handle_idle_cycle = throughput_lp_handle_idle_cycle,
 	.handle_idle_end = NULL,
 	.handle_post_exec_hook = NULL,
 	.handle_submitted_job = NULL,
-	.end_ctx = debit_lp_end_ctx,
+	.end_ctx = throughput_lp_end_ctx,
 	.custom = 0,
-	.name = "debit_lp"
+	.name = "throughput_lp"
 };
 
 #endif /* STARPU_HAVE_GLPK_H */

+ 25 - 12
sc_hypervisor/src/sc_hypervisor.c

@@ -38,7 +38,7 @@ extern struct sc_hypervisor_policy gflops_rate_policy;
 extern struct sc_hypervisor_policy feft_lp_policy;
 extern struct sc_hypervisor_policy teft_lp_policy;
 extern struct sc_hypervisor_policy ispeed_lp_policy;
-extern struct sc_hypervisor_policy debit_lp_policy;
+extern struct sc_hypervisor_policy throughput_lp_policy;
 #endif // STARPU_HAVE_GLPK_
 extern struct sc_hypervisor_policy ispeed_policy;
 
@@ -51,7 +51,7 @@ static struct sc_hypervisor_policy *predefined_policies[] =
 	&feft_lp_policy,
 	&teft_lp_policy,
 	&ispeed_lp_policy,
-	&debit_lp_policy,
+	&throughput_lp_policy,
 #endif // STARPU_HAVE_GLPK_H
 	&gflops_rate_policy,
 	&ispeed_policy
@@ -437,18 +437,26 @@ static void _reset_idle_time(unsigned sched_ctx)
 
 void _reset_resize_sample_info(unsigned sender_sched_ctx, unsigned receiver_sched_ctx)
 {
-	/* info concerning only the gflops_rate strateg */
-	struct sc_hypervisor_wrapper *sender_sc_w = &hypervisor.sched_ctx_w[sender_sched_ctx];
-	struct sc_hypervisor_wrapper *receiver_sc_w = &hypervisor.sched_ctx_w[receiver_sched_ctx];
-	
 	double start_time =  starpu_timing_now();
-	sender_sc_w->start_time = start_time;
-	_set_elapsed_flops_per_sched_ctx(sender_sched_ctx, 0.0);
-	_reset_idle_time(sender_sched_ctx);
+	if(sender_sched_ctx != STARPU_NMAX_SCHED_CTXS)
+	{
+		/* info concerning only the gflops_rate strateg */
+		struct sc_hypervisor_wrapper *sender_sc_w = &hypervisor.sched_ctx_w[sender_sched_ctx];
+		
+		sender_sc_w->start_time = start_time;
+		_set_elapsed_flops_per_sched_ctx(sender_sched_ctx, 0.0);
+		_reset_idle_time(sender_sched_ctx);
+	}
+
+	if(receiver_sched_ctx != STARPU_NMAX_SCHED_CTXS)
+	{
 
-	receiver_sc_w->start_time = start_time;
-	_set_elapsed_flops_per_sched_ctx(receiver_sched_ctx, 0.0);
-	_reset_idle_time(receiver_sched_ctx);
+		struct sc_hypervisor_wrapper *receiver_sc_w = &hypervisor.sched_ctx_w[receiver_sched_ctx];
+		
+		receiver_sc_w->start_time = start_time;
+		_set_elapsed_flops_per_sched_ctx(receiver_sched_ctx, 0.0);
+		_reset_idle_time(receiver_sched_ctx);
+	}
 }
 
 /* actually move the workers: the cpus are moved, gpus are only shared  */
@@ -527,6 +535,7 @@ void sc_hypervisor_add_workers_to_sched_ctx(int* workers_to_add, unsigned nworke
 		unsigned 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;
+		_reset_resize_sample_info(STARPU_NMAX_SCHED_CTXS, sched_ctx);
 
 	}
 	return;
@@ -554,6 +563,7 @@ void sc_hypervisor_remove_workers_from_sched_ctx(int* workers_to_remove, unsigne
 			printf("\n");
 			
 			starpu_sched_ctx_remove_workers(workers_to_remove, nworkers_to_remove, sched_ctx);
+			_reset_resize_sample_info(sched_ctx, STARPU_NMAX_SCHED_CTXS);
 		}
 		else
 		{
@@ -618,6 +628,7 @@ static unsigned _ack_resize_completed(unsigned sched_ctx, int worker)
 					if(sc_w->resize_ack.moved_workers[j] == worker)
 					{
 						only_remove = 1;
+						_reset_resize_sample_info(sched_ctx, STARPU_NMAX_SCHED_CTXS);
 						starpu_pthread_mutex_unlock(&sc_w->mutex);
 						break;
 					}
@@ -636,7 +647,9 @@ static unsigned _ack_resize_completed(unsigned sched_ctx, int worker)
 
 	/* if there is no ctx waiting for its ack return 1*/
 	if(resize_ack == NULL)
+	{
 		return 1;
+	}
 
 	int ret = starpu_pthread_mutex_trylock(&hypervisor.sched_ctx_w[sender_sched_ctx].mutex);
 	if(ret != EBUSY)

+ 1 - 1
src/core/workers.c

@@ -1102,7 +1102,7 @@ static void _starpu_terminate_workers(struct _starpu_machine_config *pconfig)
 
 out:
 		STARPU_ASSERT(starpu_task_list_empty(&worker->local_tasks));
-		_starpu_sched_ctx_list_delete(worker->sched_ctx_list);
+		_starpu_sched_ctx_list_delete(&worker->sched_ctx_list);
 		_starpu_job_list_delete(worker->terminated_jobs);
 	}
 }