From: mquinson Date: Tue, 6 Oct 2009 16:58:13 +0000 (+0000) Subject: Introduce typed tasks in SimDag X-Git-Tag: SVN~988 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/b4cdae298b5a8f436f8c3ddf4c761529603df71a Introduce typed tasks in SimDag - Specify its kind and cost at creation. - At scheduling, just give where it should be placed, and the cost for each involved resource is automatically computed. - Existing constructors so far (more to come of course): - SD_task_create_comm_e2e() for end-to-end communication - SD_task_create_comp_seq() for sequential computation - Use SD_task_schedulev() / SD_task_schedulel() to schedule them. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@6725 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- diff --git a/ChangeLog b/ChangeLog index cd5d1e27db..1cf92b9d80 100644 --- a/ChangeLog +++ b/ChangeLog @@ -60,6 +60,13 @@ SimGrid (3.3.4) unstable; urgency=low * SD_task_dependency_exists() can now cope with having one of its arguments NULL. If so, it tests whether the other argument has any dependency. + * Introduce typed tasks. Specify its kind and cost at creation. + At scheduling, just give where it should be placed, and the cost + for each involved resource is automatically computed. + Existing constructors so far (more to come of course): + - SD_task_create_comm_e2e() for end-to-end communication + - SD_task_create_comp_seq() for sequential computation + Use SD_task_schedulev() / SD_task_schedulel() to schedule them. Bug fixes: * GTNetS wrappers should now be usable again (and betterly tested too) diff --git a/include/simdag/datatypes.h b/include/simdag/datatypes.h index 39a49b7115..8ea69f6dae 100644 --- a/include/simdag/datatypes.h +++ b/include/simdag/datatypes.h @@ -68,4 +68,15 @@ typedef enum { SD_FAILED = 0x0020 /**< @brief A problem occured during the execution of the task. */ } e_SD_task_state_t; +/** @brief Task kinds + @ingroup SD_datatypes_management + + @see SD_task_management */ +typedef enum { + /* leave 0 for "not typed" */ + SD_TASK_COMM_E2E = 1, /**< @brief end to end communication */ + SD_TASK_COMP_SEQ = 2, /**< @brief sequential computation */ +} e_SD_task_kind_t; + + #endif diff --git a/include/simdag/simdag.h b/include/simdag/simdag.h index cce7badfff..9b6d259f5b 100644 --- a/include/simdag/simdag.h +++ b/include/simdag/simdag.h @@ -135,6 +135,11 @@ XBT_PUBLIC(double) SD_task_get_finish_time(SD_task_t task); XBT_PUBLIC(void) SD_task_destroy(SD_task_t task); XBT_PUBLIC(void) SD_task_dump(SD_task_t task); +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_comm_e2e(const char*name,void *data,double amount); +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 4cc0513503..d935fd52fd 100644 --- a/src/simdag/private.h +++ b/src/simdag/private.h @@ -72,6 +72,7 @@ typedef struct SD_task { e_SD_task_state_t state; void *data; /* user data */ char *name; + int kind; double amount; double remains; double start_time; diff --git a/src/simdag/sd_task.c b/src/simdag/sd_task.c index 31bdac9345..901e8f0010 100644 --- a/src/simdag/sd_task.c +++ b/src/simdag/sd_task.c @@ -33,11 +33,8 @@ SD_task_t SD_task_create(const char *name, void *data, double amount) /* general information */ task->data = data; /* user data */ - if (name != NULL) - task->name = xbt_strdup(name); - else - task->name = NULL; - + task->name = xbt_strdup(name); + task->kind = 0; task->state_hookup.prev = NULL; task->state_hookup.next = NULL; task->state_set = sd_global->not_scheduled_task_set; @@ -1056,3 +1053,98 @@ void SD_task_destroy(SD_task_t task) DEBUG0("Task destroyed."); } + + +/** @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(name,data,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(name,data,amount); + res->kind=SD_TASK_COMP_SEQ; + return res; +} + +/** @brief Auto-schedules a task. + * + * 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. + * + * To be auto-schedulable, a task must be created with SD_task_create_comm_e2e() or + * SD_task_create_comp_seq(). Check their definitions for the exact semantic of each + * of them. + * + * @todo + * We should create tasks kind for the following categories: + * - Point to point communication (done) + * - Sequential computation (done) + * - group communication (redistribution, several kinds) + * - parallel tasks with no internal communication (one kind per speedup model such as amdal) + * - idem+ internal communication. Task type not enough since we cannot store comm cost alongside to comp one) + */ +void SD_task_schedulev(SD_task_t task, int count, const SD_workstation_t*list) { + xbt_assert1(task->kind != 0,"Task %s is not typed. Cannot automatically schedule it.",SD_task_get_name(task)); + double *comp,*comms; + switch(task->kind) { + case SD_TASK_COMM_E2E: + xbt_assert2(count == 2, + "Task %s is end to end communication, but scheduled with %d hosts", + SD_task_get_name(task),count); + comms=xbt_new(double,count); + comms[0]=0; + comms[1]=SD_task_get_amount(task); + SD_task_schedule(task,count,list,NULL,comms,1); + break; + case SD_TASK_COMP_SEQ: + xbt_assert2(count==1, + "Task %s is sequential computation, but scheduled with %d hosts", + SD_task_get_name(task),count); + comp=xbt_new(double,count); + comp[0]=SD_task_get_amount(task); + SD_task_schedule(task,count,list,comp,NULL,1); + break; + default: + xbt_die(bprintf("Kind of task %s not supported by SD_task_schedulev()", + SD_task_get_name(task))); + } +} +/** @brief autoschedule a task on a list of workstations + * + * This function is very similar to SD_task_schedulev(), + * but takes the list of workstations to schedule onto as separate parameters. + * It builds a proper vector of workstations and then call SD_task_schedulev() + */ +void SD_task_schedulel(SD_task_t task, int count, ...) { + va_list ap; + SD_workstation_t *list=xbt_new(SD_workstation_t,count); + int i; + va_start(ap,count); + for (i=0;i