X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/2f810149832a2d855c33d0df5b02d736c2081e41..c3b30399c645e6d05d67a2cb03e8432958bc11b9:/examples/simdag/scheduling/minmin_test.c diff --git a/examples/simdag/scheduling/minmin_test.c b/examples/simdag/scheduling/minmin_test.c index 3a0788d18f..de62a15e5f 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,49 +8,67 @@ #include #include -#include "simdag/simdag.h" +#include "simgrid/simdag.h" #include "xbt/log.h" #include "xbt/ex.h" #include +#ifdef HAVE_JEDULE +#include "simgrid/jedule/jedule_sd_binding.h" +#endif + XBT_LOG_NEW_DEFAULT_CATEGORY(test, "Logging specific to this SimDag example"); 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) +static void sg_host_allocate_attribute(sg_host_t workstation) { void *data; data = calloc(1, sizeof(struct _WorkstationAttribute)); - SD_workstation_set_data(workstation, data); + sg_host_user_set(workstation, data); } -static void SD_workstation_free_attribute(SD_workstation_t workstation) +static void sg_host_free_attribute(sg_host_t workstation) { - free(SD_workstation_get_data(workstation)); - SD_workstation_set_data(workstation, NULL); + free(sg_host_user(workstation)); + sg_host_user_set(workstation, NULL); } -static double SD_workstation_get_available_at(SD_workstation_t workstation) +static double sg_host_get_available_at(sg_host_t workstation) { WorkstationAttribute attr = - (WorkstationAttribute) SD_workstation_get_data(workstation); + (WorkstationAttribute) sg_host_user(workstation); return attr->available_at; } -static void SD_workstation_set_available_at(SD_workstation_t workstation, +static void sg_host_set_available_at(sg_host_t workstation, double time) { WorkstationAttribute attr = - (WorkstationAttribute) SD_workstation_get_data(workstation); + (WorkstationAttribute) sg_host_user(workstation); attr->available_at = time; - SD_workstation_set_data(workstation, attr); + sg_host_user_set(workstation, attr); +} + +static SD_task_t sg_host_get_last_scheduled_task( sg_host_t workstation){ + WorkstationAttribute attr = + (WorkstationAttribute) sg_host_user(workstation); + return attr->last_scheduled_task; } +static void sg_host_set_last_scheduled_task(sg_host_t workstation, + SD_task_t task){ + WorkstationAttribute attr = + (WorkstationAttribute) sg_host_user(workstation); + attr->last_scheduled_task=task; + sg_host_user_set(workstation, attr); +} static xbt_dynar_t get_ready_tasks(xbt_dynar_t dax) { @@ -70,7 +88,7 @@ static xbt_dynar_t get_ready_tasks(xbt_dynar_t dax) return ready_tasks; } -static double finish_on_at(SD_task_t task, SD_workstation_t workstation) +static double finish_on_at(SD_task_t task, sg_host_t workstation) { volatile double result; unsigned int i; @@ -80,7 +98,7 @@ 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; - SD_workstation_t *grand_parent_workstation_list; + sg_host_t *grand_parent_workstation_list; parents = SD_task_get_parents(task); @@ -93,19 +111,25 @@ static double finish_on_at(SD_task_t task, SD_workstation_t workstation) if (SD_task_get_kind(parent) == SD_TASK_COMM_E2E) { grand_parents = SD_task_get_parents(parent); - if (xbt_dynar_length(grand_parents) > 1) { - XBT_ERROR("Warning: transfer %s has 2 parents", - SD_task_get_name(parent)); - } + xbt_assert(xbt_dynar_length(grand_parents) <2, + "Error: transfer %s has 2 parents", + SD_task_get_name(parent)); + xbt_dynar_get_cpy(grand_parents, 0, &grand_parent); grand_parent_workstation_list = SD_task_get_workstation_list(grand_parent); /* Estimate the redistribution time from this parent */ - redist_time = - SD_route_get_communication_time(grand_parent_workstation_list - [0], workstation, - SD_task_get_amount(parent)); + if (SD_task_get_amount(parent) == 0){ + redist_time= 0; + } else { + redist_time = + SD_route_get_latency(grand_parent_workstation_list[0], + workstation) + + SD_task_get_amount(parent) / + SD_route_get_bandwidth(grand_parent_workstation_list[0], + workstation); + } data_available = SD_task_get_finish_time(grand_parent) + redist_time; @@ -124,27 +148,25 @@ static double finish_on_at(SD_task_t task, SD_workstation_t workstation) xbt_dynar_free_container(&parents); - result = MAX(SD_workstation_get_available_at(workstation), + result = MAX(sg_host_get_available_at(workstation), last_data_available) + - SD_workstation_get_computation_time(workstation, - SD_task_get_amount(task)); + SD_task_get_amount(task)/sg_host_speed(workstation); } else { xbt_dynar_free_container(&parents); - result = SD_workstation_get_available_at(workstation) + - SD_workstation_get_computation_time(workstation, - SD_task_get_amount(task)); + result = sg_host_get_available_at(workstation) + + SD_task_get_amount(task)/sg_host_speed(workstation); } return result; } -static SD_workstation_t SD_task_get_best_workstation(SD_task_t task) +static sg_host_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(); - SD_workstation_t best_workstation; + const sg_host_t *workstations = sg_host_list(); + int nworkstations = sg_host_count(); + sg_host_t best_workstation; best_workstation = workstations[0]; min_EFT = finish_on_at(task, workstations[0]); @@ -153,7 +175,7 @@ static SD_workstation_t SD_task_get_best_workstation(SD_task_t task) EFT = finish_on_at(task, workstations[i]); XBT_DEBUG("%s finishes on %s at %f", SD_task_get_name(task), - SD_workstation_get_name(workstations[i]), EFT); + sg_host_get_name(workstations[i]), EFT); if (EFT < min_EFT) { min_EFT = EFT; @@ -164,117 +186,37 @@ static SD_workstation_t SD_task_get_best_workstation(SD_task_t task) return best_workstation; } -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 SD_workstation_t *workstations = SD_workstation_get_list(); - SD_task_t task; - SD_workstation_t *list; - - fprintf(out, "\n"); - fprintf(out, "\n"); - fprintf(out, " \n"); - fprintf(out, " \n"); - fprintf(out, " \n"); - fprintf(out, - " \n", - nworkstations); - fprintf(out, " \n"); - fprintf(out, " \n"); - fprintf(out, " \n"); - - xbt_dynar_foreach(dax, i, task) { - fprintf(out, " \n"); - fprintf(out, " \n", - SD_task_get_name(task)); - fprintf(out, " \n"); - if (SD_task_get_kind(task) == SD_TASK_COMM_E2E) - fprintf(out, "transfer\"/>\n"); - - fprintf(out, - " \n", - SD_task_get_start_time(task)); - fprintf(out, - " \n", - SD_task_get_finish_time(task)); - fprintf(out, " \n"); - - current_nworkstations = SD_task_get_workstation_count(task); - - fprintf(out, - " \n", - current_nworkstations); - - fprintf(out, " \n"); - list = SD_task_get_workstation_list(task); - for (j = 0; j < current_nworkstations; j++) { - for (k = 0; k < nworkstations; k++) { - if (!strcmp(SD_workstation_get_name(workstations[k]), - SD_workstation_get_name(list[j]))) { - fprintf(out, " \n", - k); - fprintf(out, - " \n"); - break; - } - } - } - fprintf(out, " \n"); - fprintf(out, " \n"); - fprintf(out, " \n"); - } - fprintf(out, " \n"); - fprintf(out, "\n"); -} - int main(int argc, char **argv) { 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; + sg_host_t workstation, selected_workstation = NULL; int total_nworkstations = 0; - const SD_workstation_t *workstations = NULL; - xbt_dynar_t dax, changed; - FILE *out = NULL; + const sg_host_t *workstations = NULL; + char * tracefilename = NULL; + xbt_dynar_t dax; /* initialization of SD */ SD_init(&argc, argv); /* Check our arguments */ - if (argc < 3) { - 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); - } - char *tracefilename; - if (argc == 3) { - char *last = strrchr(argv[2], '.'); - - tracefilename = bprintf("%.*s.jed", - (int) (last == - NULL ? strlen(argv[2]) : last - - argv[2]), argv[2]); - } else { + xbt_assert(argc > 2, "Usage: %s platform_file dax_file [jedule_file]\n" + "\tExample: %s simulacrum_7_hosts.xml Montage_25.xml Montage_25.jed", argv[0], argv[0]); + + if (argc == 4) tracefilename = xbt_strdup(argv[3]); - } /* creation of the environment */ SD_create_environment(argv[1]); /* Allocating the workstation attribute */ - total_nworkstations = SD_workstation_get_number(); - workstations = SD_workstation_get_list(); + total_nworkstations = sg_host_count(); + workstations = sg_host_list(); for (cursor = 0; cursor < total_nworkstations; cursor++) - SD_workstation_allocate_attribute(workstations[cursor]); + sg_host_allocate_attribute(workstations[cursor]); /* load the DAX file */ @@ -289,12 +231,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_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; } @@ -315,36 +256,51 @@ int main(int argc, char **argv) } XBT_INFO("Schedule %s on %s", SD_task_get_name(selected_task), - SD_workstation_get_name(selected_workstation)); + sg_host_get_name(selected_workstation)); SD_task_schedulel(selected_task, 1, selected_workstation); - SD_workstation_set_available_at(selected_workstation, min_finish_time); + + /* + * 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 = + sg_host_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( + sg_host_get_last_scheduled_task(selected_workstation), + selected_task)) + SD_task_dependency_add("resource", NULL, + last_scheduled_task, selected_task); + + sg_host_set_last_scheduled_task(selected_workstation, selected_task); + + sg_host_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); } XBT_INFO("Simulation Time: %f", SD_get_clock()); - - - - XBT_INFO - ("------------------- Produce the trace file---------------------------"); - XBT_INFO("Producing the trace of the run into %s", tracefilename); - out = fopen(tracefilename, "w"); - xbt_assert(out, "Cannot write to %s", tracefilename); + XBT_INFO("------------------- Produce the trace file---------------------------"); + XBT_INFO("Producing a jedule output (if active) of the run into %s", tracefilename?tracefilename:"./minmin_test.jed"); +#ifdef HAVE_JEDULE + jedule_sd_dump(tracefilename); +#endif free(tracefilename); - output_xml(out, dax); - - fclose(out); - - xbt_dynar_free_container(&ready_tasks); - xbt_dynar_free_container(&changed); xbt_dynar_foreach(dax, cursor, task) { SD_task_destroy(task); @@ -352,7 +308,7 @@ int main(int argc, char **argv) xbt_dynar_free_container(&dax); for (cursor = 0; cursor < total_nworkstations; cursor++) - SD_workstation_free_attribute(workstations[cursor]); + sg_host_free_attribute(workstations[cursor]); /* exit */ SD_exit();