Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
We switched to SVN
[simgrid.git] / examples / simdag / mixtesim / src / grid.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4
5 #include "simgrid.h"
6
7 #include "mixtesim_prototypes.h"
8
9 /**           **
10  ** STRUCTURE **
11  **           **/
12
13 /*
14  * newHost()
15  */
16 Host newHost()
17 {
18   return (Host)calloc(1,sizeof(struct _Host));
19 }
20
21 /* 
22  * freeHost()
23  */
24 void freeHost(Host h)
25 {
26   if (h->cpu_trace)
27     free(h->cpu_trace);
28   free(h);
29   return;
30 }
31
32 /*
33  * newLink()
34  */
35 Link newLink()
36 {
37   return (Link)calloc(1,sizeof(struct _Link));
38 }
39
40 /*
41  * freeLink()
42  */
43 void freeLink(Link l)
44 {
45   if (l->latency_trace)
46     free(l->latency_trace);
47   if (l->bandwidth_trace)
48     free(l->bandwidth_trace);
49   free(l);
50   return;
51 }
52
53 /*
54  * newGrid()
55  */
56 Grid newGrid()
57 {
58   return (Grid)calloc(1,sizeof(struct _Grid));
59 }
60
61 /*
62  * freeGrid()
63  */
64 void freeGrid(Grid g)
65 {
66   int i;
67   for (i=0;i<g->nb_hosts;i++)
68     freeHost(g->hosts[i]);
69   if (g->hosts)
70     free(g->hosts);
71   for (i=0;i<g->nb_links;i++)
72     freeLink(g->links[i]);
73   if (g->links)
74     free(g->links);
75   if (g->connections) {
76     for (i=0;i<g->nb_hosts;i++) {
77       if (g->connections[i]) {
78         free(g->connections[i]);
79       }
80     }
81     free(g->connections);
82   }
83   free(g);
84   return;
85 }
86
87
88 /**         **
89  ** PARSING **
90  **         **/
91
92 static int createConnectionMatrix(Grid grid);
93 static int parseLine(Grid,char*);
94 static int parseLinkCountLine(Grid,char*);
95 static int parseHostCountLine(Grid,char*);
96 static int parseLinkLine(Grid,char*);
97 static int parseHostLine(Grid,char*);
98
99 /*
100  * parseGridFile()
101  */
102 Grid parseGridFile(char *filename)
103 {
104   Grid new;
105   int i;
106
107   new = newGrid();
108
109   new->nb_host = SD_workstation_get_number();
110
111
112   new->nb_link = SD_link_get_number();
113
114   FILE *f;
115   char line[4084];
116   int count=0;
117   char *tmp;
118
119   Grid new;
120
121   /* open Grid description file */
122   if (!(f=fopen(filename,"r"))) {
123     fprintf(stderr,"Impossible to open file '%s'\n",filename);
124     return NULL;
125   }
126
127   /* Allocate memory for the Grid */
128   new=newGrid();
129
130   /* go through the lines in the files */
131   while(fgets(line,4084,f)) {
132     count++;
133     if (line[0]=='#') /* comment line */
134       continue;
135     if (line[0]=='\n') /* empty line */
136       continue;
137     tmp=strdup(line); /* strdupoing seesm to make it work */
138     if (parseLine(new,tmp) == -1) {
139       fprintf(stderr,"Error in  Grid description file at line %d\n",count);
140       fclose(f);
141       return NULL;
142     } 
143     free(tmp);
144   }
145   fclose(f);
146
147   /* Create the connection matrix */
148   createConnectionMatrix(new);
149
150   return new;
151 }
152
153 /*
154  * parseLine()
155  */
156 static int parseLine(Grid grid, char *line)
157 {
158   char *ptr;
159   /* does the line start with a keyword ? */
160   ptr=strchr(line,' ');
161   if (ptr==NULL) {
162     fprintf(stderr,"Syntax error\n");
163     return -1;
164   } else{
165     *ptr='\0';
166   }
167   /* process the different key words */
168   if (!strncmp(line,"LINK_COUNT",strlen("LINK_COUNT")))
169     return parseLinkCountLine(grid,ptr+1);
170   if (!strncmp(line,"LINK",strlen("LINK")))
171     return parseLinkLine(grid,ptr+1);
172   if (!strncmp(line,"HOST_COUNT",strlen("HOST_COUNT")))     
173     return parseHostCountLine(grid,ptr+1);
174   if (!strncmp(line,"HOST",strlen("HOST")))     
175     return parseHostLine(grid,ptr+1);
176
177   fprintf(stderr,"Unknown keyword %s\n",line);
178   return -1;
179 }
180
181 /*
182  * parseHostCountLine()
183  *
184  * HOST_COUNT <number>
185  */
186 int parseHostCountLine(Grid grid, char *line)
187 {
188   int i,count;
189
190   /* HOST_COUNT should be called only once */
191   if (grid->nb_hosts != 0) {
192     fprintf(stderr,"Error: Only one Host Count specification allowed\n");
193     return -1;
194   }
195
196   /* get the count */
197   count=atoi(line);
198   /* check that count >0 */
199   if (count == 0) {
200     fprintf(stderr,"Error: invalid Host count\n");
201     return -1;
202   }
203   /* allocate the grid->hosts array */
204   grid->nb_hosts=count;
205   grid->hosts=(Host *)calloc(grid->nb_hosts,sizeof(Host));
206   
207   /* allocate the connection matrix */
208   grid->connections=(Link ***)calloc(grid->nb_hosts,sizeof(Link**));
209   for (i=0;i<grid->nb_hosts;i++) {
210     grid->connections[i]=(Link **)calloc(grid->nb_hosts,sizeof(Link*));
211   }
212   return 0;
213 }
214
215 /*
216  * parseLinkCountLine()
217  *
218  * LINK_COUNT <number>
219  */
220 int parseLinkCountLine(Grid grid, char *line)
221 {
222   int count;
223
224   /* LINK_COUNT should be called only once */
225   if (grid->nb_links != 0) {
226     fprintf(stderr,"Error: Only one Link Count specification allowed\n");
227     return -1;
228   }
229
230   /* get the count */
231   count=atoi(line);
232   if (count == 0) {
233     fprintf(stderr,"Error: invalid Link count\n");
234     return -1;
235   }
236   /* allocate the grid->links array */
237   grid->nb_links=count;
238   grid->links=(Link *)calloc(grid->nb_links,sizeof(Link));
239   
240   return 0;
241 }
242
243 /*
244  * parseHostLine()
245  *
246  * HOST <index> <rel_speed> <cpu_file>
247  */
248 int parseHostLine(Grid grid, char *line)
249 {
250   char *ptr;
251   Host host;
252   char *s_indexlist,*s_cpu_file,*s_rel_speed,*s_mode;
253   int *hostIndexList=NULL;
254   int nb_hostOnLine, i, min,max;
255   double rel_speed;
256
257   /* HOST_COUNT must be called before HOST */
258   if (grid->nb_hosts == 0) {
259     fprintf(stderr,"Error: Host Count must be specified before Hosts\n");
260     return -1;
261   }
262
263   /* Get index List*/
264   ptr=strchr(line,' ');
265   if (!ptr) {
266     fprintf(stderr,"Syntax error\n");
267     return -1;
268   }
269   s_indexlist=line;
270   *ptr='\0';
271   line=ptr+1;
272
273   /* Get rel_speed */
274   ptr=strchr(line,' ');
275   if (!ptr) {
276     fprintf(stderr,"Syntax error\n");
277     return -1;
278   }
279   s_rel_speed=line;
280   *ptr='\0';
281   line=ptr+1;
282
283   /* Get cpu_file */
284   ptr=strchr(line,' ');
285   if (!ptr) {
286     fprintf(stderr,"Syntax error\n");
287     return -1;
288   }
289   s_cpu_file=line;
290   *ptr='\0';
291   line=ptr+1;
292
293   /* get mode */
294   ptr=strchr(line,'\n');
295   if (!ptr) {
296     fprintf(stderr,"Syntax error\n");
297     return -1;
298   }
299   s_mode=line;
300   *ptr='\0';
301
302   /* Process strings */
303   ptr = strchr(s_indexlist,'-');
304   min = atoi(s_indexlist);
305   max = atoi(ptr+1);
306   nb_hostOnLine = max-min+1;
307   hostIndexList=(int*)calloc(max-min+1,sizeof(int));
308   for (i=0;i<max-min+1;i++){
309     hostIndexList[i]=min+i;
310   }
311   
312   rel_speed=atof(s_rel_speed);
313
314   /* Creating the hosts */
315   for (i=0;i<nb_hostOnLine;i++){
316     host = newHost();
317     host->global_index = min+i;
318     host->rel_speed = rel_speed;
319     if (!host->global_index) {
320       host->cluster=0;
321     } else if (host->rel_speed != 
322                grid->hosts[host->global_index-1]->rel_speed) {
323       host->cluster = grid->hosts[host->global_index-1]->cluster +1;
324     } else {
325       host->cluster = grid->hosts[host->global_index-1]->cluster;
326     }
327
328     host->cpu_trace = strdup(s_cpu_file);
329     if (!strcmp(s_mode,"IN_ORDER")) {
330       host->mode = SG_SEQUENTIAL_IN_ORDER;
331     } else if (!strcmp(s_mode,"OUT_OF_ORDER")) {
332       host->mode = SG_SEQUENTIAL_OUT_OF_ORDER;
333     } else if (!strcmp(s_mode,"TIME_SLICED")) {
334       host->mode = SG_TIME_SLICED;
335     } else {
336       fprintf(stderr,"Error: invalid mode specification '%s'\n",s_mode);
337       return -1;
338     }
339     /* Is the host beyond the index */
340     if (host->global_index >= grid->nb_hosts) {
341       fprintf(stderr,"Error: More hosts than the host count\n");
342       return -1;
343     }
344     
345     /* Have we seen that host before ? */
346     if (grid->hosts[host->global_index] != NULL) {
347       fprintf(stderr,"Error: Two hosts share index %d\n",
348               host->global_index);
349       return -1;
350     }
351     /* Add the host to the grid->hosts array */
352     grid->hosts[host->global_index]=host;
353   }
354   return 1;
355 }
356
357 /*
358  * parseLinkLine()
359  *
360  * LINK <index> <lat_file> <band_file>
361  */
362 int parseLinkLine(Grid grid, char *line)
363 {
364   char *ptr;
365   Link link;
366   char buffer[16];
367
368   char *s_indexlist,*s_lat_file,*s_band_file,*s_mode;
369   int *linkIndexList=NULL;
370   int nb_linkOnLine, i, min,max;
371
372   /* LINK_COUNT must be called before LINK */
373   if (grid->nb_links == 0) {
374     fprintf(stderr,"Error: Link Count must be specified before Links\n");
375     return -1;
376   }
377
378   /* Get index */
379   ptr=strchr(line,' ');
380   if (!ptr) {
381     fprintf(stderr,"Syntax error\n");
382     return -1;
383   }
384   s_indexlist=line;
385   *ptr='\0';
386   line=ptr+1;
387
388
389   /* Get lat_file */
390   ptr=strchr(line,' ');
391   if (!ptr) {
392     fprintf(stderr,"Syntax error\n");
393     return -1;
394   }
395   s_lat_file=line;
396   *ptr='\0';
397   line=ptr+1;
398
399   /* Get band_file */
400   ptr=strchr(line,' ');
401   if (!ptr) {
402     fprintf(stderr,"Syntax error\n");
403     return -1;
404   }
405   s_band_file=line;
406   *ptr='\0';
407   line=ptr+1;
408
409   /* get mode */
410   ptr=strchr(line,'\n');
411   if (!ptr) {
412     fprintf(stderr,"Syntax error\n");
413     return -1;
414   }
415   s_mode=line;
416   *ptr='\0';
417
418   /* Process strings */
419   ptr = strchr(s_indexlist,'-');
420   min = atoi(s_indexlist);
421   if (ptr) {
422     max = atoi(ptr+1);
423   } else {
424     max=min;
425   }
426   nb_linkOnLine = max-min+1;
427   linkIndexList=(int*)calloc(max-min+1,sizeof(int));
428   for (i=0;i<max-min+1;i++){
429     linkIndexList[i]=min+i;
430   }
431   
432   /* Creating the link */
433   for (i=0;i<nb_linkOnLine;i++){
434     link = newLink();
435     link->global_index = min+i;
436     link->latency_trace=strdup(s_lat_file);
437     link->bandwidth_trace=strdup(s_band_file);
438     if (!strcmp(s_mode,"IN_ORDER")) {
439       link->mode = SG_SEQUENTIAL_IN_ORDER;
440     } else if (!strcmp(s_mode,"OUT_OF_ORDER")) {
441       link->mode = SG_SEQUENTIAL_OUT_OF_ORDER;
442     } else if (!strcmp(s_mode,"TIME_SLICED")) {
443       link->mode = SG_TIME_SLICED;
444     } else if (!strcmp(s_mode,"FAT_PIPE")){
445       link->mode = SG_FAT_PIPE;
446     } else {
447       fprintf(stderr,"Error: invalid mode specification '%s'\n",s_mode);
448       return -1;
449     }
450     sprintf(buffer,"link%d",min+i);
451
452     /* Is the node beyond the index */
453     if (link->global_index >= grid->nb_links) {
454     fprintf(stderr,"Error: More links than the link count\n");
455     return -1;
456     }
457   
458
459     /* Have we seen that link before ? */
460     if (grid->links[link->global_index] != NULL) {
461       fprintf(stderr,"Error: Two links share index %d\n",
462               link->global_index);
463       return -1;
464     }
465     /* Add the link to the grid->links array */
466     grid->links[link->global_index]=link;
467   }
468   return 1;
469 }
470
471 static int createConnectionMatrix(Grid grid){
472   int i,j,nb_clusters;
473   for (i=0;i<grid->nb_hosts;i++){
474     for(j=0;j<grid->nb_hosts;j++){
475       if (i==j) {
476         grid->connections[i][j]=(Link*)calloc(1, sizeof(Link));
477         grid->connections[i][j][0]=newLink();
478         (grid->connections[i][j][0])->global_index=-1;
479       }else{
480         /* Intra cluster connection */
481         if (grid->hosts[i]->cluster == grid->hosts[j]->cluster) {
482           grid->connections[i][j]=(Link*)calloc(3, sizeof(Link));
483           grid->connections[i][j][0]= grid->links[i];
484           grid->connections[i][j][1]= 
485             grid->links[grid->nb_hosts+grid->hosts[i]->cluster];
486           grid->connections[i][j][2]= grid->links[j]; 
487         } else { /* Inter cluster connection */
488           grid->connections[i][j]=(Link*)calloc(7, sizeof(Link));
489
490           nb_clusters = grid->hosts[grid->nb_hosts-1]->cluster+1;
491
492           /* Src host */
493           grid->connections[i][j][0]= grid->links[i];
494           /* Src switch */
495           grid->connections[i][j][1]= 
496             grid->links[grid->nb_hosts+grid->hosts[i]->cluster];
497           /* Src gateway */
498           grid->connections[i][j][2]= 
499             grid->links[grid->nb_hosts+grid->hosts[i]->cluster+nb_clusters];
500           /* Backbone */
501           grid->connections[i][j][3]= 
502             grid->links[grid->nb_links-1];
503           /* Dest gateway */
504           grid->connections[i][j][4]= 
505             grid->links[grid->nb_hosts+grid->hosts[j]->cluster+nb_clusters];
506           /* Dest switch */
507           grid->connections[i][j][5]= 
508             grid->links[grid->nb_hosts+grid->hosts[j]->cluster];
509           /* Dest host */
510           grid->connections[i][j][6]= grid->links[j]; 
511         
512         }
513       }
514     }
515   }
516   return 1;
517 }
518