X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/cc01c6a871dbbfd0cc84e26eb9f94aeb539e613e..2dbe1bde3beee5e4e7102c336ad1533b6d367033:/examples/simdag/scheduling/minmin_test.c diff --git a/examples/simdag/scheduling/minmin_test.c b/examples/simdag/scheduling/minmin_test.c index 7fb1ccab51..2d60522fe1 100644 --- a/examples/simdag/scheduling/minmin_test.c +++ b/examples/simdag/scheduling/minmin_test.c @@ -1,6 +1,6 @@ /* simple test to schedule a DAX file with the Min-Min algorithm. */ -/* Copyright (c) 2009, 2010. The SimGrid Team. +/* Copyright (c) 2009-2015. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -8,7 +8,7 @@ #include #include -#include "simdag/simdag.h" +#include "simgrid/simdag.h" #include "xbt/log.h" #include "xbt/ex.h" #include @@ -18,8 +18,9 @@ XBT_LOG_NEW_DEFAULT_CATEGORY(test, typedef struct _WorkstationAttribute *WorkstationAttribute; struct _WorkstationAttribute { - /* Earliest time at wich a workstation is ready to execute a task */ + /* Earliest time at which a workstation is ready to execute a task */ double available_at; + SD_task_t last_scheduled_task; }; static void SD_workstation_allocate_attribute(SD_workstation_t workstation) @@ -51,6 +52,19 @@ static void SD_workstation_set_available_at(SD_workstation_t workstation, SD_workstation_set_data(workstation, attr); } +static SD_task_t SD_workstation_get_last_scheduled_task( SD_workstation_t workstation){ + WorkstationAttribute attr = + (WorkstationAttribute) SD_workstation_get_data(workstation); + return attr->last_scheduled_task; +} + +static void SD_workstation_set_last_scheduled_task(SD_workstation_t workstation, + SD_task_t task){ + WorkstationAttribute attr = + (WorkstationAttribute) SD_workstation_get_data(workstation); + attr->last_scheduled_task=task; + SD_workstation_set_data(workstation, attr); +} static xbt_dynar_t get_ready_tasks(xbt_dynar_t dax) { @@ -65,13 +79,14 @@ static xbt_dynar_t get_ready_tasks(xbt_dynar_t dax) xbt_dynar_push(ready_tasks, &task); } } - DEBUG1("There are %lu ready tasks", xbt_dynar_length(ready_tasks)); + XBT_DEBUG("There are %lu ready tasks", xbt_dynar_length(ready_tasks)); return ready_tasks; } static double finish_on_at(SD_task_t task, SD_workstation_t workstation) { + volatile double result; unsigned int i; double data_available = 0.; double redist_time = 0; @@ -79,12 +94,11 @@ static double finish_on_at(SD_task_t task, SD_workstation_t workstation) SD_task_t parent, grand_parent; xbt_dynar_t parents, grand_parents; - int grand_parent_nworkstations; SD_workstation_t *grand_parent_workstation_list; parents = SD_task_get_parents(task); - if (xbt_dynar_length(parents)) { + if (!xbt_dynar_is_empty(parents)) { /* compute last_data_available */ last_data_available = -1.0; xbt_dynar_foreach(parents, i, parent) { @@ -94,13 +108,11 @@ static double finish_on_at(SD_task_t task, SD_workstation_t workstation) grand_parents = SD_task_get_parents(parent); if (xbt_dynar_length(grand_parents) > 1) { - ERROR1("Warning: transfer %s has 2 parents", + XBT_ERROR("Warning: transfer %s has 2 parents", SD_task_get_name(parent)); } xbt_dynar_get_cpy(grand_parents, 0, &grand_parent); - grand_parent_nworkstations = - SD_task_get_workstation_count(grand_parent); grand_parent_workstation_list = SD_task_get_workstation_list(grand_parent); /* Estimate the redistribution time from this parent */ @@ -126,17 +138,18 @@ static double finish_on_at(SD_task_t task, SD_workstation_t workstation) xbt_dynar_free_container(&parents); - return MAX(SD_workstation_get_available_at(workstation), + result = MAX(SD_workstation_get_available_at(workstation), last_data_available) + SD_workstation_get_computation_time(workstation, SD_task_get_amount(task)); } else { xbt_dynar_free_container(&parents); - return SD_workstation_get_available_at(workstation) + + result = SD_workstation_get_available_at(workstation) + SD_workstation_get_computation_time(workstation, SD_task_get_amount(task)); } + return result; } static SD_workstation_t SD_task_get_best_workstation(SD_task_t task) @@ -144,7 +157,7 @@ static SD_workstation_t SD_task_get_best_workstation(SD_task_t task) int i; double EFT, min_EFT = -1.0; const SD_workstation_t *workstations = SD_workstation_get_list(); - int nworkstations = SD_workstation_get_number(); + int nworkstations = SD_workstation_get_count(); SD_workstation_t best_workstation; best_workstation = workstations[0]; @@ -152,7 +165,7 @@ static SD_workstation_t SD_task_get_best_workstation(SD_task_t task) for (i = 1; i < nworkstations; i++) { EFT = finish_on_at(task, workstations[i]); - DEBUG3("%s finishes on %s at %f", + XBT_DEBUG("%s finishes on %s at %f", SD_task_get_name(task), SD_workstation_get_name(workstations[i]), EFT); @@ -169,7 +182,7 @@ static void output_xml(FILE * out, xbt_dynar_t dax) { unsigned int i, j, k; int current_nworkstations; - const int nworkstations = SD_workstation_get_number(); + const int nworkstations = SD_workstation_get_count(); const SD_workstation_t *workstations = SD_workstation_get_list(); SD_task_t task; SD_workstation_t *list; @@ -234,14 +247,14 @@ static void output_xml(FILE * out, xbt_dynar_t dax) int main(int argc, char **argv) { - unsigned int cursor, selected_idx = 0; + unsigned int cursor; double finish_time, min_finish_time = -1.0; - SD_task_t task, selected_task = NULL; + SD_task_t task, selected_task = NULL, last_scheduled_task; xbt_dynar_t ready_tasks; SD_workstation_t workstation, selected_workstation = NULL; int total_nworkstations = 0; const SD_workstation_t *workstations = NULL; - xbt_dynar_t dax, changed; + xbt_dynar_t dax; FILE *out = NULL; /* initialization of SD */ @@ -249,8 +262,8 @@ int main(int argc, char **argv) /* Check our arguments */ if (argc < 3) { - INFO1("Usage: %s platform_file dax_file [jedule_file]", argv[0]); - INFO1 + XBT_INFO("Usage: %s platform_file dax_file [jedule_file]", argv[0]); + XBT_INFO ("example: %s simulacrum_7_hosts.xml Montage_25.xml Montage_25.jed", argv[0]); exit(1); @@ -271,7 +284,7 @@ int main(int argc, char **argv) SD_create_environment(argv[1]); /* Allocating the workstation attribute */ - total_nworkstations = SD_workstation_get_number(); + total_nworkstations = SD_workstation_get_count(); workstations = SD_workstation_get_list(); for (cursor = 0; cursor < total_nworkstations; cursor++) @@ -290,12 +303,11 @@ int main(int argc, char **argv) workstation = SD_task_get_best_workstation(task); SD_task_schedulel(task, 1, workstation); - while (!xbt_dynar_is_empty((changed = SD_simulate(-1.0)))) { + while (!xbt_dynar_is_empty(SD_simulate(-1.0))) { /* Get the set of ready tasks */ ready_tasks = get_ready_tasks(dax); - if (!xbt_dynar_length(ready_tasks)) { + if (xbt_dynar_is_empty(ready_tasks)) { xbt_dynar_free_container(&ready_tasks); - xbt_dynar_free_container(&changed); /* there is no ready task, let advance the simulation */ continue; } @@ -305,39 +317,62 @@ int main(int argc, char **argv) * its best workstation. */ xbt_dynar_foreach(ready_tasks, cursor, task) { - DEBUG1("%s is ready", SD_task_get_name(task)); + XBT_DEBUG("%s is ready", SD_task_get_name(task)); workstation = SD_task_get_best_workstation(task); finish_time = finish_on_at(task, workstation); if (min_finish_time == -1. || finish_time < min_finish_time) { min_finish_time = finish_time; selected_task = task; selected_workstation = workstation; - selected_idx = cursor; } } - INFO2("Schedule %s on %s", SD_task_get_name(selected_task), + XBT_INFO("Schedule %s on %s", SD_task_get_name(selected_task), SD_workstation_get_name(selected_workstation)); SD_task_schedulel(selected_task, 1, selected_workstation); + + /* + * SimDag allows tasks to be executed concurrently when they can by default. + * Yet schedulers take decisions assuming that tasks wait for resource + * availability to start. + * The solution (well crude hack is to keep track of the last task scheduled + * on a workstation and add a special type of dependency if needed to + * force the sequential execution meant by the scheduler. + * If the last scheduled task is already done, has failed or is a + * predecessor of the current task, no need for a new dependency + */ + + last_scheduled_task = + SD_workstation_get_last_scheduled_task(selected_workstation); + if (last_scheduled_task && + (SD_task_get_state(last_scheduled_task) != SD_DONE) && + (SD_task_get_state(last_scheduled_task) != SD_FAILED) && + !SD_task_dependency_exists( + SD_workstation_get_last_scheduled_task(selected_workstation), + selected_task)) + SD_task_dependency_add("resource", NULL, + last_scheduled_task, selected_task); + + SD_workstation_set_last_scheduled_task(selected_workstation, selected_task); + SD_workstation_set_available_at(selected_workstation, min_finish_time); xbt_dynar_free_container(&ready_tasks); /* reset the min_finish_time for the next set of ready tasks */ min_finish_time = -1.; - xbt_dynar_free_container(&changed); } - INFO1("Simulation Time: %f", SD_get_clock()); + XBT_INFO("Simulation Time: %f", SD_get_clock()); - INFO0 + XBT_INFO ("------------------- Produce the trace file---------------------------"); - INFO1("Producing the trace of the run into %s", tracefilename); + XBT_INFO("Producing the trace of the run into %s", tracefilename); out = fopen(tracefilename, "w"); - xbt_assert1(out, "Cannot write to %s", tracefilename); + xbt_assert(out, "Cannot write to %s", tracefilename); free(tracefilename); output_xml(out, dax); @@ -346,11 +381,11 @@ int main(int argc, char **argv) xbt_dynar_free_container(&ready_tasks); - xbt_dynar_free_container(&changed); xbt_dynar_foreach(dax, cursor, task) { SD_task_destroy(task); } + xbt_dynar_free_container(&dax); for (cursor = 0; cursor < total_nworkstations; cursor++) SD_workstation_free_attribute(workstations[cursor]);