Algorithmique Numérique Distribuée Public GIT Repository
1 #!/usr/bin/perl -w
2 use strict;
3 #use Data::Dumper;
4 use XFig;
5 use POSIX;
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
11 my(\$color_suspended)=1;
12 my(\$color_compute)=2;
13 my(\$color_wait_for_recpt)=3;
14 my(\$color_communicate)=4;
16 # Determine the order of the colors in the legend
17 my(@color_list)=(\$color_compute,\$color_communicate,\$color_wait_for_recpt,\$color_suspended);
23     my(%Cat);
24     my(\$filename)=@_;
25     my(\$line);
27     open INPUT, \$filename;
29     while (defined(\$line=<INPUT>)) {
30         chomp \$line;
31         if(\$line =~ /^7\s/) {
32             my(\$event,\$date,\$id,\$type,\$father,@name) = split(/\s+/,\$line);
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 }
47     my(\$filename,\$Cat)=@_;
48     my(\$line);
50     open INPUT, \$filename;
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 }
67     my(\$filename)=@_;
68     my(\$line);
71     open INPUT, \$filename;
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";
82         }
83         if(\$line =~ /^17\s/) {
84             my(\$event,\$date,\$type,\$father,\$channel,\$dst,\$key,\$trash) = split(/\t+/,\$line);
85             my(\$numkey)=hex "\$key";
89         }
90     }
91     close INPUT;
93 }
96 sub build_cat_tree {
97     my(\$root,\$Cat)=@_;
98     my(@childs)=();
99     my(\$cat);
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     }
108     return [\$root,@childs];
109 }
111 sub build_cat_list {
112     my(\$tree,\$cat_list)=@_;
113     my(\$root) = shift @\$tree;
114     my(\$u);
116     push @\$cat_list,\$root;
118     foreach \$u (@\$tree) {
119         build_cat_list(\$u,\$cat_list);
120     }
121     unshift @\$tree, \$root;
122 }
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     }
135     if (!defined(\$\$Cat{\$cat2}{state})) {
136         return -1;
137     }
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 }
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 }
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 }
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 }
198 sub draw_cat {
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;
217     }
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];
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));
242                 my(\$line) = new XFig ('polyline');
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                 }
262             }
263         }
264     }
267         my(\$line) = new XFig ('polyline');
272         \$line->{'subtype'} = 1;  # line
274         print STDERR "\$link: \$src (\$src_date) -> \$dst (\$dst_date)\n";
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'];
283     }
287 # Host visualization
289     my(\$max_Y)= 0;
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;
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');
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++;
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;
322         if (\$max_Y<\$\$Cat{\$cat}{Y_max_host}) {
323             \$max_Y = \$\$Cat{\$cat}{Y_max_host};
324         }
325     }
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;
336         my(\$line) = new XFig ('polyline');
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;
349         my(\$text) = new XFig ('text');
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         }
364         \$text->{'y'} = \$min_Y + (\$i-0.5)*\$height +68;
365         \$text->{'x'} = 50;
366         \$text->{'subtype'} = 0;
368         \$i++;
369     }
371 # Time axis
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'];
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     }
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;
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;
409     }
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] ];
419 }
421 sub main {
423     my(\$cat_tree)=build_cat_tree("0",\$Cat);
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);
436     my(\$fig)=create_fig("toto.fig");