Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Merge branch 'master' of git+ssh://scm.gforge.inria.fr//gitroot/simgrid/simgrid
[simgrid.git] / tools / MSG_visualization / trace2fig.pl
1 #!/usr/bin/perl -w
2 use strict;
3 #use Data::Dumper;
4 use XFig;
5 use POSIX;
6
7 my($grid_Y_size)=225; 
8 my($grid_X_size)=100550; # Can be changed to improve readability in
9                          # function of the total execution time
10
11 my($color_suspended)=1;
12 my($color_compute)=2;
13 my($color_wait_for_recpt)=3;
14 my($color_communicate)=4;
15
16 # Determine the order of the colors in the legend
17 my(@color_list)=($color_compute,$color_communicate,$color_wait_for_recpt,$color_suspended);
18
19
20
21
22 sub read_cat {
23     my(%Cat);
24     my($filename)=@_;
25     my($line);
26
27     open INPUT, $filename;
28
29     while (defined($line=<INPUT>)) {
30         chomp $line;
31         if($line =~ /^7\s/) {
32             my($event,$date,$id,$type,$father,@name) = split(/\s+/,$line);
33
34             $Cat{$id}{name}="@name ";
35             $Cat{$id}{name}=~s/\"//g;
36             $Cat{$id}{father}=$father;
37             $Cat{$id}{type}=$type;
38             $Cat{$id}{date}=$date;
39         }
40     }
41     close INPUT;
42     return \%Cat;
43 }
44
45
46 sub read_event {
47     my($filename,$Cat)=@_;
48     my($line);
49
50     open INPUT, $filename;
51
52     while (defined($line=<INPUT>)) {
53         chomp $line;
54         if($line =~ /^11\s/) {
55             my($event,$date,$type,$id,$state) = split(/\s+/,$line);
56             push @{$$Cat{$id}{state}}, [$date,$state];
57         }
58         if($line =~ /^12\s/) {
59             my($event,$date,$type,$id) = split(/\s+/,$line);
60             push @{$$Cat{$id}{state}}, [$date];
61         }
62     }
63     close INPUT;
64 }
65
66 sub read_link {
67     my($filename)=@_;
68     my($line);
69     my(%link);
70
71     open INPUT, $filename;
72
73     while (defined($line=<INPUT>)) {
74         chomp $line;
75         if($line =~ /^16\s/) {
76             my($event,$date,$type,$father,$channel,$src,$key,$trash) = split(/\t+/,$line);
77             my($numkey)=hex "$key";
78             while (defined($link{$numkey})) {$numkey++;}
79             $link{$numkey}{src}=$src;
80             $link{$numkey}{src_date}=$date;
81
82         }
83         if($line =~ /^17\s/) {
84             my($event,$date,$type,$father,$channel,$dst,$key,$trash) = split(/\t+/,$line);
85             my($numkey)=hex "$key"; 
86             while (defined($link{$numkey}{dst})) {$numkey++;}
87             $link{$numkey}{dst}=$dst;
88             $link{$numkey}{dst_date}=$date;      
89         }
90     }
91     close INPUT;
92     return \%link;
93 }
94
95
96 sub build_cat_tree {
97     my($root,$Cat)=@_;
98     my(@childs)=();
99     my($cat);
100
101     foreach $cat (keys %$Cat) {
102         if($$Cat{$cat}{father} eq $root) {
103             push @childs, build_cat_tree($cat,$Cat);
104         }
105 #       print "$$Cat{$cat}{name}\t\t $Cat{$cat}{father}\n";
106     }
107     
108     return [$root,@childs];
109 }
110
111 sub build_cat_list {
112     my($tree,$cat_list)=@_;
113     my($root) = shift @$tree;
114     my($u);
115     
116     push @$cat_list,$root;
117
118     foreach $u (@$tree) {
119         build_cat_list($u,$cat_list);
120     }
121     unshift @$tree, $root;
122 }
123
124
125 sub cat_sorting_function {
126     my($cat1,$cat2,$Cat)=@_;
127     if (!defined($$Cat{$cat1}{state})) {
128         if (!defined($$Cat{$cat2}{state})) {
129             return 0;
130         } else {
131             return 1;
132         }
133     }
134
135     if (!defined($$Cat{$cat2}{state})) {
136         return -1;
137     }
138
139     my($comp) = $$Cat{$$Cat{$cat1}{'father'}}{'name'} cmp $$Cat{$$Cat{$cat2}{'father'}}{'name'};
140     if ($comp == 0) {
141         return $$Cat{$cat1}{'name'} cmp $$Cat{$cat2}{'name'};
142     } else {
143         return $comp;
144     }
145 }
146
147 sub update_host_Y {
148     my($host,$i) = @_;
149     if (!defined($$host{'Y_min_host'})) {
150         $$host{'Y_min_host'} = $i;
151     } else {
152         if ($$host{'Y_min_host'} > $i) {
153             $$host{'Y_min_host'} = $i;
154         }
155     }
156     if (!defined($$host{'Y_max_host'})) {
157         $$host{'Y_max_host'} = $i+1;
158     } else {
159         if ($$host{'Y_max_host'} < $i+1) {
160             $$host{'Y_max_host'} = $i+1;
161         }
162     }
163 }
164
165 sub set_cat_position {
166     my($Cat,$cat_list)=@_;
167     my($i)=0;
168     my($cat);
169     foreach $cat (sort {cat_sorting_function($a,$b,$Cat)} @$cat_list) {
170         if(defined($$Cat{$cat}{state})) {
171             update_host_Y($$Cat{$$Cat{$cat}{'father'}},$i);
172             $$Cat{$cat}{Y_min} = $i;
173             $$Cat{$cat}{Y_max} = $i+1;
174             $i++;
175         }
176     }
177 }
178
179 sub create_fig {
180     my($filename)=shift;
181     my($fig)=new XFig;
182     $fig->{object} = 'compound'; # Compound
183     $fig->{elements} = [];
184     $fig->{version} = 3.2;
185     $fig->{orientation}   = 'Landscape';
186     $fig->{justification} = 'Center';
187     $fig->{units}         = 'Metric';
188     $fig->{papersize}     = 'A4';
189     $fig->{magnification} = '100.00';
190     $fig->{multiplepage}  = 'Single';
191     $fig->{transparent}   = '-2';
192     $fig->{resolution}    = '1200';
193     $fig->{coordsystem}   = '2';
194     $fig->{filename}   = $filename;
195     return $fig;
196 }
197
198 sub draw_cat {
199     my($fig,$Cat,$Link)=@_;
200     my($cat,$e,$link);
201     my($max_string_length)=0;
202     foreach $cat (keys %$Cat) {
203         next unless (defined($$Cat{$cat}{Y_min}) && 
204                      defined($$Cat{$cat}{Y_max}));
205         my($text) = new XFig ('text');
206 #       $text->{'text'} = "$$Cat{$$Cat{$cat}{father}}{name}"."$$Cat{$cat}{name}";
207         my($printed_name)= $$Cat{$cat}{name};
208         $printed_name =~ s/\d+ \(0\)\s*$//;
209         if (length($printed_name) > $max_string_length) {
210             $max_string_length = length($printed_name);
211         }
212         $text->{'text'} = "$printed_name";
213         $text->{'y'} = ($$Cat{$cat}{Y_min}+$$Cat{$cat}{Y_max})/2*$grid_Y_size+68;
214         $text->{'x'} = -100;
215         $text->{'subtype'} = 2;
216         $fig->add ($text);
217     }
218
219     my($max_date)=0;
220     foreach $cat (keys %$Cat) {
221         next unless (defined($$Cat{$cat}{Y_min}) && 
222                      defined($$Cat{$cat}{Y_max}));
223         my(@states)=();
224         my($e);
225         foreach $e (@{$$Cat{$cat}{state}}) {
226             my($new_date,$state) = ($$e[0],$$e[1]);
227             if ($new_date > $max_date) {
228                 $max_date = $new_date;
229             }
230             if(defined($state)) {
231                 push @states, $e;
232             } else {
233                 my($old_event) = pop @states;
234                 my($old_date) = $$old_event[0];
235                 $state = $$old_event[1];
236
237 # LM: I added the next line because of "undefined values"...
238 # normally, I think that this should not happen, but this part of code
239 # is a bit too cryptic to me
240                 next unless (defined($state));          
241
242                 my($line) = new XFig ('polyline');
243
244                 $line->{'depth'} = 50;  # line
245                 $line->{'subtype'} = 1;  # line
246                 $line->{'points'} = [ [$old_date*$grid_X_size, $$Cat{$cat}{Y_min}*$grid_Y_size],
247                                       [$new_date*$grid_X_size, $$Cat{$cat}{Y_min}*$grid_Y_size],
248                                       [$new_date*$grid_X_size, $$Cat{$cat}{Y_max}*$grid_Y_size],
249                                       [$old_date*$grid_X_size, $$Cat{$cat}{Y_max}*$grid_Y_size],
250                                       [$old_date*$grid_X_size, $$Cat{$cat}{Y_min}*$grid_Y_size] ];
251                 $line->{'areafill'} = 20;
252                 if($state eq "S") {
253                     $line->{'fillcolor'} = $color_suspended;
254                 } elsif ($state eq "E") {
255                     $line->{'fillcolor'} = $color_compute;
256                 } elsif ($state eq "B") {
257                     $line->{'fillcolor'} = $color_wait_for_recpt;
258                 } elsif ($state eq "C") {
259                     $line->{'fillcolor'} = $color_communicate;
260                 }
261                 $fig->add ($line);
262             }
263         }
264     }
265
266     foreach $link (keys %$Link) {
267         my($line) = new XFig ('polyline');
268         my($src_date)=$$Link{$link}{src_date};
269         my($src)=$$Link{$link}{src};
270         my($dst_date)=$$Link{$link}{dst_date};
271         my($dst)=$$Link{$link}{dst};
272         $line->{'subtype'} = 1;  # line
273
274         print STDERR "$link: $src ($src_date) -> $dst ($dst_date)\n";
275
276         print STDERR "$$Cat{$src}{name} -> $$Cat{$dst}{name}\n";
277         $line->{'points'} = [ [$src_date*$grid_X_size, 
278                                ($$Cat{$src}{Y_min}+$$Cat{$src}{Y_max})/2*$grid_Y_size],
279                               [$dst_date*$grid_X_size, 
280                                ($$Cat{$dst}{Y_min}+$$Cat{$dst}{Y_max})/2*$grid_Y_size] ];
281         $line->{'forwardarrow'} = ['1', '1', '1.00', '60.00', '120.00'];
282         $fig->add ($line);
283     }
284
285
286
287 # Host visualization
288
289     my($max_Y)= 0;
290
291     my($index_fill)=0;
292     my($width_of_one_letter)=80;
293     my($min_x_for_host)=-400 - $max_string_length*$width_of_one_letter;
294     my($host_text_x)= $min_x_for_host + 200;
295
296     foreach $cat (keys %$Cat) {
297         next unless (defined($$Cat{$cat}{Y_min_host}) && 
298                      defined($$Cat{$cat}{Y_max_host}));
299         my($line) = new XFig ('polyline');
300         
301         $line->{'depth'} = 150;  
302         $line->{'subtype'} = 1;  # line
303         $line->{'points'} = [ [$min_x_for_host, $$Cat{$cat}{Y_min_host}*$grid_Y_size],
304                               [$max_date*$grid_X_size+150, $$Cat{$cat}{Y_min_host}*$grid_Y_size],
305                               [$max_date*$grid_X_size+150, $$Cat{$cat}{Y_max_host}*$grid_Y_size],
306                               [$min_x_for_host, $$Cat{$cat}{Y_max_host}*$grid_Y_size] ];
307         $line->{'areafill'} = 4+3*($index_fill % 2);
308         $line->{'fillcolor'} = 0;
309         $line->{'thickness'} = 0;
310         $index_fill++;
311         $fig->add ($line);
312         
313         my($text) = new XFig ('text');
314         $text->{'text'} = "$$Cat{$cat}{name}";
315         $text->{'angle'} = 3.14159265/2;
316         $text->{'x'} = $host_text_x;
317         $text->{'y'} = ($$Cat{$cat}{Y_min_host}+$$Cat{$cat}{Y_max_host})/2*$grid_Y_size;
318         $text->{'subtype'} = 1;
319         $text->{'font_size'} = 30;
320         $fig->add ($text);
321
322         if ($max_Y<$$Cat{$cat}{Y_max_host}) {
323             $max_Y = $$Cat{$cat}{Y_max_host};
324         }
325     }
326
327 # Legend:
328     my($i)=1;
329     my($color);
330     foreach $color (@color_list) {
331         my($min_x)=0;
332         my($min_Y)=($max_Y+1)*$grid_Y_size;
333         my($width)=1700;
334         my($height)=$grid_Y_size;
335
336         my($line) = new XFig ('polyline');
337
338         $line->{'depth'} = 50;  
339         $line->{'subtype'} = 1;  # line
340         $line->{'points'} = [ [$min_x,$min_Y + ($i-1)*$height ],
341                               [$min_x + $width,$min_Y + ($i-1)*$height],
342                               [$min_x + $width,$min_Y+$height + ($i-1)*$height],
343                               [$min_x,$min_Y+$height + ($i-1)*$height],
344                               [$min_x,$min_Y+ ($i-1)*$height]];
345         $line->{'areafill'} = 20;
346         $line->{'fillcolor'} = $color;
347         $fig->add ($line);
348
349         my($text) = new XFig ('text');
350
351         if ($color==$color_suspended) {
352             $text->{'text'} = "Suspended";
353         }
354         if ($color==$color_compute) {
355             $text->{'text'} = "Computing";
356         }
357         if ($color==$color_wait_for_recpt) {
358             $text->{'text'} = "Waiting for reception";
359         }
360         if ($color==$color_communicate) {
361             $text->{'text'} = "Communicating";
362         }
363
364         $text->{'y'} = $min_Y + ($i-0.5)*$height +68;
365         $text->{'x'} = 50;
366         $text->{'subtype'} = 0;
367         $fig->add ($text);
368         $i++;
369     }
370     
371 # Time axis
372         
373     my($line) = new XFig ('polyline');
374     $line->{'depth'} = 0;  
375     $line->{'subtype'} = 1;  # line
376     $line->{'points'} = [ [0,0],[$max_date * $grid_X_size+150,0] ];
377     $line->{'forwardarrow'} = ['1', '1', '1.00', '60.00', '120.00'];
378     $fig->add ($line);
379     
380     my($digits)=POSIX::floor(log($max_date)/log(10));
381     my($exponent) = 10**$digits;
382     my($mantissa)= $max_date / $exponent;
383     my($incr);
384     if ($mantissa<2) {
385         $incr = $exponent/10;
386     } elsif ($mantissa<5) {
387         $incr = $exponent/4;
388     } else {
389         $incr = $exponent/2;
390     }
391
392     print "$max_date $digits $exponent $mantissa $incr\n";
393     my($x);
394     for($x=0; $x < $max_date; $x += $incr) {
395         print "$x\n";
396         $line = new XFig ('polyline');
397         $line->{'depth'} = 0;  
398         $line->{'subtype'} = 1;  # line
399         $line->{'points'} = [ [$x * $grid_X_size,0],[$x * $grid_X_size, -100] ];
400         $line->{'forwardarrow'} = 0;
401         $fig->add ($line);
402
403         my($text) = new XFig ('text');
404         $text->{'text'} = "$x";
405         $text->{'y'} = -200;
406         $text->{'x'} = $x * $grid_X_size;
407         $text->{'subtype'} = 1;
408         $fig->add ($text);
409     }
410
411 # Empty line so that the text of the time axis can be seen on the pdf
412     $line = new XFig ('polyline');
413     $line->{'depth'} = 999;  
414     $line->{'subtype'} = 1;  # line
415     $line->{'thickness'} = 0;  
416     $line->{'points'} = [ [0,0],[0, -400] ];
417     $fig->add ($line);
418     
419 }
420
421 sub main {
422     my($Cat) = read_cat($ARGV[0]);
423     my($cat_tree)=build_cat_tree("0",$Cat);
424     read_event($ARGV[0],$Cat);
425     my($Link)=read_link($ARGV[0]);
426 #    print Dumper($cat_tree);
427 #    print Dumper($Cat);
428     my($cat_list)=[];
429     build_cat_list($cat_tree,$cat_list);
430     shift @$cat_list;
431     shift @$cat_list;
432 #    print "@$cat_list \n";
433     set_cat_position($Cat,$cat_list);
434
435     
436     my($fig)=create_fig("toto.fig");
437     draw_cat($fig,$Cat,$Link);
438     $fig->writefile ();
439     system "fig2dev -L pdf toto.fig toto.pdf";
440 }
441
442 main;