Logo AND Algorithmique Numérique Distribuée

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