X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/60086e528fae37ab1c4f3ac9bc87d3ea1de125c6..0700b488178346d3cccc454f641a7155c6ff6026:/src/simdag/sd_dotloader.c diff --git a/src/simdag/sd_dotloader.c b/src/simdag/sd_dotloader.c index 194f79efa5..cc4edd1abb 100644 --- a/src/simdag/sd_dotloader.c +++ b/src/simdag/sd_dotloader.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2009-2013. The SimGrid Team. +/* Copyright (c) 2009-2014. The SimGrid Team. * All rights reserved. */ /* This program is free software; you can redistribute it and/or modify it @@ -40,11 +40,6 @@ static xbt_dict_t computers; static Agraph_t *dag_dot; static bool schedule = true; -static void dot_task_free(void *task) { - SD_task_t t = task; - SD_task_destroy(t); -} - static void dot_task_p_free(void *task) { SD_task_t *t = task; SD_task_destroy(*t); @@ -75,6 +70,7 @@ static void TRACE_sd_dotloader (SD_task_t task, const char *category) { */ 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; @@ -121,8 +117,6 @@ xbt_dynar_t SD_dotload_with_sched(const char *filename) { }else{ XBT_WARN("The scheduling is ignored"); } - SD_task_t task; - unsigned int count; xbt_dynar_t computer = NULL; xbt_dict_cursor_t dict_cursor; char *computer_name; @@ -130,9 +124,7 @@ xbt_dynar_t SD_dotload_with_sched(const char *filename) { xbt_dynar_free(&computer); } xbt_dict_free(&computers); - xbt_dynar_foreach(result,count,task){ - SD_task_destroy(task); - } + xbt_dynar_free(&result); return NULL; } @@ -147,12 +139,23 @@ xbt_dynar_t SD_PTG_dotload(const char * filename) { return result; } +#ifdef HAVE_CGRAPH_H +static int edge_compare(const void *a, const void *b) +{ + unsigned va = AGSEQ(*(Agedge_t **)a); + unsigned vb = AGSEQ(*(Agedge_t **)b); + return va == vb ? 0 : (va < vb ? -1 : 1); +} +#endif + 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); 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 *)); SD_task_t root, end, task; /* @@ -163,14 +166,22 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ char *name = agnameof(node); double amount = atof(agget(node, (char *) "size")); - double alpha; + double alpha = 0.0; if (seq_or_par == sequential){ XBT_DEBUG("See ", name, amount); } else { - alpha = atof(agget(node, (char *) "alpha")); - if (alpha == -1.) + 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); } @@ -200,20 +211,20 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ } } - if(schedule && seq_or_par == sequential){ + 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 */ - int performer = -1; - char * char_performer = agget(node, (char *) "performer"); - if (char_performer) - performer = atoi(char_performer); - + performer = + ((!char_performer || !strcmp(char_performer,"")) ? -1:atoi(char_performer)); /* order is giving the task order on one computer */ - int order = -1; - char * char_order = agget(node, (char *) "order"); - if (char_order) - order = atoi(char_order); + 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_dynar_t computer = NULL; @@ -284,10 +295,27 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ /* * Create edges */ - node = NULL; + xbt_dynar_t edges = xbt_dynar_new(sizeof(Agedge_t*), NULL); for (node = agfstnode(dag_dot); node; node = agnxtnode(dag_dot, node)) { - Agedge_t * edge = NULL; - for (edge = agfstout(dag_dot, node); edge; edge = agnxtout(dag_dot, edge)) { + unsigned cursor; + Agedge_t * edge; + xbt_dynar_reset(edges); + 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: + * changeset: 8431:d5f1fb7e8103 + * user: Emden Gansner + * date: Tue Oct 11 12:38:58 2011 -0400 + * summary: Make sure edges are stored in node creation order + * It should be fixed in graphviz 2.30 and above. + */ + xbt_dynar_sort(edges, edge_compare); +#endif + xbt_dynar_foreach(edges, cursor, edge) { SD_task_t src, dst; char *src_name=agnameof(agtail(edge)); char *dst_name=agnameof(aghead(edge)); @@ -316,11 +344,13 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ } else { XBT_WARN("Task '%s' is defined more than once", name); } + xbt_free(name); } else { SD_task_dependency_add(NULL, NULL, src, dst); } } } + xbt_dynar_free(&edges); /* all compute and transfer tasks have been created, put the "end" node at * the end of dynar @@ -347,6 +377,13 @@ xbt_dynar_t SD_dotload_generic(const char * filename, seq_par_t seq_or_par){ agclose(dag_dot); xbt_dict_free(&jobs); + 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_dynar_free(&result); + /* (result == NULL) here */ + } return result; }