+/** @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)
+{
+ int i, j;
+ SD_dependency_t dep;
+ unsigned int cpt;
+ xbt_assert(task->kind != 0,
+ "Task %s is not typed. Cannot automatically schedule it.",
+ SD_task_get_name(task));
+ switch (task->kind) {
+ case SD_TASK_COMP_PAR_AMDAHL:
+ SD_task_distribute_comp_amdhal(task, count);
+ case SD_TASK_COMM_E2E:
+ 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++)
+ task->workstation_list[i] = list[i];
+ SD_task_do_schedule(task);
+ break;
+ default:
+ xbt_die("Kind of task %s not supported by SD_task_schedulev()",
+ SD_task_get_name(task));
+ }
+ if (task->kind == SD_TASK_COMM_E2E) {
+ XBT_VERB("Schedule comm task %s between %s -> %s. It costs %.f bytes",
+ SD_task_get_name(task),
+ SD_workstation_get_name(task->workstation_list[0]),
+ SD_workstation_get_name(task->workstation_list[1]),
+ task->communication_amount[2]);
+
+ }
+
+ /* 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",
+ SD_task_get_name(task),
+ SD_workstation_get_name(task->workstation_list[0]),
+ task->computation_amount[0]);
+
+ xbt_dynar_foreach(task->tasks_before, cpt, dep) {
+ SD_task_t before = dep->src;
+ if (before->kind == SD_TASK_COMM_E2E) {
+ before->workstation_list[1] = task->workstation_list[0];
+
+ if (before->workstation_list[0] &&
+ (__SD_task_is_schedulable(before)
+ || __SD_task_is_not_scheduled(before))) {
+ SD_task_do_schedule(before);
+ XBT_VERB
+ ("Auto-Schedule comm task %s between %s -> %s. It costs %.f bytes",
+ SD_task_get_name(before),
+ SD_workstation_get_name(before->workstation_list[0]),
+ SD_workstation_get_name(before->workstation_list[1]),
+ before->communication_amount[2]);
+ }
+ }
+ }
+ xbt_dynar_foreach(task->tasks_after, cpt, dep) {
+ SD_task_t after = dep->dst;
+ if (after->kind == SD_TASK_COMM_E2E) {
+ after->workstation_list[0] = task->workstation_list[0];
+ if (after->workstation_list[1]
+ && (__SD_task_is_not_scheduled(after)
+ || __SD_task_is_schedulable(after))) {
+ SD_task_do_schedule(after);
+ XBT_VERB
+ ("Auto-Schedule comm task %s between %s -> %s. It costs %.f bytes",
+ SD_task_get_name(after),
+ SD_workstation_get_name(after->workstation_list[0]),
+ SD_workstation_get_name(after->workstation_list[1]),
+ after->communication_amount[2]);
+
+ }
+ }
+ }
+ }
+ /* Iterate over all childs and parent being MXN_1D_BLOC to say where I am located (and start them if runnable) */
+ if (task->kind == SD_TASK_COMP_PAR_AMDAHL) {
+ XBT_VERB("Schedule computation task %s on %d workstations. %.f flops"
+ " will be distributed following Amdahl'Law",
+ SD_task_get_name(task), task->workstation_nb,
+ task->computation_amount[0]);
+ xbt_dynar_foreach(task->tasks_before, cpt, dep) {
+ SD_task_t before = dep->src;
+ if (before->kind == SD_TASK_COMM_PAR_MXN_1D_BLOCK){
+ if (!before->workstation_list){
+ XBT_VERB("Sender side of Task %s is not scheduled yet. Fill the workstation list with receiver side",
+ SD_task_get_name(before));
+ before->workstation_list = xbt_new0(SD_workstation_t, count);
+ before->workstation_nb = count;
+ for (i=0;i<count;i++)
+ before->workstation_list[i] = task->workstation_list[i];
+ } else {
+ int src_nb, dst_nb;
+ double src_start, src_end, dst_start, dst_end;
+ src_nb = before->workstation_nb;
+ dst_nb = count;
+ before->workstation_list = (SD_workstation_t*) xbt_realloc(
+ before->workstation_list,
+ (before->workstation_nb+count)*sizeof(s_SD_workstation_t));
+ for(i=0; i<count; i++)
+ before->workstation_list[before->workstation_nb+i] =
+ task->workstation_list[i];
+
+ before->workstation_nb += count;