From: Frederic Suter Date: Tue, 22 May 2012 08:42:28 +0000 (+0200) Subject: Add a new type of typed task that we may be able to autoschedule. X-Git-Tag: v3_8~700 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/1298f825dbd95a3e38a6f0f0130fc1800670aeae Add a new type of typed task that we may be able to autoschedule. SD_TASK_COMP_PAR_AMDAHL represents a parallel tasks whose initial work (amount parameter upon creation) is distributed among host according to the Amdahl's law. Such tasks are created with a parameter alpha that corresponds to the non-parallelizable part of the computation. Before calling SD_task_schedulel or SD_task_schedulev, the SD_task_distribute_comp_amdahl function has to be called with the desired number of workstations. The filling of computation_amount and communication_amount (actually empty) structures is then done seamlessly. Not sure whether SD_task_distribute_comp_amdahl should be automatically called within SD_task_schedulev or not. Easy to modify if we want to hide everything. An option could to call it if the user didn't do it. move all the creation functions at the same place in the process. --- diff --git a/include/simdag/datatypes.h b/include/simdag/datatypes.h index 6b77dfaa80..414c173873 100644 --- a/include/simdag/datatypes.h +++ b/include/simdag/datatypes.h @@ -82,7 +82,8 @@ typedef enum { typedef enum { SD_TASK_NOT_TYPED = 0, /**< @brief no specified type */ SD_TASK_COMM_E2E = 1, /**< @brief end to end communication */ - SD_TASK_COMP_SEQ = 2 /**< @brief sequential computation */ + SD_TASK_COMP_SEQ = 2, /**< @brief sequential computation */ + SD_TASK_COMP_PAR_AMDAHL = 3 /**< @brief parallel computation (Amdahl's law) */ } e_SD_task_kind_t; diff --git a/include/simdag/simdag.h b/include/simdag/simdag.h index 6dd9c2ec67..03121da610 100644 --- a/include/simdag/simdag.h +++ b/include/simdag/simdag.h @@ -157,8 +157,14 @@ XBT_PUBLIC(void) SD_task_dotty(SD_task_t task, void *out_FILE); XBT_PUBLIC(SD_task_t) SD_task_create_comp_seq(const char *name, void *data, double amount); +XBT_PUBLIC(SD_task_t) SD_task_create_comp_par_amdahl(const char *name, + void *data, + double amount, + double alpha); XBT_PUBLIC(SD_task_t) SD_task_create_comm_e2e(const char *name, void *data, double amount); + +XBT_PUBLIC(void) SD_task_distribute_comp_amdhal(SD_task_t task, int ws_count); XBT_PUBLIC(void) SD_task_schedulev(SD_task_t task, int count, const SD_workstation_t * list); XBT_PUBLIC(void) SD_task_schedulel(SD_task_t task, int count, ...); diff --git a/src/simdag/private.h b/src/simdag/private.h index 61ba759bbb..cd16f944fd 100644 --- a/src/simdag/private.h +++ b/src/simdag/private.h @@ -75,6 +75,7 @@ typedef struct SD_task { char *name; int kind; double amount; + double alpha; /* used by typed parallel tasks */ double remains; double start_time; double finish_time; diff --git a/src/simdag/sd_task.c b/src/simdag/sd_task.c index 9fd8b60598..e3ab77080a 100644 --- a/src/simdag/sd_task.c +++ b/src/simdag/sd_task.c @@ -97,6 +97,91 @@ SD_task_t SD_task_create(const char *name, void *data, double amount) return task; } +static XBT_INLINE SD_task_t SD_task_create_sized(const char *name, + void *data, double amount, + int ws_count) +{ + SD_task_t task = SD_task_create(name, data, amount); + task->communication_amount = xbt_new0(double, ws_count * ws_count); + task->computation_amount = xbt_new0(double, ws_count); + task->workstation_nb = ws_count; + task->workstation_list = xbt_new0(SD_workstation_t, ws_count); + return task; +} + +/** @brief create a end-to-end communication task that can then be auto-scheduled + * + * Auto-scheduling mean that the task can be used with SD_task_schedulev(). This + * allows to specify the task costs at creation, and decouple them from the + * scheduling process where you just specify which resource should deliver the + * mandatory power. + * + * A end-to-end communication must be scheduled on 2 hosts, and the amount + * specified at creation is sent from hosts[0] to hosts[1]. + */ +SD_task_t SD_task_create_comm_e2e(const char *name, void *data, + double amount) +{ + SD_task_t res = SD_task_create_sized(name, data, amount, 2); + res->communication_amount[2] = amount; + res->kind = SD_TASK_COMM_E2E; + return res; +} + +/** @brief create a sequential computation task that can then be auto-scheduled + * + * Auto-scheduling mean that the task can be used with SD_task_schedulev(). This + * allows to specify the task costs at creation, and decouple them from the + * scheduling process where you just specify which resource should deliver the + * mandatory power. + * + * A sequential computation must be scheduled on 1 host, and the amount + * specified at creation to be run on hosts[0]. + * + * \param name the name of the task (can be \c NULL) + * \param data the user data you want to associate with the task (can be \c NULL) + * \param amount amount of compute work to be done by the task + * \return the new SD_TASK_COMP_SEQ typed task + */ +SD_task_t SD_task_create_comp_seq(const char *name, void *data, + double amount) +{ + SD_task_t res = SD_task_create_sized(name, data, amount, 1); + res->computation_amount[0] = amount; + res->kind = SD_TASK_COMP_SEQ; + return res; +} + +/** @brief create a parallel computation task that can then be auto-scheduled + * + * Auto-scheduling mean that the task can be used with SD_task_schedulev(). This + * allows to specify the task costs at creation, and decouple them from the + * scheduling process where you just specify which resource should deliver the + * mandatory power. + * + * A parallel computation can be scheduled on any number of host. + * The underlying speedup model is Amdahl's law. + * To be auto-scheduled, \see SD_task_distribute_comp_amdhal has to be called + * first. + * \param name the name of the task (can be \c NULL) + * \param data the user data you want to associate with the task (can be \c NULL) + * \param amount amount of compute work to be done by the task + * \param purely serial fraction of the work to be done (in [0.;1.[) + * \return the new task + */ +SD_task_t SD_task_create_comp_par_amdahl(const char *name, void *data, + double amount, double alpha) +{ + xbt_assert(alpha < 1. && alpha >= 0., + "Invalid parameter: alpha must be in [0.;1.["); + + SD_task_t res = SD_task_create(name, data, amount); + res->alpha = alpha; + res->kind = SD_TASK_COMP_PAR_AMDAHL; + return res; +} + + /** * \brief Destroys a task. * @@ -367,6 +452,9 @@ void SD_task_dump(SD_task_t task) case SD_TASK_COMP_SEQ: XBT_INFO(" - kind: sequential computation"); break; + case SD_TASK_COMP_PAR_AMDAHL: + XBT_INFO(" - kind: parallel computation following Amdahl's law"); + break; default: XBT_INFO(" - (unknown kind %d)", task->kind); } @@ -963,7 +1051,7 @@ void __SD_task_really_run(SD_task_t task) surf_workstations, computation_amount, communication_amount, - task->amount, task->rate); + task->rate); } else { xbt_free(surf_workstations); } @@ -1236,56 +1324,27 @@ double SD_task_get_finish_time(SD_task_t task) else return task->finish_time; } - -static XBT_INLINE SD_task_t SD_task_create_sized(const char *name, - void *data, double amount, - int ws_count) +/** @brief Blah + * + */ +void SD_task_distribute_comp_amdhal(SD_task_t task, int ws_count) { - SD_task_t task = SD_task_create(name, data, amount); - task->communication_amount = xbt_new0(double, ws_count * ws_count); + int i; + xbt_assert(task->kind == SD_TASK_COMP_PAR_AMDAHL, + "Task %s is not a SD_TASK_COMP_PAR_AMDAHL typed task." + "Cannot use this function.", + SD_task_get_name(task)); + task->computation_amount = xbt_new0(double, ws_count); + task->communication_amount = xbt_new0(double, ws_count * ws_count); task->workstation_nb = ws_count; task->workstation_list = xbt_new0(SD_workstation_t, ws_count); - return task; -} - -/** @brief create a end-to-end communication task that can then be auto-scheduled - * - * Auto-scheduling mean that the task can be used with SD_task_schedulev(). This - * allows to specify the task costs at creation, and decorelate them from the - * scheduling process where you just specify which resource should deliver the - * mandatory power. - * - * A end-to-end communication must be scheduled on 2 hosts, and the amount - * specified at creation is sent from hosts[0] to hosts[1]. - */ -SD_task_t SD_task_create_comm_e2e(const char *name, void *data, - double amount) -{ - SD_task_t res = SD_task_create_sized(name, data, amount, 2); - res->communication_amount[2] = amount; - res->kind = SD_TASK_COMM_E2E; - return res; -} - -/** @brief create a sequential computation task that can then be auto-scheduled - * - * Auto-scheduling mean that the task can be used with SD_task_schedulev(). This - * allows to specify the task costs at creation, and decorelate them from the - * scheduling process where you just specify which resource should deliver the - * mandatory power. - * - * A sequential computation must be scheduled on 1 host, and the amount - * specified at creation to be run on hosts[0]. - */ -SD_task_t SD_task_create_comp_seq(const char *name, void *data, - double amount) -{ - SD_task_t res = SD_task_create_sized(name, data, amount, 1); - res->computation_amount[0] = amount; - res->kind = SD_TASK_COMP_SEQ; - return res; -} + + for(i=0;icomputation_amount[i] = + (task->alpha + (1 - task->alpha)/ws_count) * task->amount; + } +} /** @brief Auto-schedules a task. * @@ -1317,6 +1376,8 @@ void SD_task_schedulev(SD_task_t task, int count, SD_task_get_name(task)); switch (task->kind) { case SD_TASK_COMM_E2E: + case SD_TASK_COMP_PAR_AMDAHL: + xbt_assert(task->computation_amount, "SD_task_distribute_comp_amdhal should be called first."); case SD_TASK_COMP_SEQ: xbt_assert(task->workstation_nb == count,"Got %d locations, but were expecting %d locations",count,task->workstation_nb); for (i = 0; i < count; i++) @@ -1335,6 +1396,13 @@ void SD_task_schedulev(SD_task_t task, int count, task->communication_amount[2]); } + if (task->kind == SD_TASK_COMP_PAR_AMDAHL) { + XBT_VERB("Schedule computation task %s on %d hosts. It costs %.f flops on each host", + SD_task_get_name(task), + task->workstation_nb, + task->computation_amount[0]); + } + /* Iterate over all childs and parent being COMM_E2E to say where I am located (and start them if runnable) */ if (task->kind == SD_TASK_COMP_SEQ) { XBT_VERB("Schedule computation task %s on %s. It costs %.f flops",