Check Cabal packages when validating
[ghc-hetmet.git] / utils / parallel / gran-extr.pl
1 #!/usr/local/bin/perl
2 ##############################################################################
3 # Last modified: Time-stamp: <Sat Oct 28 1995 23:49:48 Stardate: [-31]6509.75 hwloidl>
4 #                                                      (C) Hans Wolfgang Loidl
5 #
6 # Usage: gran-extr [options] [<sim-file>]
7 #
8 # Takes a file <sim-file> generated by running the GrAnSim simulator and 
9 # produces data files that should be used as input for gnuplot.
10 # This script produces figures for:
11 #   runtime of tasks
12 #   percentage of communication
13 #   heap allocation
14 #   number of created sparks
15 #   cumulative no. of tasks over runtime
16 # Furthermore, it computes the correlation between runtime and heap allocation.
17 #
18 # Options:
19 #  -g <file>  ... filename of granularity file to be produced; should end with
20 #                .dat; -global and -local will be automatically inserted for 
21 #                other versions. 
22 #  -c <file> ... filename of communication file to be produced; should end with
23 #                .dat; -global and -local will be automatically inserted for 
24 #                other versions. 
25 #  -s <file> ... filename of sparked-threads file to be produced; should end w/
26 #                .dat; -global and -local will be automatically inserted for 
27 #                other versions. 
28 #  -a <file> ... filename of heap alloc. file to be produced; should end with
29 #                .dat;
30 #  -f <file> ... filename of communication time file to be produced; 
31 #                should end with .dat;
32 #  -p <file> ... filename of GNUPLOT file that is prouced and executed.
33 #  -G <LIST> ... provide a list of boundaries for the Intervals used in the 
34 #                granularity figure; must be a Perl list e.g. (10, 20, 50)
35 #                this is interpreted as being open to left and right.
36 #  -C <LIST> ... provide a list of boundaries for the Intervals used in the 
37 #                communication figure; must be a Perl list e.g. (10, 20, 50)
38 #                this is interpreted as being closed to left and right.
39 #  -S <LIST> ... provide a list of boundaries for the Intervals used in the 
40 #                sparked-threads figure; must be a Perl list e.g. (10, 20, 50)
41 #                this is interpreted as being closed to left and right.
42 #  -A <LIST> ... provide a list of boundaries for the Intervals used in the 
43 #                heap alloc figure; must be a Perl list e.g. (10, 20, 50)
44 #                this is interpreted as being closed to left and right.
45 #  -F <LIST> ... provide a list of boundaries for the Intervals used in the 
46 #                comm. time figure; must be a Perl list e.g. (10, 20, 50)
47 #                this is interpreted as being open to left and right.
48 #  -l <int>  ... left margin in the produced figures.
49 #  -r <int>  ... right margin in the produced figures.
50 #  -x <int>  ... enlargement of figure along x-axis.
51 #  -y <int>  ... enlargement of figure along y-axis.
52 #  -e <int>  ... thickness of impulses in figure.
53 #  -i <rat>  ... set the gray level of the impulses to <rat>; <rat> must be
54 #                between 0 and 1 with 0 meaning black. 
55 #  -k <n>    ... number of klusters (oops, clusters, I mean ;)
56 #  -P        ... print percentage of threads rather than absolute number of 
57 #                threads on the y axis
58 #  -t <file> ... use template <file> for interval settings and file names
59 #                Syntax of a line in the template file:
60 #                 <flag>: <arg>
61 #  -T        ... use smart xtics rather than GNUPLOT default x-axis naming.
62 #  -L        ... use logarithmic scale for all figures.
63 #  -W        ... print warnings
64 #  -m        ... generate monchrome output
65 #  -h        ... help; print this text.
66 #  -v        ... verbose mode.
67 #
68 ##############################################################################
69
70 # ----------------------------------------------------------------------------
71 # Command line processing and initialization
72 # ----------------------------------------------------------------------------
73
74 require "getopts.pl";
75
76 &Getopts('hvWTPDmt:L:g:f:c:s:a:p:G:F:C:S:A:l:r:x:y:e:i:k:');  
77
78 do process_options();
79
80 $OPEN_INT = 1;
81 $CLOSED_INT = 0;
82
83 if ( $opt_v ) {
84     do print_verbose_message ();
85 }
86
87 # ----------------------------------------------------------------------------
88 # The real thing
89 # ----------------------------------------------------------------------------
90
91 open(INPUT,"<$input") || die "Couldn't open input file $input";
92
93 do skip_header();
94
95 $tot_total_rt = 0;
96 $tot_rt = 0;
97 $tot_bt = 0;
98 $tot_ft = 0;
99 $tot_it = 0;
100 $gum_style_gr = 0;
101
102 $line_no = 0;
103 while (<INPUT>) {
104     next                     if /^--/;     # Comment lines start with --
105     next                     if /^\s*$/;   # Skip empty lines
106     $line_no++;
107     @fields = split(/[:,]/,$_);
108     $has_end = 0;
109
110     foreach $elem (@fields) {
111       foo : {
112         $pe = $1, $end = $2 , last foo   if $elem =~ /^\s*PE\s+(\d+)\s+\[(\d+)\].*$/;
113         $tn = $1, $has_end = 1  , last foo   if $elem =~ /^\s*END\s+(\w+).*$/;
114         # $tn = $1      , last foo   if $elem =~ /^\s*TN\s+(\w+).*$/;
115         $sn = $1        , last foo   if $elem =~ /^\s*SN\s+(\d+).*$/;
116         $start = $1     , last foo   if $elem =~ /^\s*ST\s+(\d+).*$/;
117         $is_global = $1 , last foo   if $elem =~ /^\s*EXP\s+(T|F).*$/;
118         $bbs = $1       , last foo   if $elem =~ /^\s*BB\s+(\d+).*$/;
119         $ha = $1        , last foo   if $elem =~ /^\s*HA\s+(\d+).*$/;
120         $rt = $1        , last foo   if $elem =~ /^\s*RT\s+(\d+).*$/;
121         $bt = $1, $bc = $2 , last foo if $elem =~ /^\s*BT\s+(\d+)\s+\((\d+)\).*$/;
122         $ft = $1, $fc = $2 , last foo if $elem =~ /^\s*FT\s+(\d+)\s+\((\d+)\).*$/;
123         $lsp = $1        , last foo   if $elem =~ /^\s*LS\s+(\d+).*$/;
124         $gsp = $1        , last foo   if $elem =~ /^\s*GS\s+(\d+).*$/;
125         $my = $1        , last foo   if $elem =~ /^\s*MY\s+(T|F).*$/;
126       }
127     }
128
129     next unless $has_end == 1;
130
131     $total_rt = $end - $start;
132     $ready_time = $total_rt - $rt - $bt - $ft;
133
134     # ------------------------------------------------------------------------
135     # Accumulate runtime, block time, fetch time and ready time over all threads
136     # ------------------------------------------------------------------------
137
138     $tot_total_rt += $total_rt;
139     $tot_rt += $rt;
140     $tot_bt += $bt;
141     $tot_ft += $ft;
142     $tot_it += $ready_time;
143
144     # ------------------------------------------------------------------------
145     # Gather statistics about `load' on the PEs
146     # ------------------------------------------------------------------------
147
148     print "WARNING: ready time of thread is <0: $ready_time\n" if $pedantic && ($ready_time <0);
149     $pe_load[$pe] += $ready_time;
150
151     if ( $opt_D ) {
152         print "Adding $ready_time to the load time of PE no. $pe yielding $pe_load[$pe]\n";
153     }
154
155     # ------------------------------------------------------------------------
156     # Gather statistics about the size of a spark site
157     # ------------------------------------------------------------------------
158
159     $site_size[$sn] += $rt;
160
161     if ( $opt_D ) {
162         print "Adding $rt to the size of site $sn yielding $site_size[$sn]\n";
163     }
164
165     # ------------------------------------------------------------------------
166     # Gather statistics about pure exec time
167     # ------------------------------------------------------------------------
168
169     push(@all_rts,$rt);
170     $sum_rt += $rt;
171     $max_rt = $rt  if $rt > $max_rt;
172
173     $index = do get_index_open_int($rt,@exec_times);
174     $exec_class[$index]++;
175
176     if ( $is_global eq 'T' ) {
177         $exec_global_class[$index]++;
178     } else {
179         $exec_local_class[$index]++;
180     }
181
182     # ------------------------------------------------------------------------
183     # Gather statistics about communication time (absolute time rather than %)
184     # ------------------------------------------------------------------------
185     
186     # Note: Communicatin time is fetch time
187
188     push(@all_fts,$ft);
189     $sum_ft += $ft;
190     $max_ft = $ft  if $ft > $max_ft;
191
192     $index = do get_index_open_int($ft,@fetch_times);
193     $fetch_class[$index]++;
194
195     if ( $is_global eq 'T' ) {
196         $fetch_global_class[$index]++;
197     } else {
198         $fetch_local_class[$index]++;
199     }
200
201     # ------------------------------------------------------------------------
202     # Gather statistics about communication percentage
203     # ------------------------------------------------------------------------
204
205     $comm_perc = ( $total_rt == 0 ? 100 : (100 * $ft)/$total_rt );
206
207     push(@all_comm_percs,$comm_perc); 
208     $sum_comm_perc += $comm_perc;
209     $max_comm_perc = $comm_perc  if $comm_perc > $max_comm_perc;
210
211     $index = do get_index_closed_int( $comm_perc, @comm_percs );
212     if ( $index != -1 ) {
213       $comm_class[$index]++;
214     } else {
215       print "WARNING: value " . $comm_perc . " not in range (t_rt=$total_rt; ft=$ft)\n" if $pedantic;
216       $outside++;
217     }
218
219     if ( $is_global eq 'T' ) {
220       if ( $index != -1 ) {
221         $comm_global_class[$index]++;
222       } else {
223         $outside_global++;
224       }
225     } else {
226       if ( $index != -1 ) {
227         $comm_local_class[$index]++;
228       } else {
229         $outside_local++;
230       }
231     }
232
233     # ------------------------------------------------------------------------
234     # Gather statistics about locally sparked threads
235     # ------------------------------------------------------------------------
236
237     push(@all_local_sparks,$lsp);
238     $sum_local_sp += $lsp;
239     $max_local_sp = $lsp  if $lsp > $max_local_sp;
240
241     $index = do get_index_open_int($lsp,@sparks);
242     $spark_local_class[$index]++;
243
244     # ------------------------------------------------------------------------
245     # Gather statistics about globally sparked threads
246     # ------------------------------------------------------------------------
247
248     push(@all_global_sparks,$gsp);
249     $sum_global_sp += $gsp;
250     $max_global_sp = $gsp  if $gsp > $max_global_sp;
251
252     $index = do get_index_open_int($gsp,@sparks);
253     $spark_global_class[$index]++;
254
255     # ------------------------------------------------------------------------
256     # Add the above two entries to get the total number of sparks
257     # ------------------------------------------------------------------------
258
259     $sp = $lsp + $gsp;
260
261     push(@all_sparks,$sp);
262     $sum_sp += $sp;
263     $max_sp = $sp  if $sp > $max_sp;
264
265     $index = do get_index_open_int($sp,@sparks);
266     $spark_class[$index]++;
267
268     # ------------------------------------------------------------------------
269     # Gather statistics about heap allocations
270     # ------------------------------------------------------------------------
271
272     push(@all_has,$ha);
273     $sum_ha += $ha;
274     $max_ha = $ha  if $ha > $max_ha;
275
276     $index = do get_index_open_int($ha,@has);
277     $ha_class[$index]++;
278
279     # do print_line($start,$end,$is_global,$bbs,$ha,$rt,$bt,$bc,$ft,$fc,$my);
280 }
281
282 print STDERR "You don't want to engage me for a file with just $line_no lines, do you?(N)\n" , exit (-1)         if $line_no <= 1;
283
284 # ----------------------------------------------------------------------------
285
286 do write_pie_chart();
287
288 # ----------------------------------------------------------------------------
289 # Statistics
290 # ----------------------------------------------------------------------------
291
292 if ( $opt_D ) {
293   print "Lengths:\n" .
294         "   all_rts: $#all_rts;\n" .
295         "   all_comm_percs: $#all_comm_percs;\n" .
296         "   all_sparks: $#all_sparks; \n" . 
297         "   all_local_sparks: $#all_local_sparks; \n" .
298         "   all_global_sparks: $#all_global_sparks; \n" . 
299         "   all_has: $#all_has\n" .
300         "   all_fts: $#all_fts;\n";
301
302
303   print "No of elems in all_rts: $#all_rts with sum $sum_rt\n";
304   print "No of elems in all_comm_percs: $#all_rts with sum $sum_comm_perc\n";
305   print "No of elems in all_has: $#all_has with sum $sum_ha\n";
306   print "No of elems in all_fts: $#all_fts with sum $sum_ft\n";
307
308 }
309
310 do do_statistics($line_no);
311
312 # Just for debugging
313 # ..................
314
315 if ( $opt_D ) {
316   open(FILE,">LOG") || die "Couldn't open file LOG\n";
317   printf FILE "All total runtimes (\@all_rts:)\n";
318   printf FILE "[";
319   printf FILE join(", ",@all_rts);
320   printf FILE "]\n";
321   printf FILE "  Mean, std. dev: $mean_rt, $std_dev_rt\n";
322   printf FILE 70 x "-" . "\n";
323   printf FILE "All  communication times (\@all_fts:)\n";
324   printf FILE "[";
325   printf FILE join(", ",@all_fts);
326   printf FILE "]\n";
327   printf FILE "  Mean, std. dev: $mean_ft, $std_dev_ft\n";
328   printf FILE 70 x "-" . "\n";
329   printf FILE "All communication percentages (\@all_comm_percs:)\n";
330   printf FILE "[";
331   printf FILE join(", ",@all_comm_percs);
332   printf FILE "]\n";
333   printf FILE "  Mean, std. dev: $mean_comm_perc,$std_dev_comm_perc\n";
334   printf FILE 70 x "-" . "\n";
335   printf FILE "All  sparks  (\@all_sparks:)\n";
336   printf FILE "[";
337   printf FILE join(", ",@all_sparks);
338   printf FILE "]\n";
339   printf FILE "  Mean, std. dev: $mean_spark,$std_dev_spark\n";
340   printf FILE 70 x "-" . "\n";
341   printf FILE "All local sparks  (\@all_local_sparks:)\n";
342   printf FILE "[";
343   printf FILE join(", ",@all_local_sparks);
344   printf FILE "]\n";
345   printf FILE "  Mean, std. dev: $mean_local_spark,$std_dev_local_spark\n";
346   printf FILE 70 x "-" . "\n";
347   printf FILE "All global sparks  (\@all_global_sparks:)\n";
348   printf FILE "[";
349   printf FILE join(", ",@all_global_sparks);
350   printf FILE "]\n";
351   printf FILE "  Mean, std. dev: $mean_global_spark,$std_dev_global_spark\n";
352   printf FILE 70 x "-" . "\n";
353   printf FILE "All local sparks  (\@all_has:)\n";
354   printf FILE "[";
355   printf FILE join(", ",@all_has);
356   printf FILE "]\n";
357   printf FILE "  Mean, std. dev: $mean_ha,$std_dev_ha\n";
358   printf FILE 70 x "-" . "\n";
359
360
361   printf FILE ("CORR of runtime and heap alloc:  %f\n",$c_exec_ha);
362   printf FILE ("CORR of runtime and no. of sparks:  %f\n",$c_exec_sp);
363   printf FILE ("CORR of heap alloc and no. sparks:  %f\n",$c_ha_sp);
364   printf FILE ("CORR of runtime and local sparks:  %f\n",$c_exec_lsp);
365   printf FILE ("CORR of runtime and global sparks:  %f\n",$c_exec_gsp);
366   printf FILE ("CORR of heap alloc and local sparks:  %f\n",$c_ha_lsp);
367   printf FILE ("CORR of heap alloc and global sparks:  %f\n",$c_ha_gsp);
368   printf FILE ("CORR of runtime and communication time:  %f\n",$c_exec_ft);
369   printf FILE ("CORR of heap alloc and communication time:  %f\n",$c_ha_ft);
370   printf FILE ("CORR of local sparks and communication time:  %f\n",$c_lsp_ft);
371   printf FILE ("CORR of global_sparks and communication time:  %f\n",$c_gsp_ft);
372   close FILE;
373 }
374
375 if ( $opt_P ) {
376   do percentify($line_no,*exec_class);
377   do percentify($line_no,*exec_global_class);
378   do percentify($line_no,*exec_local_class);
379   do percentify($line_no,*comm_class);
380   do percentify($line_no,*comm_global_class);
381   do percentify($line_no,*comm_local_class);
382   do percentify($line_no,*spark_local_class);
383   do percentify($line_no,*spark_global_class);
384   do percentify($line_no,*ha_class);
385   do percentify($line_no,*ft_class);
386 }
387
388 # Produce cumulative RT graph and other (more or less) nice graphs
389 # ................................................................
390
391 do sort_and_cum();
392
393 # ----------------------------------------------------------------------------
394
395 open(IV,">INTERVALS") || die "Couldn't open file INTERVALS\n";
396 do write_interval(IV, 'G', &guess_interval(@all_rts));
397 do write_interval(IV, 'C', 0, int($mean_comm_perc), 
398                            int($mean_comm_perc+$std_dev_comm_perc), 50);
399 do write_interval(IV, 'S', &guess_interval(@all_sparks));
400 do write_interval(IV, 'A', &guess_interval(@all_has));
401 close(IV);
402
403 # ----------------------------------------------------------------------------
404 # Print results to STDOUT (mainly for testing)
405 # ----------------------------------------------------------------------------
406
407 if ( $opt_v ) {
408     do print_general_info();
409 }
410
411 # ----------------------------------------------------------------------------
412 # Write results to data files to be processed by GNUPLOT
413 # ----------------------------------------------------------------------------
414
415 do write_data($gran_file_name, $OPEN_INT, $logscale{'g'}, $#exec_times+1,
416               @exec_times, @exec_class);
417
418 do write_data($gran_global_file_name, $OPEN_INT, $logscale{'g'}, $#exec_times+1,
419               @exec_times, @exec_global_class);
420
421 do write_data($gran_local_file_name, $OPEN_INT, $logscale{'g'}, $#exec_times+1,
422               @exec_times, @exec_local_class);
423
424 do write_data($comm_file_name, $CLOSED_INT, $logscale{'c'}, $#comm_percs+1,
425               @comm_percs, @comm_class);
426
427 do write_data($comm_global_file_name, $CLOSED_INT, $logscale{'c'}, $#comm_percs+1,
428               @comm_percs, @comm_global_class);
429
430 do write_data($comm_local_file_name, $CLOSED_INT, $logscale{'c'}, $#comm_percs+1,
431               @comm_percs, @comm_local_class);
432
433 do write_data($spark_file_name, $OPEN_INT, $logscale{'s'}, $#sparks+1,
434               @sparks, @spark_class);
435
436 do write_data($spark_local_file_name, $OPEN_INT, $logscale{'s'}, $#sparks+1,
437               @sparks, @spark_local_class);
438
439 do write_data($spark_global_file_name, $OPEN_INT, $logscale{'s'}, $#sparks+1,
440               @sparks, @spark_global_class);
441
442 do write_data($ha_file_name, $OPEN_INT, $logscale{'a'}, $#has+1,
443               @has, @ha_class);
444
445 do write_data($ft_file_name, $OPEN_INT, $logscale{'g'}, $#fetch_times+1,
446               @fetch_times, @fetch_class);
447
448
449 # ----------------------------------------------------------------------------
450 # Run GNUPLOT over the data files and create figures
451 # ----------------------------------------------------------------------------
452
453 do gnu_plotify($gp_file_name); 
454
455 print "Script finished successfully!\n";
456
457 exit 0;
458
459 # ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
460
461 # ----------------------------------------------------------------------------
462 # Basic Operations on the intervals
463 # ----------------------------------------------------------------------------
464
465 sub get_index_open_int {
466     local ($value,@list) = @_;
467     local ($index,$right);
468
469     # print "get_index: searching for index of" . $value;
470     # print " in " . join(':',@list);
471
472       $index = 0;
473       $right = $list[$index];
474       while ( ($value >= $right) && ($index < $#list) ) {
475         $index++;
476         $right = $list[$index];
477       }
478     
479       return ( ($index == $#list) && ($value > $right) ) ? $index+1 : $index;
480 }
481
482 # ----------------------------------------------------------------------------
483
484 sub get_index_closed_int {
485     local ($value,@list) = @_;
486     local ($index,$right);
487
488       if ( ($value < $list[0]) || ($value > $list[$#list]) ) {
489           return ( -1 );
490       }
491
492       $index = 0;
493       $left = $list[$index];
494       while ( ($left <= $value) && ($index < $#list) ) {
495         $index++;
496         $left = $list[$index];
497       }
498       return ( $index-1 );
499 }
500
501 # ----------------------------------------------------------------------------
502 # Write operations
503 # ----------------------------------------------------------------------------
504
505 sub write_data {
506     local ($file_name, $open_int, $logaxes, $n, @rest) = @_;
507     local (@times) = splice(@rest,0,$n);
508     local (@class) = @rest;
509
510     open(GRAN,">$file_name") || die "Couldn't open file $file_name for output";
511
512     if ( $open_int == $OPEN_INT ) {
513
514       for ($i=0, 
515            $left = ( index($logaxes,"x") != -1 ? int($times[0]/2) : 0 ), 
516            $right = 0; 
517            $i < $n; 
518            $i++, $left = $right) {
519          $right = $times[$i];
520          print GRAN int(($left+$right)/2) . "  " . 
521                     ($class[$i] eq "" ? "0" : $class[$i]) . "\n"; 
522       }
523       print GRAN $times[$n-1]+(($times[$n-1]-$times[$n-2])/2) . "  " . 
524                  ($class[$n] eq "" ? "0" : $class[$n]) . "\n";
525
526      } else {
527
528       print GRAN ( (index($logaxes,"x") != -1) && ($times[0] == 0 ? int($times[1]/2) : ($times[$1] + $times[0])/2 ) .  "  " . $class[0] . "\n");
529       for ($i=1; $i < $n-2; $i++) {
530          $left = $times[$i];
531          $right = $times[$i+1];
532          print(GRAN ($left+$right)/2 . "  " . 
533                     ($class[$i] eq "" ? "0" : $class[$i]) . "\n"); 
534       }
535       print GRAN ($times[$n-1]+$times[$n-2])/2 . "  " . $class[$n-2]  if $n >= 2;
536     }
537
538     close(GRAN);
539 }
540
541 # ----------------------------------------------------------------------------
542
543 sub write_array {
544     local ($file_name,$n,@list) = @_;
545
546     open(FILE,">$file_name") || die "$file_name: $!";
547     for ($i=0; $i<=$#list; $i++) {
548         print FILE $i . "  " .  ( $list[$i] eq "" ? "0" : $list[$i] ) . "\n";
549     }
550
551     if ( $opt_D ) {
552         print "write_array: (" . join(", ",1 .. $#list) . ")\n for file $file_name returns: \n (0, $#list, &list_max(@list)\n";
553     } 
554
555     return ( (0, $#list, &list_max(@list), 
556               "(" . join(", ",1 .. $#list) . ")\n") );
557 }
558
559 # ----------------------------------------------------------------------------
560
561 sub write_cumulative_data {
562     local ($file_name1,$file_name2,@list) = @_;
563     local (@ns, @elems, @xtics, $i, $j, $n, $elem, $max_clust, $xtics_str,
564            $xstart, $xend, $file_name0);
565     local ($CLUST_SZ) = $no_of_clusters;
566
567     @ns = ();
568     @elems = ();
569     $file_name0 = $file_name1;
570     $file_name0 =~ s/\.dat$//;
571     $file_name0 .= "0.dat";
572     open(CUMM,">$file_name1") || die "Couldn't open file $file_name1 (error $!)\n";
573     open(CUMM0,">$file_name0") || die "Couldn't open file $file_name0 (error $!)\n";
574
575     print CUMM "1  0\n" unless $list[0] <= 1;
576     print CUMM0 "1  0\n" unless $list[0] <= 1;;
577
578     for ($i=0; $i <= $#list; $i++) {
579         $elem = $list[$i];
580         print CUMM ($elem) . "  " . int( (100 * ($i)) / ($#list+1) ) . "\n"  unless $elem == 0;
581         print CUMM0 ($elem) . "  " . $i . "\n" unless $elem == 0;;
582         for ($n=1; $i < $#list && $list[$i+1] == $elem; $i++, $n++) { }
583
584         print CUMM "$elem  " . int( (100 * ($i+1)) / ($#list+1) ) . "\n";
585         print CUMM0 "$elem  " . ($i+1) . "\n";
586         
587
588         if ( $opt_D ) {
589             print "\n--> Insert: n:  $n (elem $elem) in the above lists yields: \n  ";
590         }
591
592         # inlined version of do insert_elem($elem, $n, $#exs, @exs, @ns)
593         for ($j=0; $j<=$#ns && $ns[$j]>$n; $j++) { }
594         if ( $j > $#ns ) {
595             push(@ns,$n);
596             push(@elems,$elem);
597         } else {
598             splice(@ns,$j,0,$n);           # insert $n at pos $j and move the
599             splice(@elems,$j,0,$elem);     # rest of the array to the right
600         }
601
602         if ( $opt_D ) {
603             print "[" . join(", ",@ns) . "]" . "\n and \n" . 
604                   "[" . join(", ",@elems) . "]\n";
605         }
606       
607     }
608
609     close(CUMM);
610     close(CUMM0);
611
612     open(CLUSTERS_ALL,">" . (&dirname($file_name2)) . "CL-" .
613                       &basename($file_name2)) 
614         || die "Couldn't open file CL-$file_name2 (error $!)\n";
615     for ($i=0; $i <= $#ns; $i++) {
616         print CLUSTERS_ALL "$elems[$i]  $ns[$i]\n";
617     }
618     close(CLUSTERS_ALL);
619
620     # Interesting are only the first parts of the list (clusters!)
621     splice(@elems, $CLUST_SZ);
622     splice(@ns, $CLUST_SZ);
623
624     open(CLUSTERS,">$file_name2") || die "Couldn't open file $file_name2 (error $!)\n";
625
626     $xstart = &list_min(@elems);
627     $xend =   &list_max(@elems);
628     $step = ($xend - $xstart) / ( $CLUST_SZ == 1 ? 1 : ($CLUST_SZ-1));
629
630     @xtics = ();
631     for ($i=0, $x=$xstart; $i <= $#ns; $i++, $x+=$step) {
632         print CLUSTERS "$x  $ns[$i]\n";
633         push(@xtics,"\"$elems[$i]\" $x");
634     }
635     close(CLUSTERS);
636
637     $max_clust = $ns[0];
638     $xtics_str = "(" . join(", ",@xtics) . ")\n";
639
640     return ( ($xstart, $xend, $max_clust, $xtics_str) );
641 }
642
643 # ----------------------------------------------------------------------------
644
645 sub get_xtics {
646     local ($open_int, @list) = @_;
647
648     local ($str);
649
650     if ( $open_int == $OPEN_INT ) { 
651       $last = pop(@list);
652       $str = "( \">0\" 0";
653       foreach $x (@list) {
654           $str .= ", \">$x\" $x";
655       }
656       $str .= ", \"Large\" $last)\n";
657     } else { 
658       $left = shift(@list);
659       $right = shift(@list)  if $#list >= 0;
660       $last  = pop(@list)    if $#list >= 0;
661       $str = "( \"$left-$right\" " . $left;
662       $left = $right;
663       foreach $right (@list) {
664           $str .= ", \"$left-$right\" " . ($left+$right)/2;
665           $left = $right;
666       }
667       $str .= ", \"$left-$last\" " . $last .")\n"   unless $last eq "";
668     }
669     return $str;
670 }
671
672 # ----------------------------------------------------------------------------
673
674 sub print_line {
675     local ($start,$end,$is_global,$bbs,$ha,$rt,$bt,$bc,$ft,$fc,$my) = @_;
676
677     printf("START: %u, END: %u  ==> tot_exec: %u\n",
678            $start,$end,$end-$start);
679     printf("  BASIC_BLOCKS: %u, HEAP_ALLOCATIONS: %u \n",$bbs,$ha);
680     printf("  TOT_EXEC: %u = RUN_TIME %u + BLOCK_TIME %u + FETCH_TIME %u\n",
681            $end-$start,$rt,$bt,$ft);
682     printf("  BLOCK_TIME %u / BLOCK_COUNT %u; FETCH_TIME %u / FETCH_COUNT %u\n",
683            $bt,$bc,$ft,$fc);
684     printf("  %s  %s\n",
685            $is_global eq 'T' ? "GLOBAL" : "LOCAL",
686            $my eq 'T' ? "MANDATORY" : "NOT MANDATORY"); 
687 }
688            
689 # ----------------------------------------------------------------------------
690
691 sub gnu_plotify {
692   local ($gp_file_name) = @_;
693
694   local (@open_xrange,@closed_xrang,@spark_xrange,@ha_xrange, @ft_range,
695          $exec_xtics,$comm_perc_xtics,$spark_xtics,$has_xtics,
696          $cumu0_rts_file, $cumu0_has_file, $cumu0_fts_file);
697
698  $cumu0_rts_file = $cumulat_rts_file_name;
699  $cumu0_rts_file =~ s/\.dat$//;
700  $cumu0_rts_file .= "0.dat";
701
702  $cumu0_has_file = $cumulat_has_file_name;
703  $cumu0_has_file =~ s/\.dat$//;
704  $cumu0_has_file .= "0.dat";
705
706  $cumu0_fts_file = $cumulat_fts_file_name;
707  $cumu0_fts_file =~ s/\.dat$//;
708  $cumu0_fts_file .= "0.dat";
709
710  $cumu0_cps_file = $cumulat_cps_file_name;
711  $cumu0_cps_file =~ s/\.dat$//;
712  $cumu0_cps_file .= "0.dat";
713
714   @open_xrange = &range($OPEN_INT,$logscale{'g'},@exec_times);
715   @closed_xrange = &range($CLOSED_INT,$logscale{'c'},@comm_percs);
716   @spark_xrange = &range($OPEN_INT,$logscale{'s'},@sparks);
717   @ha_xrange = &range($OPEN_INT,$logscale{'a'},@has);
718   @ft_xrange = &range($OPEN_INT,$logscale{'f'},@fts);
719
720   $exec_xtics = $opt_T ? &get_xtics($OPEN_INT,@exec_times) : "" ;
721   $comm_perc_xtics = $opt_T ? &get_xtics($CLOSED_INT,@comm_percs) : "";
722   $spark_xtics = $opt_T ? &get_xtics($OPEN_INT,@sparks) : "";
723   $has_xtics = $opt_T ? &get_xtics($OPEN_INT,@has) : "";
724   $fts_xtics = $opt_T ? &get_xtics($OPEN_INT,@fts) : "";
725
726   open(GP_FILE,">$gp_file_name") || 
727       die "Couldn't open gnuplot file $gp_file_name for output\n";
728
729   if ( $opt_m ) {
730       print GP_FILE "set term postscript \"Roman\" 20\n";
731   } else {
732       print GP_FILE "set term postscript color \"Roman\" 20\n";
733   }
734
735   do write_gp_record(GP_FILE,
736                      $gran_file_name, &dat2ps_name($gran_file_name),
737                      "Granularity (pure exec. time)", $ylabel, $logscale{'g'},
738                      @open_xrange,$max_rt_class,$exec_xtics);
739   do write_gp_record(GP_FILE,
740                      $gran_global_file_name, &dat2ps_name($gran_global_file_name),
741                      "Granularity (pure exec. time) of exported threads",
742                      $ylabel, $logscale{'g'},
743                      @open_xrange,$max_rt_global_class,$exec_xtics);
744   do write_gp_record(GP_FILE,
745                      $gran_local_file_name, &dat2ps_name($gran_local_file_name),
746                      "Granularity (pure exec. time) of not exported threads",
747                      $ylabel,$logscale{'g'},
748                      @open_xrange,$max_rt_local_class,$exec_xtics);
749
750   do write_gp_record(GP_FILE,
751                      $comm_file_name, &dat2ps_name($comm_file_name),
752                      "% of communication",$ylabel,$logscale{'c'},
753                      @closed_xrange,$max_comm_perc_class,$comm_perc_xtics);
754   do write_gp_record(GP_FILE,
755                      $comm_global_file_name, &dat2ps_name($comm_global_file_name),
756                      "% of communication of exported threads",$ylabel,$logscale{'c'},
757                      @closed_xrange,$max_comm_perc_global_class,$comm_perc_xtics);
758   do write_gp_record(GP_FILE,
759                      $comm_local_file_name, &dat2ps_name($comm_local_file_name),
760                      "% of communication of not exported threads",$ylabel,$logscale{'c'},
761                      @closed_xrange,$max_comm_perc_local_class,$comm_perc_xtics);
762   do write_gp_record(GP_FILE,
763                      $ft_file_name, &dat2ps_name($ft_file_name),
764                      "Communication time", $ylabel, $logscale{'g'},
765                      @open_xrange,$max_ft_class,$fts_xtics);
766
767
768   do write_gp_record(GP_FILE,
769                      $spark_file_name, &dat2ps_name($spark_file_name),
770                      "No. of sparks created", $ylabel, $logscale{'s'},
771                      @spark_xrange,$max_spark_class,$spark_xtics);
772
773   do write_gp_record(GP_FILE,
774                      $spark_local_file_name, &dat2ps_name($spark_local_file_name),
775                      "No. of sparks created (parLocal)", $ylabel, $logscale{'s'},
776                      @spark_xrange,$max_spark_local_class,$spark_xtics);
777
778   do write_gp_record(GP_FILE,
779                      $spark_global_file_name, &dat2ps_name($spark_global_file_name),
780                      "No. of sparks created (parGlobal)", $ylabel, $logscale{'s'},
781                      @spark_xrange,$max_spark_global_class,$spark_xtics);
782
783   do write_gp_record(GP_FILE,
784                      $ha_file_name, &dat2ps_name($ha_file_name),
785                      "Heap Allocations (words)", $ylabel, $logscale{'a'},
786                      @ha_xrange,$max_ha_class,$has_xtics);
787
788   do write_gp_lines_record(GP_FILE,
789                            $cumulat_rts_file_name, &dat2ps_name($cumulat_rts_file_name),
790                            "Cumulative pure exec. times","% of threads",
791                            $logscale{'Cg'},
792                            $xend_cum_rts, $yend_cum_rts,""); 
793                            # $xtics_cluster_rts as last arg?
794
795   do write_gp_lines_record(GP_FILE,
796                            $cumulat_has_file_name, &dat2ps_name($cumulat_has_file_name),
797                            "Cumulative heap allocations","% of threads",
798                            $logscale{'Ca'},
799                            $xend_cum_has, $yend_cum_has,"");
800                            #  $xtics_cluster_has as last arg?
801
802   do write_gp_lines_record(GP_FILE,
803                            $cumu0_rts_file, &dat2ps_name($cumu0_rts_file),
804                            "Cumulative pure exec. times","Number of threads",
805                            $logscale{'Cg'},
806                            $xend_cum_rts, $yend_cum0_rts,""); 
807                            # $xtics_cluster_rts as last arg?
808
809   do write_gp_lines_record(GP_FILE,
810                            $cumu0_has_file, &dat2ps_name($cumu0_has_file),
811                            "Cumulative heap allocations","Number of threads",
812                            $logscale{'Ca'},
813                            $xend_cum_has, $yend_cum0_has,"");
814                            #  $xtics_cluster_has as last arg?
815
816   do write_gp_lines_record(GP_FILE,
817                            $cumulat_fts_file_name, &dat2ps_name($cumulat_fts_file_name),
818                            "Cumulative communication times","% of threads",
819                            $logscale{'Cg'},
820                            $xend_cum_fts, $yend_cum_fts,""); 
821                            # $xtics_cluster_rts as last arg?
822
823   do write_gp_lines_record(GP_FILE,
824                            $cumu0_fts_file, &dat2ps_name($cumu0_fts_file),
825                            "Cumulative communication times","Number of threads",
826                            $logscale{'Cg'},
827                            $xend_cum_fts, $yend_cum0_fts,""); 
828                            # $xtics_cluster_rts as last arg?
829
830   do write_gp_lines_record(GP_FILE,
831                            $cumulat_cps_file_name, &dat2ps_name($cumulat_cps_file_name),
832                            "Cumulative communication percentages","% of threads",
833                            "",  # No logscale here !
834                            $xend_cum_cps, $yend_cum_cps,""); 
835                            # $xtics_cluster_rts as last arg?
836
837   do write_gp_lines_record(GP_FILE,
838                            $cumu0_cps_file, &dat2ps_name($cumu0_cps_file),
839                            "Cumulative communication percentages","Number of threads",
840                            "",  # No logscale here !
841                            $xend_cum_cps, $yend_cum0_cps,""); 
842                            # $xtics_cluster_rts as last arg?
843
844   do write_gp_record(GP_FILE,
845                      $clust_rts_file_name, &dat2ps_name($clust_rts_file_name),
846                      "Pure exec. time", "No. of threads", $logscale{'CG'},
847                      $xstart_cluster_rts,$xend_cluster_rts,$max_cluster_rts,$xtics_cluster_rts);
848
849   do write_gp_record(GP_FILE,
850                      $clust_has_file_name, &dat2ps_name($clust_has_file_name),
851                      "Pure exec. time", "No. of threads", $logscale{'CA'},
852                      $xstart_cluster_has,$xend_cluster_has,$max_cluster_has,$xtics_cluster_has);
853
854   do write_gp_record(GP_FILE,
855                      $clust_fts_file_name, &dat2ps_name($clust_fts_file_name),
856                      "Communication time", "No. of threads", $logscale{'CG'},
857                      $xstart_cluster_fts,$xend_cluster_fts,$max_cluster_fts,$xtics_cluster_rts);
858
859
860   do write_gp_simple_record(GP_FILE,
861                      $pe_file_name, &dat2ps_name($pe_file_name),
862                      "Processing Elements (PEs)", "Ready Time (not running)", 
863                      $logscale{'Yp'},$xstart_pe,$xend_pe,$max_pe,$xtics_pe);
864
865   do write_gp_simple_record(GP_FILE,
866                      $sn_file_name, &dat2ps_name($sn_file_name),
867                      "Spark sites", "Pure exec. time", 
868                      $logscale{'Ys'},$xstart_sn,$xend_sn,$max_sn,$xtics_sn);
869
870   close GP_FILE;
871
872   print "Gnu plotting figures ...\n";
873   system "gnuplot $gp_file_name";
874
875   print "Extending thickness of impulses ...\n";
876   do gp_ext($gran_file_name,
877             $gran_global_file_name,
878             $gran_local_file_name,
879             $comm_file_name,
880             $comm_global_file_name,
881             $comm_local_file_name,
882             $spark_file_name,
883             $spark_local_file_name,
884             $spark_global_file_name,
885             $ha_file_name,
886             $ft_file_name,
887             $clust_fts_file_name,
888             $clust_rts_file_name,
889             $clust_has_file_name,
890             $pe_file_name,
891             $sn_file_name
892   );
893
894
895 }
896
897 # ----------------------------------------------------------------------------
898
899 sub gp_ext {
900     local (@file_names) = @_;
901     local ($file_name);
902     local ($ps_file_name);
903     local ($prg);
904
905     #$prg = system "which gp-ext-imp";
906     #print "  Using script $prg for impuls extension\n";
907     $prg = $ENV{GRANDIR} ? $ENV{GRANDIR} . "/bin/gp-ext-imp" 
908                          : $ENV{HOME} . "/bin/gp-ext-imp" ;
909     if ( $opt_v ) {
910         print "    (using script $prg)\n";
911     }
912
913     foreach $file_name (@file_names) {
914         $ps_file_name = &dat2ps_name($file_name);
915         system "$prg -w $ext_size -g $gray " . 
916                $ps_file_name  . " " . 
917                $ps_file_name . "2" ;
918         system "mv " . $ps_file_name . "2 " . $ps_file_name;
919     }
920 }
921
922 # ----------------------------------------------------------------------------
923
924 sub write_gp_record {
925     local ($file,$in_file,$out_file,$xlabel,$ylabel,$logaxes,
926            $xstart,$xend,$ymax,$xtics) = @_;
927
928     if ( $xstart >= $xend ) {
929         print ("WARNING: empty xrange [$xstart:$xend] changed to [$xstart:" . $xstart+1 . "]\n")        if ( $pedantic || $opt_v );
930         $xend = $xstart + 1;    
931     }
932
933     if ( $ymax <=0 ) {
934         $ymax = 2;
935         print "WARNING: empty yrange changed to [0:$ymax]\n"   if ( $pedantic || $opt_v );
936     }
937
938     $str = "set size " . $xsize . "," . $ysize . "\n" .
939            "set xlabel \"" . $xlabel . "\"\n" .
940            "set ylabel \"" . $ylabel . "\"\n" .
941            ($xstart eq "" ? "" 
942                           : "set xrange [" . int($xstart) .":" . int($xend) . "]\n") .
943            ($ymax eq "" ? "" 
944                         : "set yrange [" . (index($logaxes,"y") != -1 ? 1 : 0) . 
945                           ":" . &list_max(2,int($ymax+$ymax/5)) . "]\n") .
946            ($xtics ne "" ? "set xtics $xtics" : "") . 
947            "set tics out\n" .
948            "set border\n" .
949            "set title \"$nPEs PEs\"\n" .
950            "set nokey \n" .
951            "set nozeroaxis\n" .
952            "set format xy \"%g\"\n" .
953            (index($logaxes,"x") != -1 ? 
954                "set logscale x\n" : 
955                "set nologscale x\n") .
956            (index($logaxes,"y") != -1 ? 
957                "set logscale y\n" : 
958                "set nologscale y\n") .
959            "set output \"" . $out_file . "\"\n" .
960            "plot \"" . $in_file . "\" with impulses\n\n";
961     print $file $str;
962 }
963
964 # ----------------------------------------------------------------------------
965
966 sub write_gp_lines_record {
967     local ($file,$in_file,$out_file,$xlabel,$ylabel,$logaxes,
968            $xend,$yend,$xtics) = @_;
969
970     local ($str);
971
972     $str = "set xlabel \"" . $xlabel . "\"\n" .
973            "set ylabel \"" . $ylabel . "\"\n" .
974            "set xrange [" . ( index($logaxes,"x") != -1 ? 1 : 0 ) . ":$xend]\n" .
975            "set yrange [" . ( index($logaxes,"y") != -1 ? 1 : 0 ) . ":$yend]\n" .
976            "set border\n" .
977            "set nokey\n" .
978            ( $xtics ne "" ? "set xtics $xtics" : "" ) .
979            (index($logaxes,"x") != -1 ? 
980                "set logscale x\n" : 
981                "set nologscale x\n") .
982            (index($logaxes,"y") != -1 ? 
983                "set logscale y\n" : 
984                "set nologscale y\n") .
985            "set nozeroaxis\n" .
986            "set format xy \"%g\"\n" .
987            "set output \"" . $out_file . "\"\n" .
988            "plot \"" . $in_file . "\" with lines\n\n";
989     print $file $str;
990 }
991
992
993 # ----------------------------------------------------------------------------
994
995 sub write_gp_simple_record {
996     local ($file,$in_file,$out_file,$xlabel,$ylabel,$logaxes,
997            $xstart,$xend,$ymax,$xtics) = @_;
998
999     $str = "set size " . $xsize . "," . $ysize . "\n" .
1000            "set xlabel \"" . $xlabel . "\"\n" .
1001            "set ylabel \"" . $ylabel . "\"\n" .
1002            ($xstart eq "" ? "" 
1003                           : "set xrange [" . int($xstart) .":" . int($xend) . "]\n") .
1004            ($ymax eq "" ? "" 
1005                         : "set yrange [" . (index($logaxes,"y") != -1 ? 1 : 0) . 
1006                           ":" . &list_max(2,int($ymax+$ymax/5)) . "]\n") .
1007            ($xtics ne "" ? "set xtics $xtics" : "") . 
1008            "set border\n" .
1009            "set nokey\n" .
1010            "set tics out\n" .
1011            "set nozeroaxis\n" .
1012            "set format xy \"%g\"\n" .
1013            (index($logaxes,"x") != -1 ? 
1014                "set logscale x\n" : 
1015                "set nologscale x\n") .
1016            (index($logaxes,"y") != -1 ? 
1017                "set logscale y\n" : 
1018                "set nologscale y\n") .
1019            "set output \"" . $out_file . "\"\n" .
1020            "plot \"" . $in_file . "\" with impulses\n\n";
1021     print $file $str;
1022 }
1023
1024 # ----------------------------------------------------------------------------
1025
1026 sub dat2ps_name {
1027     local ($dat_name) = @_;
1028
1029     $dat_name =~ s/\.dat$/\.ps/;
1030     return ($dat_name);
1031 }
1032
1033 # ----------------------------------------------------------------------------
1034
1035 sub range {
1036     local ($open_int, $logaxes, @ints) = @_;
1037
1038     local ($range, $left_margin, $right_margin);
1039
1040     $range = $ints[$#ints]-$ints[0];
1041     $left_margin = 0; # $range/10;
1042     $right_margin = 0; # $range/10;
1043
1044     if ( $opt_D ) {
1045        print "\n==> Range: logaxes are $logaxes i.e. " . 
1046            (index($logaxes,"x") != -1 ? "matches x axis\n" 
1047                                       : "DOESN'T match x axis\n"); 
1048     }
1049     if ( index($logaxes,"x") != -1 ) {
1050         if ( $open_int == $OPEN_INT ) {
1051             return ( ($ints[0]/2-$left_margin, 
1052                       $ints[$#ints]+($ints[$#ints]-$ints[$#ints-1])/2+$right_margin) );
1053         } else {
1054             return ( ( &list_max(1,$ints[0]-$left_margin), 
1055                        $ints[$#ints]+($ints[$#ints]-$ints[$#ints-1])/2+$right_margin) );
1056         }
1057     } else {
1058         if ( $open_int == $OPEN_INT ) {
1059             return ( ($ints[0]/2-$left_margin, 
1060                       $ints[$#ints]+($ints[$#ints]-$ints[$#ints-1])/2+$right_margin) );
1061         } else {
1062             return ( ($ints[0]-$left_margin, 
1063                       $ints[$#ints]+($ints[$#ints]-$ints[$#ints-1])/2+$right_margin) );
1064         }
1065     }
1066 }
1067
1068 # ----------------------------------------------------------------------------
1069
1070 sub percentify {
1071     local ($sum,*classes) = @_;
1072
1073     for ($i=0; $i<=$#classes; $i++) {
1074         $classes[$i] = (100 * $classes[$i]) / $sum;
1075     }
1076 }
1077
1078 # ----------------------------------------------------------------------------
1079 # ToDo: get these statistics functions from "stat.pl"
1080 # ----------------------------------------------------------------------------
1081
1082 sub mean_std_dev {
1083     local ($sum,@list) = @_;
1084
1085     local ($n, $s, $s_);
1086
1087     #print "\nmean_std_dev: sum is $sum ; list has length $#list";
1088
1089     $n = $#list+1;
1090     $mean_value = $sum/$n;
1091
1092     $s_ = 0;
1093     foreach $x (@list) {
1094         $s_ += $x;
1095         $s += ($mean_value - $x) ** 2;  
1096     }
1097     if ( $sum != $s_ ) {
1098       print "ERROR in mean_std_dev: provided sum is wrong  " .
1099             "(provided: $sum; computed: $s_)\n"; 
1100       print " list_sum: " . &list_sum(@list) . "\n";
1101       exit (2);
1102     }
1103
1104     return ( ($mean_value, sqrt($s / ($n - 1)) ) );
1105 }
1106
1107 # ----------------------------------------------------------------------------
1108
1109 sub _mean_std_dev {
1110     return ( &mean_std_dev(&list_sum(@_), @_) );
1111 }
1112
1113 # ----------------------------------------------------------------------------
1114 # Compute covariance of 2 vectors, having their sums precomputed.
1115 # Input: $n   ... number of all elements in @list_1 as well as in @list_2
1116 #                 (i.e. $n = $#list_1+1 = $#list_2+1).
1117 #        $mean_1 ... mean value of all elements in @list_1
1118 #        @list_1 ... list of integers; first vector
1119 #        $mean_2 ... mean value of all elements in @list_2
1120 #        @list_2 ... list of integers; first vector
1121 # Output: covariance of @list_1 and @list_2 
1122 # ----------------------------------------------------------------------------
1123
1124 sub cov {
1125     local ($n, $mean_1, @rest) = @_;
1126     local (@list_1) = splice(@rest,0,$n);
1127     local ($mean_2, @list_2) = @rest;
1128
1129     local ($i,$s,$s_1,$s_2);
1130
1131     for ($i=0; $i<$n; $i++) {
1132         $s_1 += $list_1[$i];
1133         $s_2 += $list_2[$i];
1134         $s += ($mean_1 - $list_1[$i]) * ($mean_2 - $list_2[$i]);
1135     }
1136     if ( $mean_1 != ($s_1/$n) ) {
1137       print "ERROR in cov: provided mean value is wrong " . 
1138             "(provided: $mean_1; computed: " . ($s_1/$n) . ")\n"; 
1139       exit (2);
1140     }
1141     if ( $mean_2 != ($s_2/$n) ) {
1142       print "ERROR in cov: provided mean value is wrong " .
1143             "(provided: $mean_2; computed: " . ($s_2/$n) . ")\n"; 
1144       exit (2);
1145     }
1146     return ( $s / ($n - 1) ) ;
1147 }
1148
1149 # ----------------------------------------------------------------------------
1150 # Compute correlation of 2 vectors, having their sums precomputed.
1151 # Input: $n   ... number of all elements in @list_1 as well as in @list_2
1152 #                 (i.e. $n = $#list_1+1 = $#list_2+1).
1153 #        $sum_1 ... sum of all elements in @list_1
1154 #        @list_1 ... list of integers; first vector
1155 #        $sum_2 ... sum of all elements in @list_2
1156 #        @list_2 ... list of integers; first vector
1157 # Output: correlation of @list_1 and @list_2 
1158 # ----------------------------------------------------------------------------
1159
1160 sub corr {
1161     local ($n, $sum_1, @rest) = @_;
1162     local (@list_1) = splice(@rest,0,$n);
1163     local ($sum_2, @list_2) = @rest;
1164        
1165     local ($mean_1,$mean_2,$std_dev_1,$std_dev_2);
1166
1167     if ( $opt_D ) {
1168       print "\ncorr: n=$n  sum_1=$sum_1  sum_2=$sum_2\n";
1169       print "     list_sum of list_1=" . &list_sum(@list_1) . 
1170               "   list_sum of list_2=" . &list_sum(@list_2) . "\n";
1171       print "     len of list_1=$#list_1  len of list_2=$#list_2\n";
1172     }
1173
1174     ($mean_1, $std_dev_1) = &mean_std_dev($sum_1,@list_1);
1175     ($mean_2, $std_dev_2) = &mean_std_dev($sum_2,@list_2);
1176
1177     if ( $opt_D ) {
1178       print "corr: $mean_1, $std_dev_1; $mean_2, $std_dev_2\n";
1179     }
1180
1181     return ( ($std_dev_1 * $std_dev_2) == 0  ?
1182                0 : 
1183                &cov($n, $mean_1, @list_1, $mean_2, @list_2) / 
1184                ( $std_dev_1 * $std_dev_2 ) );
1185 }
1186
1187 # ----------------------------------------------------------------------------
1188
1189 sub list_sum {
1190     local (@list) = @_;
1191
1192     local ($sum);
1193
1194     foreach $x (@list) {
1195         $sum += $x;
1196     }
1197
1198     return ($sum);
1199 }
1200
1201 # ----------------------------------------------------------------------------
1202
1203 sub list_max {
1204     local (@list) = @_;
1205
1206     local ($max) = shift;
1207
1208     foreach $x (@list) {
1209         $max = $x  if $x > $max;
1210     }
1211
1212     return ($max);
1213 }
1214
1215 # ----------------------------------------------------------------------------
1216
1217 sub list_min {
1218     local (@list) = @_;
1219
1220     local ($min) = shift;
1221
1222     foreach $x (@list) {
1223         $min = $x  if $x < $min;
1224     }
1225
1226     return ($min);
1227 }
1228
1229 # ----------------------------------------------------------------------------
1230
1231 sub guess_interval {
1232     local (@list) = @_ ;
1233
1234     local ($min,$max,$sum,$mean,$std_dev,@intervals);
1235
1236     $min = &list_min(@list);
1237     $max = &list_max(@list);
1238     $sum = &list_sum(@list);
1239     ($mean, $std_dev) = &mean_std_dev($sum,@list);
1240
1241     @intervals = (int($mean-$std_dev),int($mean-$std_dev/2),int($mean),
1242                   int($mean+$std_dev/2),int($mean+$std_dev));
1243
1244     while ($#intervals>=0 && $intervals[0]<0) {
1245         shift(@intervals);
1246     }
1247
1248     return (@intervals);
1249 }
1250
1251 # ----------------------------------------------------------------------------
1252
1253 sub write_interval {
1254     local ($file,$flag,@intervals) = @_;
1255
1256     printf $file "$flag: (" . join(", ",@intervals) . ")\n";
1257 }
1258  
1259 # ----------------------------------------------------------------------------
1260
1261 sub read_template {
1262
1263     if ( $opt_v ) {
1264         print "Reading settings from template file $templ_file_name ...\n";
1265     }
1266
1267     open(TEMPLATE,$templ_file_name) || die "Couldn't open file $templ_file_name";
1268     while (<TEMPLATE>) {
1269       next if /^\s*$/ || /^--/;
1270       if (/^\s*G[:,;.\s]+([^\n]+)$/) {
1271           $list_str = $1;
1272           $list_str =~ s/[\(\)\[\]]//g;
1273           @exec_times = split(/[,;. ]+/, $list_str);
1274       } elsif (/^\s*F[:,;.\s]+([^\n]+)$/) {
1275           $list_str = $1;
1276           $list_str =~ s/[\(\)\[\]]//g;
1277           @fetch_times = split(/[,;. ]+/, $list_str);
1278       } elsif (/^\s*A[:,;.\s]+([^\n]+)$/) {
1279           $list_str = $1;
1280           $list_str =~ s/[\(\)\[\]]//g;
1281           @has = split(/[,;. ]+/, $list_str);
1282       } elsif (/^\s*C[:,;.\s]+([^\n]+)$/) {
1283           $list_str = $1;
1284           $list_str =~ s/[\(\)\[\]]//g;
1285           @comm_percs = split(/[,;. ]+/, $list_str);
1286       } elsif (/^\s*S[:,;.\s]+([^\n]+)$/) {
1287           $list_str = $1;
1288           $list_str =~ s/[\(\)\[\]]//g;
1289           @sparks = split(/[,;. ]+/, $list_str);
1290       } elsif (/^\s*g[:,;.\s]+([\S]+)$/) {
1291          ($gran_file_name,$gran_global_file_name, $gran_local_file_name) = 
1292            &mk_global_local_names($1);
1293       } elsif (/^\s*f[:,;.\s]+([\S]+)$/) {
1294          ($ft_file_name,$ft_global_file_name, $ft_local_file_name) = 
1295            &mk_global_local_names($1);
1296       } elsif (/^\s*c[:,;.\s]+([\S]+)$/) {
1297          ($comm_file_name, $comm_global_file_name, $comm_local_file_name) = 
1298            &mk_global_local_names($1);
1299       } elsif (/^\s*s[:,;.\s]+([\S]+)$/) {
1300          ($spark_file_name, $spark_global_file_name, $spark_local_file_name) = 
1301            &mk_global_local_names($1);
1302       } elsif (/^\s*a[:,;.\s]+([\S]+)$/) {
1303          ($ha_file_name, $ha_global_file_name, $ha_local_file_name) = 
1304            &mk_global_local_names($1);
1305       } elsif (/^\s*p[:,;.\s]+([\S]+)$/) {
1306          $gp_file_name = $1;
1307          $ps_file_name = &dat2ps_name($gp_file_name);
1308
1309       } elsif (/^\s*Xcorr[:,;.\s]+([\S]+)$/) {
1310          $corr_file_name = $1;
1311       } elsif (/^\s*Xcumulat-rts[:,;.\s]+([\S]+)$/) {
1312          $cumulat_rts_file_name = $1;
1313       } elsif (/^\s*Xcumulat-has[:,;.\s]+([\S]+)$/) {
1314          $cumulat_has_file_name = $1;
1315       } elsif (/^\s*Xcumulat-fts[:,;.\s]+([\S]+)$/) {
1316          $cumulat_fts_file_name = $1;
1317       } elsif (/^\s*Xcumulat-cps[:,;.\s]+([\S]+)$/) {
1318          $cumulat_cps_file_name = $1;
1319       } elsif (/^\s*Xclust-rts[:,;.\s]+([\S]+)$/) {
1320          $clust_rts_file_name = $1;
1321       } elsif (/^\s*Xclust-has[:,;.\s]+([\S]+)$/) {
1322          $clust_has_file_name = $1;
1323       } elsif (/^\s*Xclust-fts[:,;.\s]+([\S]+)$/) {
1324          $clust_fts_file_name = $1;
1325       } elsif (/^\s*Xclust-cps[:,;.\s]+([\S]+)$/) {
1326          $clust_cps_file_name = $1;
1327       } elsif (/^\s*Xpe[:,;.\s]+([\S]+)$/) {
1328          $pe_file_name = $1;
1329       } elsif (/^\s*Xsn[:,;.\s]+([\S]+)$/) {
1330          $sn_file_name = $1;
1331
1332       } elsif (/^\s*XRTS[:,;.\s]+([\S]+)$/) {
1333           $rts_file_name = $1;
1334       } elsif (/^\s*XHAS[:,;.\s]+([\S]+)$/) {
1335           $has_file_name = $1;
1336       } elsif (/^\s*XFTS[:,;.\s]+([\S]+)$/) {
1337           $fts_file_name = $1;
1338       } elsif (/^\s*XLSPS[:,;.\s]+([\S]+)$/) {
1339           $lsps_file_name = $1;
1340       } elsif (/^\s*XGSPS[:,;.\s]+([\S]+)$/) {
1341           $gsps_file_name = $1;
1342       } elsif (/^\s*XCPS[:,;.\s]+([\S]+)$/) {
1343           $cps_file_name = $1;
1344       } elsif (/^\s*XCCPS[:,;.\s]+([\S]+)$/) {
1345           $ccps_file_name = $1;
1346
1347       } elsif (/^\s*\-[:,;.\s]+([\S]+)$/) {
1348          $input = $1;
1349       } elsif (/^\s*L[:,;\s]+(.*)$/) {
1350          $str = $1;
1351          %logscale = ('g',"xy",'a',"xy",'Cg',"xy",'Ca',"xy",'Yp',"y",'Ys',"y") , next  if $str eq ".";
1352          $str =~ s/[\(\)\[\]]//g;
1353          %logscale = split(/[,;. ]+/, $str);
1354       } elsif (/^\s*i[:,;.\s]+([\S]+)$/) {
1355          $gray = $1;
1356       } elsif (/^\s*k[:,;.\s]+([\S]+)$/) {
1357          $no_of_clusters = $1;
1358       } elsif (/^\s*e[:,;.\s]+([\S]+)$/) {
1359          $ext_size = $1;
1360       } elsif (/^\s*v.*$/) {
1361          $verbose = 1;
1362       } elsif (/^\s*T.*$/) {
1363          $opt_T = 1;
1364       } elsif (/^\s*m.*$/) {
1365          $opt_m = 1;
1366      }
1367   }
1368   close(TEMPLATE);
1369 }      
1370
1371 # ----------------------------------------------------------------------------
1372
1373 sub mk_global_local_names { 
1374     local ($file_name) = @_;
1375
1376     $file_name .= ".dat" unless $file_name =~ /\.dat$/;
1377     $global_file_name = $file_name; 
1378     $global_file_name =~ s/\.dat/\-global\.dat/ ;
1379     $local_file_name = $file_name; 
1380     $local_file_name =~ s/\.dat/\-local\.dat/ ;
1381
1382     return ( ($file_name, $global_file_name, $local_file_name) );
1383 }
1384
1385 # ----------------------------------------------------------------------------
1386
1387 # ----------------------------------------------------------------------------
1388
1389 sub pre_process {
1390     local ($lines) = @_;
1391
1392     local (@all_rts, @all_comm_percs, @all_sparks, @all_local_sparks, 
1393            @all_global_sparks, @all_has, @fields,
1394            $line_no, $elem, $total_rt, $comm_perc,
1395            $pe, $start, $end, $is_global, $bbs, $ha, $rt, $bt, $ft, 
1396            $lsp, $gsp, $my);
1397
1398     if ( $opt_v ) {
1399         print "Preprocessing file $input ... \n";
1400     }
1401
1402     open(INPUT,"<$input") || die "Couldn't open input file $input";
1403
1404     do skip_header();
1405
1406     $line_no = 0;
1407     while (<INPUT>) {
1408         $line_no++;
1409         last  if $line_no > $lines;
1410         
1411         @fields = split(/,/,$_);
1412         
1413         foreach $elem (@fields) {
1414             foo : {
1415                 $pe = $1        , last foo   if $elem =~ /^\s*PE\s+(\d+).*$/;
1416                 $start = $1     , last foo   if $elem =~ /^\s*ST\s+(\d+).*$/;
1417                 $end = $1       , last foo   if $elem =~ /^\s*END\s+(\d+).*$/;
1418                 $is_global = $1 , last foo   if $elem =~ /^\s*GBL\s+(T|F).*$/;
1419                 $bbs = $1       , last foo   if $elem =~ /^\s*BB\s+(\d+).*$/;
1420                 $ha = $1        , last foo   if $elem =~ /^\s*HA\s+(\d+).*$/;
1421                 $rt = $1        , last foo   if $elem =~ /^\s*RT\s+(\d+).*$/;
1422                 $bt = $1, $bc = $2 , last foo if $elem =~ /^\s*BT\s+(\d+)\s+\((\d+)\).*$/;
1423                 $ft = $1, $fc = $2 , last foo if $elem =~ /^\s*FT\s+(\d+)\s+\((\d+)\).*$/;
1424                 $lsp = $1        , last foo   if $elem =~ /^\s*LS\s+(\d+).*$/;
1425                 $gsp = $1        , last foo   if $elem =~ /^\s*GS\s+(\d+).*$/;
1426                 $my = $1        , last foo   if $elem =~ /^\s*MY\s+(T|F).*$/;
1427             }
1428         }
1429
1430         $total_rt = $end - $start;
1431         $comm_perc = ( $total_rt == 0 ? 100 : (100 * $ft)/$total_rt );
1432         $sp = $lsp + $gsp;
1433         
1434         push(@all_rts,$rt);
1435         
1436         push(@all_comm_percs,$comm_perc); 
1437         
1438         push(@all_sparks,$sp);
1439         push(@all_local_sparks,$lsp);
1440         push(@all_global_sparks,$gsp);
1441         
1442         push(@all_has,$ha);
1443     }
1444
1445     close(INPUT);
1446
1447     @exec_times = &guess_interval(@all_rts);
1448     @sparks     = &guess_interval(@all_sparks);
1449     @has        = &guess_interval(@all_has);
1450
1451     ($m,$std_dev) = &_mean_std_dev(@all_comm_percs);
1452     @comm_percs = (0, int($m), int($std_dev), 100)       unless int($m) == 0;
1453     @comm_percs = (0, 1, 2, 5, 10, 50, 100)              if     int($m) == 0;
1454 }
1455
1456 # ----------------------------------------------------------------------------
1457
1458 sub process_options {
1459     if ( $opt_h ) {                      
1460         open(ME,$0) || die "Can't open myself ($0)";
1461         $n = 0;
1462         while (<ME>) {
1463             last if $_ =~ /^$/;
1464             print $_;
1465             $n++;
1466         }
1467         close(ME);
1468         
1469         # system "cat $0 | awk 'BEGIN { n = 0; } \
1470         #                             /^$/ { print n; \
1471         #                                    exit; } \
1472         #                                  { n++; }'"
1473         exit ;
1474     }
1475
1476     if ( $opt_W ) {
1477         $pedantic = 1;
1478     } else {
1479         $pedantic = 0;
1480     }
1481
1482     $input = $#ARGV == -1 ? "-" : $ARGV[0] ;
1483     
1484     if ( $#ARGV != 0 ) {
1485         #print "Usage: gran-extr [options] <sim-file>\n";
1486         #print "Use -h option to get details\n";
1487         #exit 1;
1488         
1489     }
1490     
1491     
1492     if ( ! $opt_t ) {
1493         do pre_process(20);
1494     }
1495     
1496     if ( $opt_g ) {
1497         ($gran_file_name, $gran_global_file_name, $gran_local_file_name) =       
1498             do mk_global_local_names($opt_g);
1499     } else {
1500         $gran_file_name = "gran.dat";
1501         $gran_global_file_name = "gran-global.dat";
1502         $gran_local_file_name = "gran-local.dat";
1503     }
1504     
1505     if ( $opt_c ) {
1506         ($comm_file_name, $comm_global_file_name, $comm_local_file_name) =       
1507             do mk_global_local_names($opt_c);
1508     } else {
1509         $comm_file_name = "comm.dat";
1510         $comm_global_file_name = "comm-global.dat";
1511         $comm_local_file_name = "comm-local.dat";
1512     }
1513     
1514     if ( $opt_f ) {
1515         ($ft_file_name, $ft_global_file_name, $ft_local_file_name) =       
1516             do mk_global_local_names($opt_c);
1517     } else {
1518         $ft_file_name = "ft.dat";
1519         $ft_global_file_name = "ft-global.dat";
1520         $ft_local_file_name = "ft-local.dat";
1521     }
1522     
1523     if ( $opt_s ) {
1524         ($spark_file_name, $spark_global_file_name, $spark_local_file_name) =  
1525             do mk_global_local_names($opt_s);
1526     } else {
1527         $spark_file_name = "spark.dat";
1528         $spark_global_file_name = "spark-global.dat";
1529         $spark_local_file_name = "spark-local.dat";
1530     }
1531     
1532     if ( $opt_a ) {
1533         ($ha_file_name, $ha_global_file_name, $ha_local_file_name) =       
1534             do mk_global_local_names($opt_a);
1535     } else {
1536         $ha_file_name = "ha.dat";
1537     }
1538     
1539     if ( $opt_p ) {
1540         $gp_file_name = $opt_p;
1541     } else {
1542         $gp_file_name = "gran.gp";
1543     }
1544     
1545     $ps_file_name = &dat2ps_name($gp_file_name);
1546     
1547     $corr_file_name = "CORR";
1548     $cumulat_rts_file_name = "cumulative-rts.dat";
1549     $cumulat_has_file_name = "cumulative-has.dat";
1550     $cumulat_fts_file_name = "cumulative-fts.dat";
1551     $cumulat_cps_file_name = "cumulative-cps.dat";
1552     $clust_rts_file_name = "clusters-rts.dat";
1553     $clust_has_file_name = "clusters-has.dat";
1554     $clust_fts_file_name = "clusters-fts.dat";
1555     $clust_cps_file_name = "clusters-cps.dat";
1556     $pe_file_name = "pe.dat";
1557     $sn_file_name = "sn.dat";
1558
1559     $pie_file_name = "Pie.ps";
1560
1561     $cps_file_name = "CPS";
1562     $fts_file_name = "FTS";
1563     $rts_file_name = "RTS";
1564     $has_file_name = "HAS";
1565     $lsps_file_name = "LSPS";
1566     $gsps_file_name = "GSPS";
1567     $ccps_file_name = "CCPS";
1568
1569     if ( $opt_l ) {
1570         $left_margin = $opt_l; 
1571     } else {
1572         $left_margin = 0; 
1573     }
1574     $left_perc_margin = 0;
1575     
1576     if ( $opt_r ) {
1577         $right_margin = $opt_r; 
1578     } else {
1579         $right_margin = 0; 
1580     }
1581     $right_perc_margin = 0;
1582     
1583     if ( $opt_x ) {
1584         $xsize = $opt_x;
1585     } else {
1586         $xsize = 1;
1587     }
1588     
1589     if ( $opt_y ) {
1590         $ysize = $opt_y;
1591     } else {
1592         $ysize = 1;
1593     }
1594     
1595     if ( $opt_e ) {
1596         $ext_size = $opt_e; 
1597     } else {
1598         $ext_size = 200; 
1599     }
1600     
1601     if ( $opt_i ) {
1602         $gray = $opt_i; 
1603     } else {
1604         $gray = 0; 
1605     }
1606     
1607     if ( $opt_k ) {
1608         $no_of_clusters = $opt_k; 
1609     } else {
1610         $no_of_clusters = 5; 
1611     }
1612     
1613     if ( $opt_L ) {
1614         $str = $opt_L;
1615         $str =~ s/[\(\)\[\]]//g;
1616         %logscale = split(/[,;. ]+/, $str);
1617         # $logscale = $opt_L;
1618     } else {
1619         %logscale = ();        # ('g',"xy",'a',"xy",'Cg',"xy",'Ca',"xy");
1620     }
1621     
1622 # $delta = do compute_delta(@exec_times);
1623 # $no_of_exec_times = $#exec_times;
1624     
1625     if ( $opt_G ) {
1626         $opt_G =~ s/[\(\)\[\]]//g;
1627         @exec_times = split(/[,;. ]+/, $opt_G);
1628         # @exec_times = split(/[,;. ]+/, ($opt_G =~ s/[\(\)]//g));
1629     } else {
1630         # @exec_times = (50, 100, 200, 300, 400, 500, 700);
1631     }
1632     
1633     if ( $opt_F ) {
1634         $opt_F =~ s/[\(\)\[\]]//g;
1635         @fetch_times = split(/[,;. ]+/, $opt_F);
1636         # @fetch_times = split(/[,;. ]+/, ($opt_F =~ s/[\(\)]//g));
1637     } else {
1638         # @fetch_times = (50, 100, 200, 300, 400, 500, 700);
1639     }
1640     
1641     if ( $opt_C ) {
1642         $opt_C =~ s/[\(\)\[\]]//g;
1643         @comm_percs = split(/[,;. ]+/, $opt_C);
1644     } else { 
1645         # @comm_percs = (0,10,20,30,50,100);
1646     } 
1647     
1648     if ( $opt_S ) {
1649         $opt_S =~ s/[\(\)\[\]]//g;
1650         @sparks = split(/[,;. ]+/, $opt_S);
1651     } else { 
1652         # @sparks = (0,5,10,50);
1653     } 
1654     
1655 # $delta_comm = do compute_delta(@comm_percs);
1656     
1657     if ( $opt_A ) {
1658         $opt_A =~ s/[\(\)\[\]]//g;
1659         @has = split(/[,;. ]+/, $opt_A);
1660     } else {
1661         # @has = (10, 100, 200, 300, 500, 1000);
1662     }
1663     
1664     if ( $opt_t ) {
1665         $templ_file_name = ( $opt_t eq '.' ? "TEMPL"     #   default file name
1666                              : $opt_t eq ',' ? "/users/fp/hwloidl/grasp/GrAn/bin/TEMPL"     #   global master template
1667                              : $opt_t eq '/' ? "/users/fp/hwloidl/grasp/GrAn/bin/T0"     #   template, that throws away most of the info
1668                              : $opt_t ); 
1669         do read_template();
1670         # see RTS2gran for use of template-package
1671     }
1672     
1673     $ylabel = $opt_P ? "% of threads" : "No. of threads";
1674 }  
1675
1676 # ----------------------------------------------------------------------------
1677
1678 sub print_verbose_message { 
1679
1680     print "-" x 70 . "\n";
1681     print "Setup: \n";
1682     print "-" x 70 . "\n";
1683     print "\nFilenames: \n";
1684     print "  Input file: $input\n";
1685     print "  Gran files: $gran_file_name $gran_global_file_name $gran_local_file_name\n"; 
1686     print "  Comm files: $comm_file_name $comm_global_file_name $comm_local_file_name\n";
1687     print "  Sparked threads file: $spark_file_name $spark_local_file_name $spark_global_file_name\n";
1688     print "  Heap file: $ha_file_name\n";
1689     print "  GNUPLOT file name: $gp_file_name   Correlation file name: $corr_file_name\n";
1690     print "  Cumulative RT file name: $cumulat_rts_file_name   \n  Cumulative HA file name: $cumulat_has_file_name\n";
1691     print "  Cluster RT file name: $clust_rts_file_name   \n  Cluster HA file name: $clust_has_file_name\n";
1692     print "  Cumulative runtimes file name:    $cumulat_rts_file_name\n";
1693     print "  Cumulative heap allocations file name   $cumulat_has_file_name\n";
1694     print "  Cluster run times file name:    $clust_rts_file_name\n";
1695     print "  Cluster heap allocations file name:    $clust_has_file_name\n";
1696     print "  PE load file name:    $pe_file_name\n";
1697     print "  Site size file name:    $sn_file_name\n";
1698     print "\nBoundaries: \n";
1699     print "  Gran boundaries: @exec_times\n";
1700     print "  Comm boundaries: @comm_percs\n";
1701     print "  Sparked threads boundaries: @sparks\n";
1702     print "  Heap boundaries: @has\n";
1703     print "\nOther pars: \n";
1704     print "  Left margin: $left_margin  Right margin: $right_margin\n";
1705     print "  GP-extension: $ext_size  GP xsize: $xsize  GP ysize: $ysize\n";
1706     print "  Gray scale: $gray  Smart x-tics is " . ($opt_T ? "ON" : "OFF") .
1707           "  Percentage y-axis is " . ($opt_P ? "ON" : "OFF") . "\n";
1708     print "  Log. scaling assoc list: ";
1709     while (($key,$value) = each %logscale) {
1710         print "$key: $value, ";
1711     }
1712     print "\n";
1713     print "  Active template file: $templ_file\n"              if $opt_t;  
1714     print "-" x 70 . "\n";
1715 }
1716
1717 # ----------------------------------------------------------------------------
1718
1719 sub sort_and_cum {
1720
1721 @sorted_rts = sort {$a <=> $b} @all_rts;
1722
1723 ($xstart_cluster_rts,$xend_cluster_rts,$max_cluster_rts,$xtics_cluster_rts) =
1724   &write_cumulative_data($cumulat_rts_file_name,$clust_rts_file_name,@sorted_rts);
1725
1726 $xend_cum_rts = pop(@sorted_rts);
1727 $yend_cum_rts = 100;
1728 $yend_cum0_rts = $#sorted_rts+1;         # unpercentified cum graph
1729
1730 open(RTS,">$rts_file_name") || die "$rts_file_name: $!";
1731 print RTS "Sorted list of all runtimes:\n";
1732 print RTS join("\n",@sorted_rts);
1733 close(RTS);
1734
1735 @sorted_has = sort {$a <=> $b} @all_has;
1736
1737 ($xstart_cluster_has,$xend_cluster_has,$max_cluster_has,$xtics_cluster_has) =
1738   &write_cumulative_data($cumulat_has_file_name,$clust_has_file_name,@sorted_has);
1739
1740 $xend_cum_has = pop(@sorted_has);
1741 $yend_cum_has = 100;
1742 $yend_cum0_has = $#sorted_has+1;         # unpercentified cum graph
1743
1744 open(HAS,">$has_file_name") || die "$has_file_name: $!";
1745 print HAS "Sorted list of all heap allocations:\n";
1746 print HAS join("\n",@sorted_has);
1747 close(HAS);
1748
1749 @sorted_lsps = sort {$a <=> $b} @all_local_sparks;
1750
1751 open(LSPS,">$lsps_file_name") || die "$lsps_file_name: $!";
1752 print LSPS "Sorted list of all local sparks:\n";
1753 print LSPS join("\n",@sorted_lsps);
1754 close(LSPS);
1755
1756 @sorted_gsps = sort {$a <=> $b} @all_global_sparks;
1757
1758 open(GSPS,">$gsps_file_name") || die "$gsps_file_name: $!";
1759 print GSPS "Sorted list of all global sparks:\n";
1760 print GSPS join("\n",@sorted_gsps);
1761 close(GSPS);
1762
1763 @sorted_fts = sort {$a <=> $b} @all_fts;
1764
1765 ($xstart_cluster_fts,$xend_cluster_fts,$max_cluster_fts,$xtics_cluster_fts) =
1766   &write_cumulative_data($cumulat_fts_file_name,$clust_fts_file_name,@sorted_fts);
1767
1768 $xend_cum_fts = pop(@sorted_fts);
1769 $yend_cum_fts = 100;
1770 $yend_cum0_fts = $#sorted_fts+1;         # unpercentified cum graph
1771
1772 open(FTS,">$fts_file_name") || die "$FTS_file_name: $!";
1773 print FTS "Sorted list of all communication times:\n";
1774 print FTS join("\n",@sorted_fts);
1775 close(FTS);
1776
1777 @sorted_comm_percs = sort {$a <=> $b} @all_comm_percs;
1778
1779 ($xstart_cluster_cps,$xend_cluster_cps,$max_cluster_cps,$xtics_cluster_cps) =
1780   &write_cumulative_data($cumulat_cps_file_name,$clust_cps_file_name,@sorted_comm_percs);
1781
1782 $xend_cum_cps = 100;  # pop(@sorted_comm_percs);
1783 $yend_cum_cps = 100;
1784 $yend_cum0_cps = $#sorted_comm_percs+1;         # unpercentified cum graph
1785
1786 open(CCPS,">$ccps_file_name") || die "$ccps_file_name: $!";
1787 print CCPS "Sorted list of all communication percentages:\n";
1788 print CCPS join("\n",@sorted_comm_percs);
1789 close(CCPS);
1790
1791 ($xstart_pe,$xend_pe,$max_pe,$xtics_pe) =
1792     &write_array($pe_file_name,$#pe_load,@pe_load);
1793
1794 ($xstart_sn,$xend_sn,$max_sn,$xtics_sn) =
1795     &write_array($sn_file_name,$#site_size,@site_size);
1796
1797 if ( $opt_D ) {
1798   print "After write_array: xstart, xend, max _sn: $xstart_sn,$xend_sn,$max_sn,$xtics_sn\n";
1799
1800 }
1801
1802 # ----------------------------------------------------------------------------
1803 # Compute statistical values (like mean, std_dev and especially corr coeff).
1804 # Write the important info to a file.
1805 # ----------------------------------------------------------------------------
1806
1807 sub do_statistics {
1808     local ($n) = @_;
1809
1810     if ( $n <= 1 ) {
1811         print "Sorry, no statistics for just $n threads\n";
1812         return -1;
1813     }
1814
1815 # Compute mean values and std deviations
1816 # ......................................
1817     
1818     ($mean_rt,$std_dev_rt) = &mean_std_dev($sum_rt,@all_rts);
1819     ($mean_comm_perc,$std_dev_comm_perc) = &mean_std_dev($sum_comm_perc,@all_comm_percs);
1820     ($mean_spark,$std_dev_spark) = &mean_std_dev($sum_sp,@all_sparks);
1821     ($mean_local_spark,$std_dev_local_spark) = &mean_std_dev($sum_local_sp,@all_local_sparks);
1822     ($mean_global_spark,$std_dev_global_spark) = &mean_std_dev($sum_global_sp,@all_global_sparks);
1823     ($mean_ha,$std_dev_ha) = &mean_std_dev($sum_ha,@all_has);
1824     ($mean_ft,$std_dev_ft) = &mean_std_dev($sum_ft,@all_fts);
1825     
1826 # Compute correlation coefficients
1827 # ................................
1828     
1829     $c_exec_ha = &corr($#all_rts+1,$sum_rt,@all_rts,$sum_ha,@all_has);
1830     $c_exec_sp = &corr($#all_rts+1,$sum_rt,@all_rts,$sum_sp,@all_sparks);
1831     $c_exec_lsp = &corr($#all_rts+1,$sum_rt,@all_rts,$sum_local_sp,@all_local_sparks);
1832     $c_exec_gsp = &corr($#all_rts+1,$sum_rt,@all_rts,$sum_global_sp,@all_global_sparks);
1833     $c_ha_sp   = &corr($#all_has+1,$sum_ha,@all_has,$sum_sp,@all_sparks);
1834     $c_ha_lsp   = &corr($#all_has+1,$sum_ha,@all_has,$sum_local_sp,@all_local_sparks);
1835     $c_ha_gsp   = &corr($#all_has+1,$sum_ha,@all_has,$sum_global_sp,@all_global_sparks);
1836     $c_exec_ft = &corr($#all_rts+1,$sum_rt,@all_rts,$sum_ft,@all_fts);
1837     $c_ha_ft = &corr($#all_has+1,$sum_ha,@all_has,$sum_ft,@all_fts);
1838     $c_lsp_ft = &corr($#all_local_sparks+1,$sum_local_sp,@all_local_sparks,$sum_ft,@all_fts);
1839     $c_gsp_ft = &corr($#all_global_sparks+1,$sum_global_sp,@all_global_sparks,$sum_ft,@all_fts);
1840     
1841 # Write corr coeffs into a file
1842 # .............................
1843     
1844     open(CORR,">$corr_file_name") || die "Couldn't open file $corr_file_name\n";
1845     #printf CORR ("%f\n%f\n%f\n%f\n%f",$c_exec_ha,$c_exec_lsp,$c_exec_gsp,$c_ha_lsp,$c_ha_gsp)   ;
1846     printf CORR ("CORR of runtime and heap alloc:  %f\n",$c_exec_ha);
1847     printf CORR ("CORR of runtime and no. of sparks:  %f\n",$c_exec_sp);
1848     printf CORR ("CORR of heap alloc and no. sparks:  %f\n",$c_ha_sp);
1849     printf CORR ("CORR of runtime and no. of local sparks:  %f\n",$c_exec_lsp);
1850     printf CORR ("CORR of runtime and no. of global sparks:  %f\n",$c_exec_gsp);
1851     printf CORR ("CORR of heap alloc and no. local sparks:  %f\n",$c_ha_lsp);
1852     printf CORR ("CORR of heap alloc and no. global sparks:  %f\n",$c_ha_gsp);
1853     printf CORR ("CORR of runtime and communication time:  %f\n",$c_exec_ft);
1854     printf CORR ("CORR of heap alloc and communication time:  %f\n",$c_ha_ft);
1855     printf CORR ("CORR of no. of local sparks and communication time:  %f\n",$c_lsp_ft);
1856     printf CORR ("CORR of no. of global sparks and communication time:  %f\n",$c_gsp_ft);
1857     close(CORR);
1858
1859 # These are needed later in the GNUPLOT files
1860 # ...........................................
1861
1862     $max_rt_class = &list_max(@exec_class);
1863     $max_rt_global_class = &list_max(@exec_global_class);
1864     $max_rt_local_class = &list_max(@exec_local_class);
1865     $max_comm_perc_class = &list_max(@comm_class);
1866     $max_comm_perc_global_class = &list_max(@comm_global_class);
1867     $max_comm_perc_local_class = &list_max(@comm_local_class);
1868     $max_spark_class = &list_max(@spark_class);
1869     $max_spark_local_class = &list_max(@spark_local_class);
1870     $max_spark_global_class = &list_max(@spark_global_class);
1871     $max_ha_class = &list_max(@ha_class);
1872     $max_ft_class = &list_max(@fetch_class);
1873
1874 }
1875
1876 # ----------------------------------------------------------------------------
1877 # This is written to STDOUT at the end of the file processing (before 
1878 # gnuplotting and such) if the verbose option is given.
1879 # ----------------------------------------------------------------------------
1880
1881 sub print_general_info {
1882
1883     printf("\nTotal number of lines: %d\n", $line_no);
1884     
1885     print "\nDistribution of execution times: \n";
1886     print " Intervals: " . join('|',@exec_times) . "\n";
1887     print " Total: " . join('|',@exec_class) . "\n";
1888     print " Global: " . join('|',@exec_global_class) . "\n";
1889     print " Local: " . join('|',@exec_local_class) . "\n";
1890     
1891     $total=0; foreach $i (@exec_class) { $total += $i ; }
1892     $global=0; foreach $i (@exec_global_class) { $global += $i ; }
1893     $local=0; foreach $i (@exec_local_class) { $local += $i ; }
1894     
1895     print " Sum of classes (should be " . $line_no . "): " . $total .
1896         "   (global/local)=(" . $global . "/" . $local . ")\n";
1897     print " Mean value: $mean_rt   Std dev: $std_dev_rt\n";
1898     
1899     print "\nPercentage of communication: \n";
1900     print " Intervals: " . join('|',@comm_percs) . "\n";
1901     print " Total: " . join('|',@comm_class) . "\n";
1902     print " Global: " . join('|',@comm_global_class) . "\n";
1903     print " Local: " . join('|',@comm_local_class) . "\n";
1904     print " Values outside closed int: Total: " . $outside .
1905         " Global: " . $outside_global . " Local: " . $outside_local . "\n";
1906     
1907     $total=0; foreach $i (@comm_class) { $total += $i ; }
1908     $global=0; foreach $i (@comm_global_class) { $global += $i ; }
1909     $local=0; foreach $i (@comm_local_class) { $local += $i ; }
1910     
1911     print " Sum of classes (should be " . $line_no . "): " . $total .
1912         "   (global/local)=(" . $global . "/" . $local . ")\n";
1913     print " Mean value: $mean_comm_perc   Std dev: $std_dev_comm_perc\n";
1914     
1915     print "\nSparked threads: \n";
1916     print " Intervals:   " . join('|',@sparks) . "\n";
1917     print " Total allocs: " . join('|',@spark_class) . "\n";
1918     
1919     $total=0; foreach $i (@spark_class) { $total += $i ; }
1920
1921     print " Sum of classes (should be " . $line_no . "): " . $total . "\n";
1922     print " Mean value: $mean_spark   Std dev: $std_dev_spark\n";
1923     
1924     print "\nHeap Allcoations: \n";
1925     print " Intervals:   " . join('|',@has) . "\n";
1926     print " Total allocs: " . join('|',@ha_class) . "\n";
1927     
1928     $total=0; foreach $i (@ha_class) { $total += $i ; }
1929     
1930     print " Sum of classes (should be " . $line_no . "): " . $total . "\n";
1931     print " Mean value: $mean_ha   Std dev: $std_dev_ha\n";
1932     print "\n";
1933     print "CORRELATION between runtimes and heap allocations: $c_exec_ha \n";
1934     print "CORRELATION between runtime and no. of sparks:  $c_exec_sp \n";
1935     print "CORRELATION between heap alloc and no. sparks:  $c_ha_sp \n";
1936     print "CORRELATION between runtimes and locally sparked threads: $c_exec_lsp \n";
1937     print "CORRELATION between runtimes and globally sparked threads: $c_exec_gsp \n";
1938     print "CORRELATION between heap allocations and locally sparked threads: $c_ha_lsp \n";
1939     print "CORRELATION between heap allocations and globally sparked threads: $c_ha_gsp \n";
1940     print "CORRELATION between runtime and communication time:  $c_exec_ft\n";
1941     print "CORRELATION between heap alloc and communication time:  $c_ha_ft\n";
1942     print "CORRELATION between no. of local sparks and communication time:  $c_lsp_ft\n";
1943     print "CORRELATION between no. of global sparks and communication time:  $c_gsp_ft\n";
1944     print "\n";
1945     
1946 }
1947
1948 # ----------------------------------------------------------------------------
1949 # Old (obsolete) stuff
1950 # ----------------------------------------------------------------------------
1951 #
1952 #for ($index=0; 
1953 #     $index <= &list_max($#spark_local_class,$#spark_local_class); 
1954 #     $index++) {
1955 #    $spark_class[$index] = $spark_local_class[$index] + $spark_global_class[$index];
1956 #}
1957 #
1958 #for ($index=0, $sum_sp=0; 
1959 #     $index <= &list_max($#all_local_sparks,$#all_global_sparks); 
1960 #     $index++) {
1961 #    $all_sparks[$index] = $all_local_sparks[$index] + $all_global_sparks[$index];
1962 #    $sum_sp += $all_sparks[$index];
1963 #}
1964 #
1965 # ----------------------------------------------------------------------------
1966 #
1967 #sub compute_delta {
1968 #    local (@times) = @_;
1969 #
1970 #    return ($times[$#times] -  $times[$#times-1]);
1971 #}
1972 #
1973 # ----------------------------------------------------------------------------
1974
1975 sub insert_elem {
1976     local ($elem,$val,$n,*list1,*list2) = @_;
1977     local (@small_part, $i, $len);
1978
1979     if ( $opt_D ) {
1980         print "Inserting val $val (with elem $elem) in the following list: \n" .
1981                @list . "\n yields the lists: \n  ";
1982     }
1983
1984     for ($i=0; $i<=$#list2 && $list2[$i]>$val; $i++) { }
1985     $len = $#list2 - $i + 1;
1986     if ( $len == 0 ) {
1987         push(@list1,$elem);
1988         push(@list2,$val);
1989     } else {
1990         splice(@list1,$i,0,$elem);
1991         splice(@list2,$i,0,$val);
1992     }
1993
1994     if ( $opt_D ) {
1995         print @list1 . "\n and \n" . @list2;
1996     }
1997
1998 }
1999
2000 # ----------------------------------------------------------------------------
2001
2002 sub skip_header {
2003     local ($in_header);
2004
2005     $in_header = 9;
2006     while (<INPUT>) {
2007         if ( $in_header = 9 ) {
2008             if (/^=/) {
2009                 $gum_style_gr = 1;
2010                 $in_header = 0;
2011                 $prg = "????";          # 
2012                 $pars = "-b??????";             # 
2013                 $nPEs =  1; # 
2014                 $lat =  1;
2015                 return ($prg, $pars, $nPEs, $lat);
2016             } else {
2017                 $gum_style_gr = 0;
2018                 $in_header = 1;
2019             }
2020             
2021         }
2022         $prg = $1, $pars = $2  if /^Granularity Simulation for\s+(\w+)\s+(.*)$/;
2023         $nPEs = $1             if /^PEs\s+(\d+)/;
2024         $lat = $1, $fetch = $2 if /^Latency\s+(\d+)[^F]+Fetch\s+(\d+)/;
2025
2026         last             if /^\+\+\+\+\+/;
2027     }
2028 }
2029
2030 # ----------------------------------------------------------------------------
2031
2032 sub write_pie_chart {
2033     local ($rt_perc, $bt_perc, $ft_perc, $it_perc);
2034     local ($title, $title_sz, $label_sz, $x_center, $y_center, $radius); 
2035
2036     $PieChart = "/users/fp/hwloidl/grasp/GrAn/bin/PieChart.ps";
2037
2038     $title = "Original Glaswegian Communication Pie (tm)";
2039     $title_sz = 24;
2040     $label_sz = 12;
2041     $x_center = 300; 
2042     $y_center = 400;
2043     $radius = 100;
2044
2045     open(PIE,">$pie_file_name") || die "$pie_file_name: $!";
2046     
2047     print PIE "%!PS-Adobe-2.0\n";
2048     print PIE "%%Title: Pie Chart\n";
2049     print PIE "%%Creator: gran-extr\n";
2050     print PIE "%%CreationDate: Ides of March 44 B.C.\n";
2051     print PIE "%%EndComments\n";
2052     print PIE "\n";
2053     print PIE "% Def of PieChart is taken from:\n";
2054     print PIE "% ($PieChart) run\n";
2055     print PIE "\n";
2056
2057     open(PIE_CHART,"<$PieChart") || die "$PieChart: $!";
2058     while (<PIE_CHART>){
2059         print PIE $_;
2060     }
2061     close (PIE_CHART);
2062     print PIE "\n";
2063
2064     $rt_perc = $tot_rt / $tot_total_rt;
2065     $bt_perc = $tot_bt / $tot_total_rt;
2066     $ft_perc = $tot_ft / $tot_total_rt;
2067     $it_perc = $tot_it / $tot_total_rt;
2068
2069     print PIE "($title) $title_sz $label_sz  % Title, title size and label size\n" .
2070               "[                     % PS Array of (descrition, percentage [0, .., 1])\n" .
2071               "[(Run Time) $rt_perc]\n" .
2072               "[(Block Time) $bt_perc]\n" .
2073               "[(Fetch Time) $ft_perc]\n" .
2074               "[(Ready Time) $it_perc]\n" .
2075               "] $x_center $y_center $radius DrawPieChart\n";
2076     print PIE "showpage\n";
2077
2078     close(PIE);
2079 }
2080
2081 # ----------------------------------------------------------------------------
2082
2083 sub basename {
2084     local ($in_str) = @_;
2085     local ($str,$i) ;
2086
2087     $i = rindex($in_str,"/");
2088     if ($i == -1) {
2089         $str = $in_str;
2090     } else {
2091         $str = substr($in_str,$i+1) ;
2092     }
2093
2094     return $str;
2095 }
2096
2097 # ----------------------------------------------------------------------------
2098
2099 sub dirname {
2100     local ($in_str) = @_;
2101     local ($str,$i) ;
2102
2103     $i = rindex($in_str,"/");
2104     if ($i == -1) {
2105         $str = "";
2106     } else {
2107         $str = substr($in_str,0,$i+1) ;
2108     }
2109
2110     return $str;
2111 }
2112
2113 # ----------------------------------------------------------------------------
2114