Logo AND Algorithmique Numérique Distribuée

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