From 3cffa21b9a838fd49d32ec728d33277718a3eafb Mon Sep 17 00:00:00 2001 From: Frederic Suter Date: Tue, 2 Feb 2016 12:07:23 +0100 Subject: [PATCH 1/1] start to simplify this dot parsing stuff --- src/simdag/sd_dotloader.cpp | 156 ++++++++++++------------------------ 1 file changed, 52 insertions(+), 104 deletions(-) diff --git a/src/simdag/sd_dotloader.cpp b/src/simdag/sd_dotloader.cpp index 9333294531..03d1edae28 100644 --- a/src/simdag/sd_dotloader.cpp +++ b/src/simdag/sd_dotloader.cpp @@ -34,11 +34,9 @@ typedef enum { xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par); -static xbt_dynar_t result; static xbt_dict_t jobs; static xbt_dict_t computers; -static Agraph_t *dag_dot; -static bool schedule = true; +static bool schedule = false; static void dot_task_p_free(void *task) { SD_task_t *t = (SD_task_t *)task; @@ -47,30 +45,23 @@ static void dot_task_p_free(void *task) { /** @brief loads a DOT file describing a DAG * - * See http://www.graphviz.org/doc/info/lang.html - * for more details. - * To obtain information about transfers and tasks, two attributes are - * required : size on task (execution time in Flop) and size on edge - * (the amount of data transfer in bit). - * if they aren't here, there choose to be equal to zero. + * See http://www.graphviz.org/doc/info/lang.html for more details. + * The size attribute of a node describes: + * - for a compute task: the amount of flops to execute + * - for a communication task : the amount of bytes to transfer + * If this attribute is ommited, the default value is zero. */ xbt_dynar_t SD_dotload(const char *filename) { - computers = xbt_dict_new_homogeneous(NULL); - schedule = false; - SD_dotload_generic(filename, sequential); - xbt_dynar_t computer = NULL; - xbt_dict_cursor_t dict_cursor; - char *computer_name; - xbt_dict_foreach(computers,dict_cursor,computer_name,computer){ - xbt_dynar_free(&computer); - } - xbt_dict_free(&computers); - return result; + return SD_dotload_generic(filename, sequential); +} + +xbt_dynar_t SD_PTG_dotload(const char * filename) { + return SD_dotload_generic(filename, parallel); } xbt_dynar_t SD_dotload_with_sched(const char *filename) { - computers = xbt_dict_new_homogeneous(NULL); - SD_dotload_generic(filename, sequential); + schedule = true; + xbt_dynar_t result = SD_dotload_generic(filename, sequential); if(schedule){ xbt_dynar_t computer = NULL; @@ -83,12 +74,11 @@ xbt_dynar_t SD_dotload_with_sched(const char *filename) { SD_task_t task; SD_task_t task_previous = NULL; xbt_dynar_foreach(computer,count,task){ - /* add dependency between the previous and the task to avoid - * parallel execution */ + /* add dependency between the previous and the task to avoid parallel execution */ if(task != NULL ){ - if(task_previous != NULL && - !SD_task_dependency_exists(task_previous, task)) + if(task_previous != NULL && !SD_task_dependency_exists(task_previous, task)) SD_task_dependency_add(NULL, NULL, task_previous, task); + SD_task_schedulel(task, 1, workstations[count_computer]); task_previous = task; } @@ -114,17 +104,6 @@ xbt_dynar_t SD_dotload_with_sched(const char *filename) { return NULL; } -xbt_dynar_t SD_PTG_dotload(const char * filename) { - xbt_dynar_t result = SD_dotload_generic(filename, parallel); - if (!acyclic_graph_detail(result)) { - XBT_ERROR("The DOT described in %s is not a DAG. It contains a cycle.", - basename((char*)filename)); - xbt_dynar_free(&result); - /* (result == NULL) here */ - } - return result; -} - #ifdef HAVE_CGRAPH_H static int edge_compare(const void *a, const void *b) { @@ -137,52 +116,40 @@ static int edge_compare(const void *a, const void *b) xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ xbt_assert(filename, "Unable to use a null file descriptor\n"); unsigned int i; - result = xbt_dynar_new(sizeof(SD_task_t), dot_task_p_free); + xbt_dynar_t result = xbt_dynar_new(sizeof(SD_task_t), dot_task_p_free); jobs = xbt_dict_new_homogeneous(NULL); FILE *in_file = fopen(filename, "r"); if (in_file == NULL) xbt_die("Failed to open file: %s", filename); - dag_dot = agread(in_file, NIL(Agdisc_t *)); + Agraph_t * dag_dot = agread(in_file, NIL(Agdisc_t *)); SD_task_t root, end, task; - /* - * Create all the nodes - */ + + if (schedule) + computers = xbt_dict_new_homogeneous(NULL); + + /* Create all the nodes */ Agnode_t *node = NULL; for (node = agfstnode(dag_dot); node; node = agnxtnode(dag_dot, node)) { - char *name = agnameof(node); double amount = atof(agget(node, (char *) "size")); double alpha = 0.0; - if (seq_or_par == sequential){ - XBT_DEBUG("See ", name, amount); - } else { - if (!strcmp(agget(node, (char *) "alpha"), "")){ - alpha = atof(agget(node, (char *) "alpha")); - if (alpha == -1.){ - XBT_DEBUG("negative alpha value provided. Set to 0."); - alpha = 0.0 ; - } - } else { - XBT_DEBUG("no alpha value provided. Set to 0"); - alpha = 0.0 ; - } - - XBT_DEBUG("See ", - name, amount, alpha); - } - if (!(task = (SD_task_t)xbt_dict_get_or_null(jobs, name))) { if (seq_or_par == sequential){ + XBT_DEBUG("See ", name, amount); task = SD_task_create_comp_seq(name, NULL , amount); } else { + alpha = atof(agget(node, (char *) "alpha")); + XBT_DEBUG("See ", name, amount, alpha); task = SD_task_create_comp_par_amdahl(name, NULL , amount, alpha); } + xbt_dict_set(jobs, name, task, NULL); + if (!strcmp(name, "root")){ - /* by design the root task is always SCHEDULABLE */ - SD_task_set_state(task, SD_SCHEDULABLE); - /* Put it at the beginning of the dynar */ + /* by design the root task is always SCHEDULABLE */ + SD_task_set_state(task, SD_SCHEDULABLE); + /* Put it at the beginning of the dynar */ xbt_dynar_insert_at(result, 0, &task); } else { if (!strcmp(name, "end")){ @@ -194,22 +161,17 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ } } - if((seq_or_par == sequential) && - (schedule || - XBT_LOG_ISENABLED(sd_dotparse, xbt_log_priority_verbose))){ - /* try to take the information to schedule the task only if all is - * right*/ + if((seq_or_par == sequential) && (schedule || XBT_LOG_ISENABLED(sd_dotparse, xbt_log_priority_verbose))){ + /* try to take the information to schedule the task only if all is right*/ int performer, order; char *char_performer = agget(node, (char *) "performer"); char *char_order = agget(node, (char *) "order"); /* performer is the computer which execute the task */ - performer = - ((!char_performer || !strcmp(char_performer,"")) ? -1:atoi(char_performer)); + performer = ((!char_performer || !strcmp(char_performer,"")) ? -1:atoi(char_performer)); /* order is giving the task order on one computer */ order = ((!char_order || !strcmp(char_order, ""))? -1:atoi(char_order)); - XBT_DEBUG ("Task '%s' is scheduled on workstation '%d' in position '%d'", - task->name, performer, order); + XBT_DEBUG ("Task '%s' is scheduled on workstation '%d' in position '%d'", task->name, performer, order); xbt_dynar_t computer = NULL; if(performer != -1 && order != -1){ /* required parameters are given */ @@ -227,8 +189,7 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ /* the user gives the same order to several tasks */ schedule = false; XBT_VERB("The task %s starts on the computer %s at the position : %s like the task %s", - (*task_test)->name, char_performer, char_order, - task->name); + (*task_test)->name, char_performer, char_order, task->name); }else{ /* the parameter seems to be ok */ xbt_dynar_set_as(computer, order, SD_task_t, task); @@ -243,8 +204,7 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ else { /* one of required parameters is not given */ schedule = false; - XBT_VERB("The schedule is ignored, the task %s is not correctly scheduled", - task->name); + XBT_VERB("The schedule is ignored, the task %s is not correctly scheduled", task->name); } } } else { @@ -252,10 +212,7 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ } } - /* - * Check if 'root' and 'end' nodes have been explicitly declared. - * If not, create them. - */ + /*Check if 'root' and 'end' nodes have been explicitly declared. If not, create them. */ if (!(root = (SD_task_t)xbt_dict_get_or_null(jobs, "root"))){ if (seq_or_par == sequential) root = SD_task_create_comp_seq("root", NULL, 0); @@ -264,7 +221,7 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ /* by design the root task is always SCHEDULABLE */ SD_task_set_state(root, SD_SCHEDULABLE); /* Put it at the beginning of the dynar */ - xbt_dynar_insert_at(result, 0, &root); + xbt_dynar_insert_at(result, 0, &root); } if (!(end = (SD_task_t)xbt_dict_get_or_null(jobs, "end"))){ @@ -272,12 +229,9 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ end = SD_task_create_comp_seq("end", NULL, 0); else end = SD_task_create_comp_par_amdahl("end", NULL, 0, 0); - /* Should be inserted later in the dynar */ } - /* - * Create edges - */ + /* Create edges */ xbt_dynar_t edges = xbt_dynar_new(sizeof(Agedge_t*), NULL); for (node = agfstnode(dag_dot); node; node = agnxtnode(dag_dot, node)) { unsigned cursor; @@ -286,10 +240,9 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ for (edge = agfstout(dag_dot, node); edge; edge = agnxtout(dag_dot, edge)) xbt_dynar_push_as(edges, Agedge_t *, edge); #ifdef HAVE_CGRAPH_H - /* Hack: circumvent a bug in libcgraph, where the edges are not always given - * back in creation order. We sort them again, according to their sequence - * id. The problem appears to be solved (i.e.: I did not test it) in - * graphviz' mercurial repository by the following changeset: + /* Hack: circumvent a bug in libcgraph, where the edges are not always given back in creation order. We sort them + * again, according to their sequence id. The problem appears to be solved (i.e.: I did not test it) in graphviz' + * mercurial repository by the following changeset: * changeset: 8431:d5f1fb7e8103 * user: Emden Gansner * date: Tue Oct 11 12:38:58 2011 -0400 @@ -331,25 +284,21 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ } xbt_dynar_free(&edges); - /* all compute and transfer tasks have been created, put the "end" node at - * the end of dynar - */ - XBT_DEBUG("All tasks have been created, put %s at the end of the dynar", - end->name); + /* all compute and transfer tasks have been created, put the "end" node at the end of dynar */ + XBT_DEBUG("All tasks have been created, put %s at the end of the dynar", end->name); xbt_dynar_push(result, &end); /* Connect entry tasks to 'root', and exit tasks to 'end'*/ - xbt_dynar_foreach (result, i, task){ if (task == root || task == end) continue; if (xbt_dynar_is_empty(task->tasks_before)) { - XBT_DEBUG("file '%s' has no source. Add dependency from 'root'", - task->name); + XBT_DEBUG("file '%s' has no source. Add dependency from 'root'", task->name); SD_task_dependency_add(NULL, NULL, root, task); - } else if (xbt_dynar_is_empty(task->tasks_after)) { - XBT_DEBUG("file '%s' has no destination. Add dependency to 'end'", - task->name); + } + + if (xbt_dynar_is_empty(task->tasks_after)) { + XBT_DEBUG("file '%s' has no destination. Add dependency to 'end'", task->name); SD_task_dependency_add(NULL, NULL, task, end); } } @@ -359,10 +308,9 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ fclose(in_file); if (!acyclic_graph_detail(result)) { - XBT_ERROR("The DOT described in %s is not a DAG. It contains a cycle.", - basename((char*)filename)); + XBT_ERROR("The DOT described in %s is not a DAG. It contains a cycle.", basename((char*)filename)); xbt_dynar_free(&result); - /* (result == NULL) here */ + result = NULL; } return result; } -- 2.20.1