Logo AND Algorithmique Numérique Distribuée

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