-/* dot_add_output_dependencies create the dependencies between a task
- * and a transfers. This is given by the edges in the dot file.
- * The amount of data transfers is given by the attribute size on the
- * edge. */
-void dot_add_input_dependencies(SD_task_t current_job, Agedge_t *edge) {
- SD_task_t file;
-
- char name[80];
- sprintf(name ,"%s->%s",agnameof(agtail(edge)) ,agnameof(aghead(edge)));
- double size = dot_parse_double(agget(edge,(char*)"size"));
- INFO2("size : %e, get size : %s",size,agget(edge,(char*)"size"));
- //int sender = dot_parse_int(agget(edge,(char*)"sender"));
- //int reciever = dot_parse_int(agget(edge,(char*)"reciever"));
- if(size >0){
- file = xbt_dict_get_or_null(files,name);
- if (file==NULL) {
- file = SD_task_create_comm_e2e(name,NULL,size);
- xbt_dict_set(files,name,file,&dot_task_free);
- } else {
- if (SD_task_get_amount(file)!=size) {
- WARN3("Ignoring file %s size redefinition from %.0f to %.0f",
- name,SD_task_get_amount(file),size);
+ /*
+ * Check if 'root' and 'end' nodes have been explicitly declared.
+ * If not, create them.
+ */
+ if (!(root = xbt_dict_get_or_null(jobs, "root"))){
+ if (seq_or_par == sequential)
+ root = SD_task_create_comp_seq("root", NULL, 0);
+ else
+ root = SD_task_create_comp_par_amdahl("root", NULL, 0, 0);
+ /* 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);
+ }
+
+ if (!(end = xbt_dict_get_or_null(jobs, "end"))){
+ if (seq_or_par == sequential)
+ 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
+ */
+ xbt_dynar_t edges = xbt_dynar_new(sizeof(Agedge_t*), NULL);
+ for (node = agfstnode(dag_dot); node; node = agnxtnode(dag_dot, node)) {
+ 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 <erg@research.att.com>
+ * 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));
+ double size = atof(agget(edge, (char *) "size"));
+
+ src = xbt_dict_get_or_null(jobs, src_name);
+ dst = xbt_dict_get_or_null(jobs, dst_name);
+
+ if (size > 0) {
+ char *name =
+ xbt_malloc((strlen(src_name)+strlen(dst_name)+6)*sizeof(char));
+ sprintf(name, "%s->%s", src_name, dst_name);
+ XBT_DEBUG("See <transfer id=%s amount = %.0f>", name, size);
+ if (!(task = xbt_dict_get_or_null(jobs, name))) {
+ if (seq_or_par == sequential)
+ task = SD_task_create_comm_e2e(name, NULL , size);
+ else
+ task = SD_task_create_comm_par_mxn_1d_block(name, NULL , size);
+#ifdef HAVE_TRACING
+ TRACE_sd_dotloader (task, agget (node, (char*)"category"));
+#endif
+ SD_task_dependency_add(NULL, NULL, src, task);
+ SD_task_dependency_add(NULL, NULL, task, dst);
+ xbt_dict_set(jobs, name, task, NULL);
+ xbt_dynar_push(result, &task);
+ } else {
+ XBT_WARN("Task '%s' is defined more than once", name);