Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
5deef854568d293c8450998b2a42daf3ad26e2cf
[simgrid.git] / src / simdag / sd_daxloader.c
1 /* Copyright (c) 2009 Da SimGrid Team.  All rights reserved.                */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "private.h"
7 #include "simdag/simdag.h"
8 #include "xbt/misc.h"
9 #include "xbt/log.h"
10
11 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(sd_daxparse, sd,"Parsing DAX files");
12
13 #undef CLEANUP
14 #include "dax_dtd.h"
15 #include "dax_dtd.c"
16
17
18 /* Parsing helpers */
19 static void dax_parse_error(char *msg) {
20   fprintf(stderr, "Parse error on line %d: %s\n", dax_lineno, msg);
21   abort();
22 }
23 static double dax_parse_double(const char *string) {
24   int ret = 0;
25   double value;
26
27   ret = sscanf(string, "%lg", &value);
28   if (ret != 1)
29     dax_parse_error(bprintf("%s is not a double", string));
30   return value;
31 }
32 static int dax_parse_int(const char *string) {
33   int ret = 0;
34   int value;
35
36   ret = sscanf(string, "%d", &value);
37   if (ret != 1)
38     dax_parse_error(bprintf("%s is not an integer", string));
39   return value;
40 }
41
42 static YY_BUFFER_STATE input_buffer;
43
44 static xbt_dynar_t result;
45 static xbt_dict_t files;
46 static SD_task_t current_job;
47 static SD_task_t root_task,end_task;
48
49 static void dump_res() {
50   unsigned int cursor;
51   SD_task_t task;
52   xbt_dynar_foreach(result,cursor,task) {
53     INFO1("Task %d",cursor);
54     SD_task_dump(task);
55   }
56 }
57
58 static void dax_task_free(void*task){
59   SD_task_t t=task;
60   SD_task_destroy(t);
61 }
62
63 xbt_dynar_t SD_daxload(const char*filename) {
64   FILE* in_file = fopen(filename,"r");
65   xbt_assert1(in_file, "Unable to open \"%s\"\n", filename);
66   input_buffer = dax__create_buffer(in_file, 10);
67   dax__switch_to_buffer(input_buffer);
68   dax_lineno = 1;
69
70   result = xbt_dynar_new(sizeof(SD_task_t),dax_task_free);
71   files=xbt_dict_new();
72   root_task = SD_task_create("root",NULL,0);
73   xbt_dynar_push(result,&root_task);
74   end_task = SD_task_create("end",NULL,0);
75
76   xbt_assert2(!dax_lex(),"Parse error in %s: %s",filename,dax__parse_err_msg());
77   dax__delete_buffer(input_buffer);
78   fclose(in_file);
79
80   /* And now, post-process the files.
81    * We want a file task per pair of computation tasks exchanging the file. Dupplicate on need
82    * Files not produced in the system are said to be produced by root task (top of DAG).
83    * Files not consumed in the system are said to be consumed by end task (bottom of DAG).
84    */
85   xbt_dict_cursor_t cursor;
86   SD_task_t file;
87   char *name;
88   xbt_dict_foreach(files,cursor,name,file) {
89     unsigned int cpt1,cpt2;
90     SD_dependency_t depbefore,depafter;
91     if (xbt_dynar_length(file->tasks_before) == 0) {
92       xbt_dynar_foreach(file->tasks_after,cpt2,depafter) {
93         SD_task_t newfile = SD_task_create_comm_e2e(file->name,NULL,file->amount);
94         SD_task_dependency_add(NULL,NULL,root_task,newfile);
95         SD_task_dependency_add(NULL,NULL,newfile,depafter->dst);
96         xbt_dynar_push(result,&newfile);
97       }
98     } else if (xbt_dynar_length(file->tasks_after) == 0) {
99       xbt_dynar_foreach(file->tasks_before,cpt2,depbefore) {
100         SD_task_t newfile = SD_task_create_comm_e2e(file->name,NULL,file->amount);
101         SD_task_dependency_add(NULL,NULL,depbefore->src,newfile);
102         SD_task_dependency_add(NULL,NULL,newfile,end_task);
103         xbt_dynar_push(result,&newfile);
104       }
105     } else {
106       xbt_dynar_foreach(file->tasks_before,cpt1,depbefore) {
107         xbt_dynar_foreach(file->tasks_after,cpt2,depafter) {
108           SD_task_t newfile = SD_task_create_comm_e2e(file->name,NULL,file->amount);
109           SD_task_dependency_add(NULL,NULL,depbefore->src,newfile);
110           SD_task_dependency_add(NULL,NULL,newfile,depafter->dst);
111           xbt_dynar_push(result,&newfile);
112         }
113       }
114     }
115   }
116
117   /* Push end task last */
118   xbt_dynar_push(result,&end_task);
119
120   /* Free previous copy of the files */
121   xbt_dict_free(&files);
122
123   return result;
124 }
125
126 void STag_dax__adag(void) {
127   double version = dax_parse_double(A_dax__adag_version);
128
129   xbt_assert1((version == 2.1), "Expected version 2.1 in <adag> tag, got %f. Fix the parser or your file",version);
130 }
131 void STag_dax__job(void) {
132   double runtime = dax_parse_double(A_dax__job_runtime);
133   runtime*=4200000000.; /* Assume that timings were done on a 4.2GFlops machine. I mean, why not? */
134 //  INFO3("See <job id=%s runtime=%s %.0f>",A_dax__job_id,A_dax__job_runtime,runtime);
135   current_job = SD_task_create_comp_seq(A_dax__job_id,NULL,runtime);
136   xbt_dynar_push(result,&current_job);
137
138 }
139 void STag_dax__child(void) {
140 //  INFO0("See <child>");
141 }
142 void STag_dax__parent(void) {
143 //  INFO0("See <parent>");
144 }
145 void STag_dax__uses(void) {
146   SD_task_t file;
147   double size = dax_parse_double(A_dax__uses_size);
148   int is_input = (A_dax__uses_link == A_dax__uses_link_input);
149
150 //  INFO2("See <uses file=%s %s>",A_dax__uses_file,(is_input?"in":"out"));
151   file = xbt_dict_get_or_null(files,A_dax__uses_file);
152   if (file==NULL) {
153     file = SD_task_create_comm_e2e(A_dax__uses_file,NULL,size);
154     xbt_dict_set(files,A_dax__uses_file,file,&dax_task_free);
155   } else {
156     if (SD_task_get_amount(file)!=size) {
157       WARN3("Ignoring file %s size redefinition from %.0f to %.0f",
158           A_dax__uses_file,SD_task_get_amount(file),size);
159     }
160   }
161   if (is_input) {
162     SD_task_dependency_add(NULL,NULL,file,current_job);
163   } else {
164     SD_task_dependency_add(NULL,NULL,current_job,file);
165     if (xbt_dynar_length(file->tasks_before)>1) {
166       WARN1("File %s created at more than one location...",file->name);
167     }
168   }
169 }
170 void ETag_dax__adag(void) {
171 //  INFO0("See </adag>");
172 }
173 void ETag_dax__job(void) {
174   current_job = NULL;
175 //  INFO0("See </job>");
176 }
177 void ETag_dax__child(void) {
178 //  INFO0("See </child>");
179 }
180 void ETag_dax__parent(void) {
181 //  INFO0("See </parent>");
182 }
183 void ETag_dax__uses(void) {
184 //  INFO0("See </uses>");
185 }