+#!/usr/local/bin/perl
+##############################################################################
+# Last modified: Time-stamp: <Sat Oct 28 1995 23:49:48 Stardate: [-31]6509.75 hwloidl>
+# (C) Hans Wolfgang Loidl
+#
+# Usage: gran-extr [options] [<sim-file>]
+#
+# Takes a file <sim-file> generated by running the GrAnSim simulator and
+# produces data files that should be used as input for gnuplot.
+# This script produces figures for:
+# runtime of tasks
+# percentage of communication
+# heap allocation
+# number of created sparks
+# cumulative no. of tasks over runtime
+# Furthermore, it computes the correlation between runtime and heap allocation.
+#
+# Options:
+# -g <file> ... filename of granularity file to be produced; should end with
+# .dat; -global and -local will be automatically inserted for
+# other versions.
+# -c <file> ... filename of communication file to be produced; should end with
+# .dat; -global and -local will be automatically inserted for
+# other versions.
+# -s <file> ... filename of sparked-threads file to be produced; should end w/
+# .dat; -global and -local will be automatically inserted for
+# other versions.
+# -a <file> ... filename of heap alloc. file to be produced; should end with
+# .dat;
+# -f <file> ... filename of communication time file to be produced;
+# should end with .dat;
+# -p <file> ... filename of GNUPLOT file that is prouced and executed.
+# -G <LIST> ... provide a list of boundaries for the Intervals used in the
+# granularity figure; must be a Perl list e.g. (10, 20, 50)
+# this is interpreted as being open to left and right.
+# -C <LIST> ... provide a list of boundaries for the Intervals used in the
+# communication figure; must be a Perl list e.g. (10, 20, 50)
+# this is interpreted as being closed to left and right.
+# -S <LIST> ... provide a list of boundaries for the Intervals used in the
+# sparked-threads figure; must be a Perl list e.g. (10, 20, 50)
+# this is interpreted as being closed to left and right.
+# -A <LIST> ... provide a list of boundaries for the Intervals used in the
+# heap alloc figure; must be a Perl list e.g. (10, 20, 50)
+# this is interpreted as being closed to left and right.
+# -F <LIST> ... provide a list of boundaries for the Intervals used in the
+# comm. time figure; must be a Perl list e.g. (10, 20, 50)
+# this is interpreted as being open to left and right.
+# -l <int> ... left margin in the produced figures.
+# -r <int> ... right margin in the produced figures.
+# -x <int> ... enlargement of figure along x-axis.
+# -y <int> ... enlargement of figure along y-axis.
+# -e <int> ... thickness of impulses in figure.
+# -i <rat> ... set the gray level of the impulses to <rat>; <rat> must be
+# between 0 and 1 with 0 meaning black.
+# -k <n> ... number of klusters (oops, clusters, I mean ;)
+# -P ... print percentage of threads rather than absolute number of
+# threads on the y axis
+# -t <file> ... use template <file> for interval settings and file names
+# Syntax of a line in the template file:
+# <flag>: <arg>
+# -T ... use smart xtics rather than GNUPLOT default x-axis naming.
+# -L ... use logarithmic scale for all figures.
+# -W ... print warnings
+# -m ... generate monchrome output
+# -h ... help; print this text.
+# -v ... verbose mode.
+#
+##############################################################################
+
+# ----------------------------------------------------------------------------
+# Command line processing and initialization
+# ----------------------------------------------------------------------------
+
+require "getopts.pl";
+
+&Getopts('hvWTPDmt:L:g:f:c:s:a:p:G:F:C:S:A:l:r:x:y:e:i:k:');
+
+do process_options();
+
+$OPEN_INT = 1;
+$CLOSED_INT = 0;
+
+if ( $opt_v ) {
+ do print_verbose_message ();
+}
+
+# ----------------------------------------------------------------------------
+# The real thing
+# ----------------------------------------------------------------------------
+
+open(INPUT,"<$input") || die "Couldn't open input file $input";
+
+do skip_header();
+
+$tot_total_rt = 0;
+$tot_rt = 0;
+$tot_bt = 0;
+$tot_ft = 0;
+$tot_it = 0;
+$gum_style_gr = 0;
+
+$line_no = 0;
+while (<INPUT>) {
+ next if /^--/; # Comment lines start with --
+ next if /^\s*$/; # Skip empty lines
+ $line_no++;
+ @fields = split(/[:,]/,$_);
+ $has_end = 0;
+
+ foreach $elem (@fields) {
+ foo : {
+ $pe = $1, $end = $2 , last foo if $elem =~ /^\s*PE\s+(\d+)\s+\[(\d+)\].*$/;
+ $tn = $1, $has_end = 1 , last foo if $elem =~ /^\s*END\s+(\w+).*$/;
+ # $tn = $1 , last foo if $elem =~ /^\s*TN\s+(\w+).*$/;
+ $sn = $1 , last foo if $elem =~ /^\s*SN\s+(\d+).*$/;
+ $start = $1 , last foo if $elem =~ /^\s*ST\s+(\d+).*$/;
+ $is_global = $1 , last foo if $elem =~ /^\s*EXP\s+(T|F).*$/;
+ $bbs = $1 , last foo if $elem =~ /^\s*BB\s+(\d+).*$/;
+ $ha = $1 , last foo if $elem =~ /^\s*HA\s+(\d+).*$/;
+ $rt = $1 , last foo if $elem =~ /^\s*RT\s+(\d+).*$/;
+ $bt = $1, $bc = $2 , last foo if $elem =~ /^\s*BT\s+(\d+)\s+\((\d+)\).*$/;
+ $ft = $1, $fc = $2 , last foo if $elem =~ /^\s*FT\s+(\d+)\s+\((\d+)\).*$/;
+ $lsp = $1 , last foo if $elem =~ /^\s*LS\s+(\d+).*$/;
+ $gsp = $1 , last foo if $elem =~ /^\s*GS\s+(\d+).*$/;
+ $my = $1 , last foo if $elem =~ /^\s*MY\s+(T|F).*$/;
+ }
+ }
+
+ next unless $has_end == 1;
+
+ $total_rt = $end - $start;
+ $ready_time = $total_rt - $rt - $bt - $ft;
+
+ # ------------------------------------------------------------------------
+ # Accumulate runtime, block time, fetch time and ready time over all threads
+ # ------------------------------------------------------------------------
+
+ $tot_total_rt += $total_rt;
+ $tot_rt += $rt;
+ $tot_bt += $bt;
+ $tot_ft += $ft;
+ $tot_it += $ready_time;
+
+ # ------------------------------------------------------------------------
+ # Gather statistics about `load' on the PEs
+ # ------------------------------------------------------------------------
+
+ print "WARNING: ready time of thread is <0: $ready_time\n" if $pedantic && ($ready_time <0);
+ $pe_load[$pe] += $ready_time;
+
+ if ( $opt_D ) {
+ print "Adding $ready_time to the load time of PE no. $pe yielding $pe_load[$pe]\n";
+ }
+
+ # ------------------------------------------------------------------------
+ # Gather statistics about the size of a spark site
+ # ------------------------------------------------------------------------
+
+ $site_size[$sn] += $rt;
+
+ if ( $opt_D ) {
+ print "Adding $rt to the size of site $sn yielding $site_size[$sn]\n";
+ }
+
+ # ------------------------------------------------------------------------
+ # Gather statistics about pure exec time
+ # ------------------------------------------------------------------------
+
+ push(@all_rts,$rt);
+ $sum_rt += $rt;
+ $max_rt = $rt if $rt > $max_rt;
+
+ $index = do get_index_open_int($rt,@exec_times);
+ $exec_class[$index]++;
+
+ if ( $is_global eq 'T' ) {
+ $exec_global_class[$index]++;
+ } else {
+ $exec_local_class[$index]++;
+ }
+
+ # ------------------------------------------------------------------------
+ # Gather statistics about communication time (absolute time rather than %)
+ # ------------------------------------------------------------------------
+
+ # Note: Communicatin time is fetch time
+
+ push(@all_fts,$ft);
+ $sum_ft += $ft;
+ $max_ft = $ft if $ft > $max_ft;
+
+ $index = do get_index_open_int($ft,@fetch_times);
+ $fetch_class[$index]++;
+
+ if ( $is_global eq 'T' ) {
+ $fetch_global_class[$index]++;
+ } else {
+ $fetch_local_class[$index]++;
+ }
+
+ # ------------------------------------------------------------------------
+ # Gather statistics about communication percentage
+ # ------------------------------------------------------------------------
+
+ $comm_perc = ( $total_rt == 0 ? 100 : (100 * $ft)/$total_rt );
+
+ push(@all_comm_percs,$comm_perc);
+ $sum_comm_perc += $comm_perc;
+ $max_comm_perc = $comm_perc if $comm_perc > $max_comm_perc;
+
+ $index = do get_index_closed_int( $comm_perc, @comm_percs );
+ if ( $index != -1 ) {
+ $comm_class[$index]++;
+ } else {
+ print "WARNING: value " . $comm_perc . " not in range (t_rt=$total_rt; ft=$ft)\n" if $pedantic;
+ $outside++;
+ }
+
+ if ( $is_global eq 'T' ) {
+ if ( $index != -1 ) {
+ $comm_global_class[$index]++;
+ } else {
+ $outside_global++;
+ }
+ } else {
+ if ( $index != -1 ) {
+ $comm_local_class[$index]++;
+ } else {
+ $outside_local++;
+ }
+ }
+
+ # ------------------------------------------------------------------------
+ # Gather statistics about locally sparked threads
+ # ------------------------------------------------------------------------
+
+ push(@all_local_sparks,$lsp);
+ $sum_local_sp += $lsp;
+ $max_local_sp = $lsp if $lsp > $max_local_sp;
+
+ $index = do get_index_open_int($lsp,@sparks);
+ $spark_local_class[$index]++;
+
+ # ------------------------------------------------------------------------
+ # Gather statistics about globally sparked threads
+ # ------------------------------------------------------------------------
+
+ push(@all_global_sparks,$gsp);
+ $sum_global_sp += $gsp;
+ $max_global_sp = $gsp if $gsp > $max_global_sp;
+
+ $index = do get_index_open_int($gsp,@sparks);
+ $spark_global_class[$index]++;
+
+ # ------------------------------------------------------------------------
+ # Add the above two entries to get the total number of sparks
+ # ------------------------------------------------------------------------
+
+ $sp = $lsp + $gsp;
+
+ push(@all_sparks,$sp);
+ $sum_sp += $sp;
+ $max_sp = $sp if $sp > $max_sp;
+
+ $index = do get_index_open_int($sp,@sparks);
+ $spark_class[$index]++;
+
+ # ------------------------------------------------------------------------
+ # Gather statistics about heap allocations
+ # ------------------------------------------------------------------------
+
+ push(@all_has,$ha);
+ $sum_ha += $ha;
+ $max_ha = $ha if $ha > $max_ha;
+
+ $index = do get_index_open_int($ha,@has);
+ $ha_class[$index]++;
+
+ # do print_line($start,$end,$is_global,$bbs,$ha,$rt,$bt,$bc,$ft,$fc,$my);
+}
+
+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;
+
+# ----------------------------------------------------------------------------
+
+do write_pie_chart();
+
+# ----------------------------------------------------------------------------
+# Statistics
+# ----------------------------------------------------------------------------
+
+if ( $opt_D ) {
+ print "Lengths:\n" .
+ " all_rts: $#all_rts;\n" .
+ " all_comm_percs: $#all_comm_percs;\n" .
+ " all_sparks: $#all_sparks; \n" .
+ " all_local_sparks: $#all_local_sparks; \n" .
+ " all_global_sparks: $#all_global_sparks; \n" .
+ " all_has: $#all_has\n" .
+ " all_fts: $#all_fts;\n";
+
+
+ print "No of elems in all_rts: $#all_rts with sum $sum_rt\n";
+ print "No of elems in all_comm_percs: $#all_rts with sum $sum_comm_perc\n";
+ print "No of elems in all_has: $#all_has with sum $sum_ha\n";
+ print "No of elems in all_fts: $#all_fts with sum $sum_ft\n";
+
+}
+
+do do_statistics($line_no);
+
+# Just for debugging
+# ..................
+
+if ( $opt_D ) {
+ open(FILE,">LOG") || die "Couldn't open file LOG\n";
+ printf FILE "All total runtimes (\@all_rts:)\n";
+ printf FILE "[";
+ printf FILE join(", ",@all_rts);
+ printf FILE "]\n";
+ printf FILE " Mean, std. dev: $mean_rt, $std_dev_rt\n";
+ printf FILE 70 x "-" . "\n";
+ printf FILE "All communication times (\@all_fts:)\n";
+ printf FILE "[";
+ printf FILE join(", ",@all_fts);
+ printf FILE "]\n";
+ printf FILE " Mean, std. dev: $mean_ft, $std_dev_ft\n";
+ printf FILE 70 x "-" . "\n";
+ printf FILE "All communication percentages (\@all_comm_percs:)\n";
+ printf FILE "[";
+ printf FILE join(", ",@all_comm_percs);
+ printf FILE "]\n";
+ printf FILE " Mean, std. dev: $mean_comm_perc,$std_dev_comm_perc\n";
+ printf FILE 70 x "-" . "\n";
+ printf FILE "All sparks (\@all_sparks:)\n";
+ printf FILE "[";
+ printf FILE join(", ",@all_sparks);
+ printf FILE "]\n";
+ printf FILE " Mean, std. dev: $mean_spark,$std_dev_spark\n";
+ printf FILE 70 x "-" . "\n";
+ printf FILE "All local sparks (\@all_local_sparks:)\n";
+ printf FILE "[";
+ printf FILE join(", ",@all_local_sparks);
+ printf FILE "]\n";
+ printf FILE " Mean, std. dev: $mean_local_spark,$std_dev_local_spark\n";
+ printf FILE 70 x "-" . "\n";
+ printf FILE "All global sparks (\@all_global_sparks:)\n";
+ printf FILE "[";
+ printf FILE join(", ",@all_global_sparks);
+ printf FILE "]\n";
+ printf FILE " Mean, std. dev: $mean_global_spark,$std_dev_global_spark\n";
+ printf FILE 70 x "-" . "\n";
+ printf FILE "All local sparks (\@all_has:)\n";
+ printf FILE "[";
+ printf FILE join(", ",@all_has);
+ printf FILE "]\n";
+ printf FILE " Mean, std. dev: $mean_ha,$std_dev_ha\n";
+ printf FILE 70 x "-" . "\n";
+
+
+ printf FILE ("CORR of runtime and heap alloc: %f\n",$c_exec_ha);
+ printf FILE ("CORR of runtime and no. of sparks: %f\n",$c_exec_sp);
+ printf FILE ("CORR of heap alloc and no. sparks: %f\n",$c_ha_sp);
+ printf FILE ("CORR of runtime and local sparks: %f\n",$c_exec_lsp);
+ printf FILE ("CORR of runtime and global sparks: %f\n",$c_exec_gsp);
+ printf FILE ("CORR of heap alloc and local sparks: %f\n",$c_ha_lsp);
+ printf FILE ("CORR of heap alloc and global sparks: %f\n",$c_ha_gsp);
+ printf FILE ("CORR of runtime and communication time: %f\n",$c_exec_ft);
+ printf FILE ("CORR of heap alloc and communication time: %f\n",$c_ha_ft);
+ printf FILE ("CORR of local sparks and communication time: %f\n",$c_lsp_ft);
+ printf FILE ("CORR of global_sparks and communication time: %f\n",$c_gsp_ft);
+ close FILE;
+}
+
+if ( $opt_P ) {
+ do percentify($line_no,*exec_class);
+ do percentify($line_no,*exec_global_class);
+ do percentify($line_no,*exec_local_class);
+ do percentify($line_no,*comm_class);
+ do percentify($line_no,*comm_global_class);
+ do percentify($line_no,*comm_local_class);
+ do percentify($line_no,*spark_local_class);
+ do percentify($line_no,*spark_global_class);
+ do percentify($line_no,*ha_class);
+ do percentify($line_no,*ft_class);
+}
+
+# Produce cumulative RT graph and other (more or less) nice graphs
+# ................................................................
+
+do sort_and_cum();
+
+# ----------------------------------------------------------------------------
+
+open(IV,">INTERVALS") || die "Couldn't open file INTERVALS\n";
+do write_interval(IV, 'G', &guess_interval(@all_rts));
+do write_interval(IV, 'C', 0, int($mean_comm_perc),
+ int($mean_comm_perc+$std_dev_comm_perc), 50);
+do write_interval(IV, 'S', &guess_interval(@all_sparks));
+do write_interval(IV, 'A', &guess_interval(@all_has));
+close(IV);
+
+# ----------------------------------------------------------------------------
+# Print results to STDOUT (mainly for testing)
+# ----------------------------------------------------------------------------
+
+if ( $opt_v ) {
+ do print_general_info();
+}
+
+# ----------------------------------------------------------------------------
+# Write results to data files to be processed by GNUPLOT
+# ----------------------------------------------------------------------------
+
+do write_data($gran_file_name, $OPEN_INT, $logscale{'g'}, $#exec_times+1,
+ @exec_times, @exec_class);
+
+do write_data($gran_global_file_name, $OPEN_INT, $logscale{'g'}, $#exec_times+1,
+ @exec_times, @exec_global_class);
+
+do write_data($gran_local_file_name, $OPEN_INT, $logscale{'g'}, $#exec_times+1,
+ @exec_times, @exec_local_class);
+
+do write_data($comm_file_name, $CLOSED_INT, $logscale{'c'}, $#comm_percs+1,
+ @comm_percs, @comm_class);
+
+do write_data($comm_global_file_name, $CLOSED_INT, $logscale{'c'}, $#comm_percs+1,
+ @comm_percs, @comm_global_class);
+
+do write_data($comm_local_file_name, $CLOSED_INT, $logscale{'c'}, $#comm_percs+1,
+ @comm_percs, @comm_local_class);
+
+do write_data($spark_file_name, $OPEN_INT, $logscale{'s'}, $#sparks+1,
+ @sparks, @spark_class);
+
+do write_data($spark_local_file_name, $OPEN_INT, $logscale{'s'}, $#sparks+1,
+ @sparks, @spark_local_class);
+
+do write_data($spark_global_file_name, $OPEN_INT, $logscale{'s'}, $#sparks+1,
+ @sparks, @spark_global_class);
+
+do write_data($ha_file_name, $OPEN_INT, $logscale{'a'}, $#has+1,
+ @has, @ha_class);
+
+do write_data($ft_file_name, $OPEN_INT, $logscale{'g'}, $#fetch_times+1,
+ @fetch_times, @fetch_class);
+
+
+# ----------------------------------------------------------------------------
+# Run GNUPLOT over the data files and create figures
+# ----------------------------------------------------------------------------
+
+do gnu_plotify($gp_file_name);
+
+print "Script finished successfully!\n";
+
+exit 0;
+
+# ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+# ----------------------------------------------------------------------------
+# Basic Operations on the intervals
+# ----------------------------------------------------------------------------
+
+sub get_index_open_int {
+ local ($value,@list) = @_;
+ local ($index,$right);
+
+ # print "get_index: searching for index of" . $value;
+ # print " in " . join(':',@list);
+
+ $index = 0;
+ $right = $list[$index];
+ while ( ($value >= $right) && ($index < $#list) ) {
+ $index++;
+ $right = $list[$index];
+ }
+
+ return ( ($index == $#list) && ($value > $right) ) ? $index+1 : $index;
+}
+
+# ----------------------------------------------------------------------------
+
+sub get_index_closed_int {
+ local ($value,@list) = @_;
+ local ($index,$right);
+
+ if ( ($value < $list[0]) || ($value > $list[$#list]) ) {
+ return ( -1 );
+ }
+
+ $index = 0;
+ $left = $list[$index];
+ while ( ($left <= $value) && ($index < $#list) ) {
+ $index++;
+ $left = $list[$index];
+ }
+ return ( $index-1 );
+}
+
+# ----------------------------------------------------------------------------
+# Write operations
+# ----------------------------------------------------------------------------
+
+sub write_data {
+ local ($file_name, $open_int, $logaxes, $n, @rest) = @_;
+ local (@times) = splice(@rest,0,$n);
+ local (@class) = @rest;
+
+ open(GRAN,">$file_name") || die "Couldn't open file $file_name for output";
+
+ if ( $open_int == $OPEN_INT ) {
+
+ for ($i=0,
+ $left = ( index($logaxes,"x") != -1 ? int($times[0]/2) : 0 ),
+ $right = 0;
+ $i < $n;
+ $i++, $left = $right) {
+ $right = $times[$i];
+ print GRAN int(($left+$right)/2) . " " .
+ ($class[$i] eq "" ? "0" : $class[$i]) . "\n";
+ }
+ print GRAN $times[$n-1]+(($times[$n-1]-$times[$n-2])/2) . " " .
+ ($class[$n] eq "" ? "0" : $class[$n]) . "\n";
+
+ } else {
+
+ print GRAN ( (index($logaxes,"x") != -1) && ($times[0] == 0 ? int($times[1]/2) : ($times[$1] + $times[0])/2 ) . " " . $class[0] . "\n");
+ for ($i=1; $i < $n-2; $i++) {
+ $left = $times[$i];
+ $right = $times[$i+1];
+ print(GRAN ($left+$right)/2 . " " .
+ ($class[$i] eq "" ? "0" : $class[$i]) . "\n");
+ }
+ print GRAN ($times[$n-1]+$times[$n-2])/2 . " " . $class[$n-2] if $n >= 2;
+ }
+
+ close(GRAN);
+}
+
+# ----------------------------------------------------------------------------
+
+sub write_array {
+ local ($file_name,$n,@list) = @_;
+
+ open(FILE,">$file_name") || die "$file_name: $!";
+ for ($i=0; $i<=$#list; $i++) {
+ print FILE $i . " " . ( $list[$i] eq "" ? "0" : $list[$i] ) . "\n";
+ }
+
+ if ( $opt_D ) {
+ print "write_array: (" . join(", ",1 .. $#list) . ")\n for file $file_name returns: \n (0, $#list, &list_max(@list)\n";
+ }
+
+ return ( (0, $#list, &list_max(@list),
+ "(" . join(", ",1 .. $#list) . ")\n") );
+}
+
+# ----------------------------------------------------------------------------
+
+sub write_cumulative_data {
+ local ($file_name1,$file_name2,@list) = @_;
+ local (@ns, @elems, @xtics, $i, $j, $n, $elem, $max_clust, $xtics_str,
+ $xstart, $xend, $file_name0);
+ local ($CLUST_SZ) = $no_of_clusters;
+
+ @ns = ();
+ @elems = ();
+ $file_name0 = $file_name1;
+ $file_name0 =~ s/\.dat$//;
+ $file_name0 .= "0.dat";
+ open(CUMM,">$file_name1") || die "Couldn't open file $file_name1 (error $!)\n";
+ open(CUMM0,">$file_name0") || die "Couldn't open file $file_name0 (error $!)\n";
+
+ print CUMM "1 0\n" unless $list[0] <= 1;
+ print CUMM0 "1 0\n" unless $list[0] <= 1;;
+
+ for ($i=0; $i <= $#list; $i++) {
+ $elem = $list[$i];
+ print CUMM ($elem) . " " . int( (100 * ($i)) / ($#list+1) ) . "\n" unless $elem == 0;
+ print CUMM0 ($elem) . " " . $i . "\n" unless $elem == 0;;
+ for ($n=1; $i < $#list && $list[$i+1] == $elem; $i++, $n++) { }
+
+ print CUMM "$elem " . int( (100 * ($i+1)) / ($#list+1) ) . "\n";
+ print CUMM0 "$elem " . ($i+1) . "\n";
+
+
+ if ( $opt_D ) {
+ print "\n--> Insert: n: $n (elem $elem) in the above lists yields: \n ";
+ }
+
+ # inlined version of do insert_elem($elem, $n, $#exs, @exs, @ns)
+ for ($j=0; $j<=$#ns && $ns[$j]>$n; $j++) { }
+ if ( $j > $#ns ) {
+ push(@ns,$n);
+ push(@elems,$elem);
+ } else {
+ splice(@ns,$j,0,$n); # insert $n at pos $j and move the
+ splice(@elems,$j,0,$elem); # rest of the array to the right
+ }
+
+ if ( $opt_D ) {
+ print "[" . join(", ",@ns) . "]" . "\n and \n" .
+ "[" . join(", ",@elems) . "]\n";
+ }
+
+ }
+
+ close(CUMM);
+ close(CUMM0);
+
+ open(CLUSTERS_ALL,">" . (&dirname($file_name2)) . "CL-" .
+ &basename($file_name2))
+ || die "Couldn't open file CL-$file_name2 (error $!)\n";
+ for ($i=0; $i <= $#ns; $i++) {
+ print CLUSTERS_ALL "$elems[$i] $ns[$i]\n";
+ }
+ close(CLUSTERS_ALL);
+
+ # Interesting are only the first parts of the list (clusters!)
+ splice(@elems, $CLUST_SZ);
+ splice(@ns, $CLUST_SZ);
+
+ open(CLUSTERS,">$file_name2") || die "Couldn't open file $file_name2 (error $!)\n";
+
+ $xstart = &list_min(@elems);
+ $xend = &list_max(@elems);
+ $step = ($xend - $xstart) / ( $CLUST_SZ == 1 ? 1 : ($CLUST_SZ-1));
+
+ @xtics = ();
+ for ($i=0, $x=$xstart; $i <= $#ns; $i++, $x+=$step) {
+ print CLUSTERS "$x $ns[$i]\n";
+ push(@xtics,"\"$elems[$i]\" $x");
+ }
+ close(CLUSTERS);
+
+ $max_clust = $ns[0];
+ $xtics_str = "(" . join(", ",@xtics) . ")\n";
+
+ return ( ($xstart, $xend, $max_clust, $xtics_str) );
+}
+
+# ----------------------------------------------------------------------------
+
+sub get_xtics {
+ local ($open_int, @list) = @_;
+
+ local ($str);
+
+ if ( $open_int == $OPEN_INT ) {
+ $last = pop(@list);
+ $str = "( \">0\" 0";
+ foreach $x (@list) {
+ $str .= ", \">$x\" $x";
+ }
+ $str .= ", \"Large\" $last)\n";
+ } else {
+ $left = shift(@list);
+ $right = shift(@list) if $#list >= 0;
+ $last = pop(@list) if $#list >= 0;
+ $str = "( \"$left-$right\" " . $left;
+ $left = $right;
+ foreach $right (@list) {
+ $str .= ", \"$left-$right\" " . ($left+$right)/2;
+ $left = $right;
+ }
+ $str .= ", \"$left-$last\" " . $last .")\n" unless $last eq "";
+ }
+ return $str;
+}
+
+# ----------------------------------------------------------------------------
+
+sub print_line {
+ local ($start,$end,$is_global,$bbs,$ha,$rt,$bt,$bc,$ft,$fc,$my) = @_;
+
+ printf("START: %u, END: %u ==> tot_exec: %u\n",
+ $start,$end,$end-$start);
+ printf(" BASIC_BLOCKS: %u, HEAP_ALLOCATIONS: %u \n",$bbs,$ha);
+ printf(" TOT_EXEC: %u = RUN_TIME %u + BLOCK_TIME %u + FETCH_TIME %u\n",
+ $end-$start,$rt,$bt,$ft);
+ printf(" BLOCK_TIME %u / BLOCK_COUNT %u; FETCH_TIME %u / FETCH_COUNT %u\n",
+ $bt,$bc,$ft,$fc);
+ printf(" %s %s\n",
+ $is_global eq 'T' ? "GLOBAL" : "LOCAL",
+ $my eq 'T' ? "MANDATORY" : "NOT MANDATORY");
+}
+
+# ----------------------------------------------------------------------------
+
+sub gnu_plotify {
+ local ($gp_file_name) = @_;
+
+ local (@open_xrange,@closed_xrang,@spark_xrange,@ha_xrange, @ft_range,
+ $exec_xtics,$comm_perc_xtics,$spark_xtics,$has_xtics,
+ $cumu0_rts_file, $cumu0_has_file, $cumu0_fts_file);
+
+ $cumu0_rts_file = $cumulat_rts_file_name;
+ $cumu0_rts_file =~ s/\.dat$//;
+ $cumu0_rts_file .= "0.dat";
+
+ $cumu0_has_file = $cumulat_has_file_name;
+ $cumu0_has_file =~ s/\.dat$//;
+ $cumu0_has_file .= "0.dat";
+
+ $cumu0_fts_file = $cumulat_fts_file_name;
+ $cumu0_fts_file =~ s/\.dat$//;
+ $cumu0_fts_file .= "0.dat";
+
+ $cumu0_cps_file = $cumulat_cps_file_name;
+ $cumu0_cps_file =~ s/\.dat$//;
+ $cumu0_cps_file .= "0.dat";
+
+ @open_xrange = &range($OPEN_INT,$logscale{'g'},@exec_times);
+ @closed_xrange = &range($CLOSED_INT,$logscale{'c'},@comm_percs);
+ @spark_xrange = &range($OPEN_INT,$logscale{'s'},@sparks);
+ @ha_xrange = &range($OPEN_INT,$logscale{'a'},@has);
+ @ft_xrange = &range($OPEN_INT,$logscale{'f'},@fts);
+
+ $exec_xtics = $opt_T ? &get_xtics($OPEN_INT,@exec_times) : "" ;
+ $comm_perc_xtics = $opt_T ? &get_xtics($CLOSED_INT,@comm_percs) : "";
+ $spark_xtics = $opt_T ? &get_xtics($OPEN_INT,@sparks) : "";
+ $has_xtics = $opt_T ? &get_xtics($OPEN_INT,@has) : "";
+ $fts_xtics = $opt_T ? &get_xtics($OPEN_INT,@fts) : "";
+
+ open(GP_FILE,">$gp_file_name") ||
+ die "Couldn't open gnuplot file $gp_file_name for output\n";
+
+ if ( $opt_m ) {
+ print GP_FILE "set term postscript \"Roman\" 20\n";
+ } else {
+ print GP_FILE "set term postscript color \"Roman\" 20\n";
+ }
+
+ do write_gp_record(GP_FILE,
+ $gran_file_name, &dat2ps_name($gran_file_name),
+ "Granularity (pure exec. time)", $ylabel, $logscale{'g'},
+ @open_xrange,$max_rt_class,$exec_xtics);
+ do write_gp_record(GP_FILE,
+ $gran_global_file_name, &dat2ps_name($gran_global_file_name),
+ "Granularity (pure exec. time) of exported threads",
+ $ylabel, $logscale{'g'},
+ @open_xrange,$max_rt_global_class,$exec_xtics);
+ do write_gp_record(GP_FILE,
+ $gran_local_file_name, &dat2ps_name($gran_local_file_name),
+ "Granularity (pure exec. time) of not exported threads",
+ $ylabel,$logscale{'g'},
+ @open_xrange,$max_rt_local_class,$exec_xtics);
+
+ do write_gp_record(GP_FILE,
+ $comm_file_name, &dat2ps_name($comm_file_name),
+ "% of communication",$ylabel,$logscale{'c'},
+ @closed_xrange,$max_comm_perc_class,$comm_perc_xtics);
+ do write_gp_record(GP_FILE,
+ $comm_global_file_name, &dat2ps_name($comm_global_file_name),
+ "% of communication of exported threads",$ylabel,$logscale{'c'},
+ @closed_xrange,$max_comm_perc_global_class,$comm_perc_xtics);
+ do write_gp_record(GP_FILE,
+ $comm_local_file_name, &dat2ps_name($comm_local_file_name),
+ "% of communication of not exported threads",$ylabel,$logscale{'c'},
+ @closed_xrange,$max_comm_perc_local_class,$comm_perc_xtics);
+ do write_gp_record(GP_FILE,
+ $ft_file_name, &dat2ps_name($ft_file_name),
+ "Communication time", $ylabel, $logscale{'g'},
+ @open_xrange,$max_ft_class,$fts_xtics);
+
+
+ do write_gp_record(GP_FILE,
+ $spark_file_name, &dat2ps_name($spark_file_name),
+ "No. of sparks created", $ylabel, $logscale{'s'},
+ @spark_xrange,$max_spark_class,$spark_xtics);
+
+ do write_gp_record(GP_FILE,
+ $spark_local_file_name, &dat2ps_name($spark_local_file_name),
+ "No. of sparks created (parLocal)", $ylabel, $logscale{'s'},
+ @spark_xrange,$max_spark_local_class,$spark_xtics);
+
+ do write_gp_record(GP_FILE,
+ $spark_global_file_name, &dat2ps_name($spark_global_file_name),
+ "No. of sparks created (parGlobal)", $ylabel, $logscale{'s'},
+ @spark_xrange,$max_spark_global_class,$spark_xtics);
+
+ do write_gp_record(GP_FILE,
+ $ha_file_name, &dat2ps_name($ha_file_name),
+ "Heap Allocations (words)", $ylabel, $logscale{'a'},
+ @ha_xrange,$max_ha_class,$has_xtics);
+
+ do write_gp_lines_record(GP_FILE,
+ $cumulat_rts_file_name, &dat2ps_name($cumulat_rts_file_name),
+ "Cumulative pure exec. times","% of threads",
+ $logscale{'Cg'},
+ $xend_cum_rts, $yend_cum_rts,"");
+ # $xtics_cluster_rts as last arg?
+
+ do write_gp_lines_record(GP_FILE,
+ $cumulat_has_file_name, &dat2ps_name($cumulat_has_file_name),
+ "Cumulative heap allocations","% of threads",
+ $logscale{'Ca'},
+ $xend_cum_has, $yend_cum_has,"");
+ # $xtics_cluster_has as last arg?
+
+ do write_gp_lines_record(GP_FILE,
+ $cumu0_rts_file, &dat2ps_name($cumu0_rts_file),
+ "Cumulative pure exec. times","Number of threads",
+ $logscale{'Cg'},
+ $xend_cum_rts, $yend_cum0_rts,"");
+ # $xtics_cluster_rts as last arg?
+
+ do write_gp_lines_record(GP_FILE,
+ $cumu0_has_file, &dat2ps_name($cumu0_has_file),
+ "Cumulative heap allocations","Number of threads",
+ $logscale{'Ca'},
+ $xend_cum_has, $yend_cum0_has,"");
+ # $xtics_cluster_has as last arg?
+
+ do write_gp_lines_record(GP_FILE,
+ $cumulat_fts_file_name, &dat2ps_name($cumulat_fts_file_name),
+ "Cumulative communication times","% of threads",
+ $logscale{'Cg'},
+ $xend_cum_fts, $yend_cum_fts,"");
+ # $xtics_cluster_rts as last arg?
+
+ do write_gp_lines_record(GP_FILE,
+ $cumu0_fts_file, &dat2ps_name($cumu0_fts_file),
+ "Cumulative communication times","Number of threads",
+ $logscale{'Cg'},
+ $xend_cum_fts, $yend_cum0_fts,"");
+ # $xtics_cluster_rts as last arg?
+
+ do write_gp_lines_record(GP_FILE,
+ $cumulat_cps_file_name, &dat2ps_name($cumulat_cps_file_name),
+ "Cumulative communication percentages","% of threads",
+ "", # No logscale here !
+ $xend_cum_cps, $yend_cum_cps,"");
+ # $xtics_cluster_rts as last arg?
+
+ do write_gp_lines_record(GP_FILE,
+ $cumu0_cps_file, &dat2ps_name($cumu0_cps_file),
+ "Cumulative communication percentages","Number of threads",
+ "", # No logscale here !
+ $xend_cum_cps, $yend_cum0_cps,"");
+ # $xtics_cluster_rts as last arg?
+
+ do write_gp_record(GP_FILE,
+ $clust_rts_file_name, &dat2ps_name($clust_rts_file_name),
+ "Pure exec. time", "No. of threads", $logscale{'CG'},
+ $xstart_cluster_rts,$xend_cluster_rts,$max_cluster_rts,$xtics_cluster_rts);
+
+ do write_gp_record(GP_FILE,
+ $clust_has_file_name, &dat2ps_name($clust_has_file_name),
+ "Pure exec. time", "No. of threads", $logscale{'CA'},
+ $xstart_cluster_has,$xend_cluster_has,$max_cluster_has,$xtics_cluster_has);
+
+ do write_gp_record(GP_FILE,
+ $clust_fts_file_name, &dat2ps_name($clust_fts_file_name),
+ "Communication time", "No. of threads", $logscale{'CG'},
+ $xstart_cluster_fts,$xend_cluster_fts,$max_cluster_fts,$xtics_cluster_rts);
+
+
+ do write_gp_simple_record(GP_FILE,
+ $pe_file_name, &dat2ps_name($pe_file_name),
+ "Processing Elements (PEs)", "Ready Time (not running)",
+ $logscale{'Yp'},$xstart_pe,$xend_pe,$max_pe,$xtics_pe);
+
+ do write_gp_simple_record(GP_FILE,
+ $sn_file_name, &dat2ps_name($sn_file_name),
+ "Spark sites", "Pure exec. time",
+ $logscale{'Ys'},$xstart_sn,$xend_sn,$max_sn,$xtics_sn);
+
+ close GP_FILE;
+
+ print "Gnu plotting figures ...\n";
+ system "gnuplot $gp_file_name";
+
+ print "Extending thickness of impulses ...\n";
+ do gp_ext($gran_file_name,
+ $gran_global_file_name,
+ $gran_local_file_name,
+ $comm_file_name,
+ $comm_global_file_name,
+ $comm_local_file_name,
+ $spark_file_name,
+ $spark_local_file_name,
+ $spark_global_file_name,
+ $ha_file_name,
+ $ft_file_name,
+ $clust_fts_file_name,
+ $clust_rts_file_name,
+ $clust_has_file_name,
+ $pe_file_name,
+ $sn_file_name
+ );
+
+
+}
+
+# ----------------------------------------------------------------------------
+
+sub gp_ext {
+ local (@file_names) = @_;
+ local ($file_name);
+ local ($ps_file_name);
+ local ($prg);
+
+ #$prg = system "which gp-ext-imp";
+ #print " Using script $prg for impuls extension\n";
+ $prg = $ENV{GRANDIR} ? $ENV{GRANDIR} . "/bin/gp-ext-imp"
+ : $ENV{HOME} . "/bin/gp-ext-imp" ;
+ if ( $opt_v ) {
+ print " (using script $prg)\n";
+ }
+
+ foreach $file_name (@file_names) {
+ $ps_file_name = &dat2ps_name($file_name);
+ system "$prg -w $ext_size -g $gray " .
+ $ps_file_name . " " .
+ $ps_file_name . "2" ;
+ system "mv " . $ps_file_name . "2 " . $ps_file_name;
+ }
+}
+
+# ----------------------------------------------------------------------------
+
+sub write_gp_record {
+ local ($file,$in_file,$out_file,$xlabel,$ylabel,$logaxes,
+ $xstart,$xend,$ymax,$xtics) = @_;
+
+ if ( $xstart >= $xend ) {
+ print ("WARNING: empty xrange [$xstart:$xend] changed to [$xstart:" . $xstart+1 . "]\n") if ( $pedantic || $opt_v );
+ $xend = $xstart + 1;
+ }
+
+ if ( $ymax <=0 ) {
+ $ymax = 2;
+ print "WARNING: empty yrange changed to [0:$ymax]\n" if ( $pedantic || $opt_v );
+ }
+
+ $str = "set size " . $xsize . "," . $ysize . "\n" .
+ "set xlabel \"" . $xlabel . "\"\n" .
+ "set ylabel \"" . $ylabel . "\"\n" .
+ ($xstart eq "" ? ""
+ : "set xrange [" . int($xstart) .":" . int($xend) . "]\n") .
+ ($ymax eq "" ? ""
+ : "set yrange [" . (index($logaxes,"y") != -1 ? 1 : 0) .
+ ":" . &list_max(2,int($ymax+$ymax/5)) . "]\n") .
+ ($xtics ne "" ? "set xtics $xtics" : "") .
+ "set tics out\n" .
+ "set border\n" .
+ "set title \"$nPEs PEs\"\n" .
+ "set nokey \n" .
+ "set nozeroaxis\n" .
+ "set format xy \"%g\"\n" .
+ (index($logaxes,"x") != -1 ?
+ "set logscale x\n" :
+ "set nologscale x\n") .
+ (index($logaxes,"y") != -1 ?
+ "set logscale y\n" :
+ "set nologscale y\n") .
+ "set output \"" . $out_file . "\"\n" .
+ "plot \"" . $in_file . "\" with impulses\n\n";
+ print $file $str;
+}
+
+# ----------------------------------------------------------------------------
+
+sub write_gp_lines_record {
+ local ($file,$in_file,$out_file,$xlabel,$ylabel,$logaxes,
+ $xend,$yend,$xtics) = @_;
+
+ local ($str);
+
+ $str = "set xlabel \"" . $xlabel . "\"\n" .
+ "set ylabel \"" . $ylabel . "\"\n" .
+ "set xrange [" . ( index($logaxes,"x") != -1 ? 1 : 0 ) . ":$xend]\n" .
+ "set yrange [" . ( index($logaxes,"y") != -1 ? 1 : 0 ) . ":$yend]\n" .
+ "set border\n" .
+ "set nokey\n" .
+ ( $xtics ne "" ? "set xtics $xtics" : "" ) .
+ (index($logaxes,"x") != -1 ?
+ "set logscale x\n" :
+ "set nologscale x\n") .
+ (index($logaxes,"y") != -1 ?
+ "set logscale y\n" :
+ "set nologscale y\n") .
+ "set nozeroaxis\n" .
+ "set format xy \"%g\"\n" .
+ "set output \"" . $out_file . "\"\n" .
+ "plot \"" . $in_file . "\" with lines\n\n";
+ print $file $str;
+}
+
+
+# ----------------------------------------------------------------------------
+
+sub write_gp_simple_record {
+ local ($file,$in_file,$out_file,$xlabel,$ylabel,$logaxes,
+ $xstart,$xend,$ymax,$xtics) = @_;
+
+ $str = "set size " . $xsize . "," . $ysize . "\n" .
+ "set xlabel \"" . $xlabel . "\"\n" .
+ "set ylabel \"" . $ylabel . "\"\n" .
+ ($xstart eq "" ? ""
+ : "set xrange [" . int($xstart) .":" . int($xend) . "]\n") .
+ ($ymax eq "" ? ""
+ : "set yrange [" . (index($logaxes,"y") != -1 ? 1 : 0) .
+ ":" . &list_max(2,int($ymax+$ymax/5)) . "]\n") .
+ ($xtics ne "" ? "set xtics $xtics" : "") .
+ "set border\n" .
+ "set nokey\n" .
+ "set tics out\n" .
+ "set nozeroaxis\n" .
+ "set format xy \"%g\"\n" .
+ (index($logaxes,"x") != -1 ?
+ "set logscale x\n" :
+ "set nologscale x\n") .
+ (index($logaxes,"y") != -1 ?
+ "set logscale y\n" :
+ "set nologscale y\n") .
+ "set output \"" . $out_file . "\"\n" .
+ "plot \"" . $in_file . "\" with impulses\n\n";
+ print $file $str;
+}
+
+# ----------------------------------------------------------------------------
+
+sub dat2ps_name {
+ local ($dat_name) = @_;
+
+ $dat_name =~ s/\.dat$/\.ps/;
+ return ($dat_name);
+}
+
+# ----------------------------------------------------------------------------
+
+sub range {
+ local ($open_int, $logaxes, @ints) = @_;
+
+ local ($range, $left_margin, $right_margin);
+
+ $range = $ints[$#ints]-$ints[0];
+ $left_margin = 0; # $range/10;
+ $right_margin = 0; # $range/10;
+
+ if ( $opt_D ) {
+ print "\n==> Range: logaxes are $logaxes i.e. " .
+ (index($logaxes,"x") != -1 ? "matches x axis\n"
+ : "DOESN'T match x axis\n");
+ }
+ if ( index($logaxes,"x") != -1 ) {
+ if ( $open_int == $OPEN_INT ) {
+ return ( ($ints[0]/2-$left_margin,
+ $ints[$#ints]+($ints[$#ints]-$ints[$#ints-1])/2+$right_margin) );
+ } else {
+ return ( ( &list_max(1,$ints[0]-$left_margin),
+ $ints[$#ints]+($ints[$#ints]-$ints[$#ints-1])/2+$right_margin) );
+ }
+ } else {
+ if ( $open_int == $OPEN_INT ) {
+ return ( ($ints[0]/2-$left_margin,
+ $ints[$#ints]+($ints[$#ints]-$ints[$#ints-1])/2+$right_margin) );
+ } else {
+ return ( ($ints[0]-$left_margin,
+ $ints[$#ints]+($ints[$#ints]-$ints[$#ints-1])/2+$right_margin) );
+ }
+ }
+}
+
+# ----------------------------------------------------------------------------
+
+sub percentify {
+ local ($sum,*classes) = @_;
+
+ for ($i=0; $i<=$#classes; $i++) {
+ $classes[$i] = (100 * $classes[$i]) / $sum;
+ }
+}
+
+# ----------------------------------------------------------------------------
+# ToDo: get these statistics functions from "stat.pl"
+# ----------------------------------------------------------------------------
+
+sub mean_std_dev {
+ local ($sum,@list) = @_;
+
+ local ($n, $s, $s_);
+
+ #print "\nmean_std_dev: sum is $sum ; list has length $#list";
+
+ $n = $#list+1;
+ $mean_value = $sum/$n;
+
+ $s_ = 0;
+ foreach $x (@list) {
+ $s_ += $x;
+ $s += ($mean_value - $x) ** 2;
+ }
+ if ( $sum != $s_ ) {
+ print "ERROR in mean_std_dev: provided sum is wrong " .
+ "(provided: $sum; computed: $s_)\n";
+ print " list_sum: " . &list_sum(@list) . "\n";
+ exit (2);
+ }
+
+ return ( ($mean_value, sqrt($s / ($n - 1)) ) );
+}
+
+# ----------------------------------------------------------------------------
+
+sub _mean_std_dev {
+ return ( &mean_std_dev(&list_sum(@_), @_) );
+}
+
+# ----------------------------------------------------------------------------
+# Compute covariance of 2 vectors, having their sums precomputed.
+# Input: $n ... number of all elements in @list_1 as well as in @list_2
+# (i.e. $n = $#list_1+1 = $#list_2+1).
+# $mean_1 ... mean value of all elements in @list_1
+# @list_1 ... list of integers; first vector
+# $mean_2 ... mean value of all elements in @list_2
+# @list_2 ... list of integers; first vector
+# Output: covariance of @list_1 and @list_2
+# ----------------------------------------------------------------------------
+
+sub cov {
+ local ($n, $mean_1, @rest) = @_;
+ local (@list_1) = splice(@rest,0,$n);
+ local ($mean_2, @list_2) = @rest;
+
+ local ($i,$s,$s_1,$s_2);
+
+ for ($i=0; $i<$n; $i++) {
+ $s_1 += $list_1[$i];
+ $s_2 += $list_2[$i];
+ $s += ($mean_1 - $list_1[$i]) * ($mean_2 - $list_2[$i]);
+ }
+ if ( $mean_1 != ($s_1/$n) ) {
+ print "ERROR in cov: provided mean value is wrong " .
+ "(provided: $mean_1; computed: " . ($s_1/$n) . ")\n";
+ exit (2);
+ }
+ if ( $mean_2 != ($s_2/$n) ) {
+ print "ERROR in cov: provided mean value is wrong " .
+ "(provided: $mean_2; computed: " . ($s_2/$n) . ")\n";
+ exit (2);
+ }
+ return ( $s / ($n - 1) ) ;
+}
+
+# ----------------------------------------------------------------------------
+# Compute correlation of 2 vectors, having their sums precomputed.
+# Input: $n ... number of all elements in @list_1 as well as in @list_2
+# (i.e. $n = $#list_1+1 = $#list_2+1).
+# $sum_1 ... sum of all elements in @list_1
+# @list_1 ... list of integers; first vector
+# $sum_2 ... sum of all elements in @list_2
+# @list_2 ... list of integers; first vector
+# Output: correlation of @list_1 and @list_2
+# ----------------------------------------------------------------------------
+
+sub corr {
+ local ($n, $sum_1, @rest) = @_;
+ local (@list_1) = splice(@rest,0,$n);
+ local ($sum_2, @list_2) = @rest;
+
+ local ($mean_1,$mean_2,$std_dev_1,$std_dev_2);
+
+ if ( $opt_D ) {
+ print "\ncorr: n=$n sum_1=$sum_1 sum_2=$sum_2\n";
+ print " list_sum of list_1=" . &list_sum(@list_1) .
+ " list_sum of list_2=" . &list_sum(@list_2) . "\n";
+ print " len of list_1=$#list_1 len of list_2=$#list_2\n";
+ }
+
+ ($mean_1, $std_dev_1) = &mean_std_dev($sum_1,@list_1);
+ ($mean_2, $std_dev_2) = &mean_std_dev($sum_2,@list_2);
+
+ if ( $opt_D ) {
+ print "corr: $mean_1, $std_dev_1; $mean_2, $std_dev_2\n";
+ }
+
+ return ( ($std_dev_1 * $std_dev_2) == 0 ?
+ 0 :
+ &cov($n, $mean_1, @list_1, $mean_2, @list_2) /
+ ( $std_dev_1 * $std_dev_2 ) );
+}
+
+# ----------------------------------------------------------------------------
+
+sub list_sum {
+ local (@list) = @_;
+
+ local ($sum);
+
+ foreach $x (@list) {
+ $sum += $x;
+ }
+
+ return ($sum);
+}
+
+# ----------------------------------------------------------------------------
+
+sub list_max {
+ local (@list) = @_;
+
+ local ($max) = shift;
+
+ foreach $x (@list) {
+ $max = $x if $x > $max;
+ }
+
+ return ($max);
+}
+
+# ----------------------------------------------------------------------------
+
+sub list_min {
+ local (@list) = @_;
+
+ local ($min) = shift;
+
+ foreach $x (@list) {
+ $min = $x if $x < $min;
+ }
+
+ return ($min);
+}
+
+# ----------------------------------------------------------------------------
+
+sub guess_interval {
+ local (@list) = @_ ;
+
+ local ($min,$max,$sum,$mean,$std_dev,@intervals);
+
+ $min = &list_min(@list);
+ $max = &list_max(@list);
+ $sum = &list_sum(@list);
+ ($mean, $std_dev) = &mean_std_dev($sum,@list);
+
+ @intervals = (int($mean-$std_dev),int($mean-$std_dev/2),int($mean),
+ int($mean+$std_dev/2),int($mean+$std_dev));
+
+ while ($#intervals>=0 && $intervals[0]<0) {
+ shift(@intervals);
+ }
+
+ return (@intervals);
+}
+
+# ----------------------------------------------------------------------------
+
+sub write_interval {
+ local ($file,$flag,@intervals) = @_;
+
+ printf $file "$flag: (" . join(", ",@intervals) . ")\n";
+}
+
+# ----------------------------------------------------------------------------
+
+sub read_template {
+
+ if ( $opt_v ) {
+ print "Reading settings from template file $templ_file_name ...\n";
+ }
+
+ open(TEMPLATE,$templ_file_name) || die "Couldn't open file $templ_file_name";
+ while (<TEMPLATE>) {
+ next if /^\s*$/ || /^--/;
+ if (/^\s*G[:,;.\s]+([^\n]+)$/) {
+ $list_str = $1;
+ $list_str =~ s/[\(\)\[\]]//g;
+ @exec_times = split(/[,;. ]+/, $list_str);
+ } elsif (/^\s*F[:,;.\s]+([^\n]+)$/) {
+ $list_str = $1;
+ $list_str =~ s/[\(\)\[\]]//g;
+ @fetch_times = split(/[,;. ]+/, $list_str);
+ } elsif (/^\s*A[:,;.\s]+([^\n]+)$/) {
+ $list_str = $1;
+ $list_str =~ s/[\(\)\[\]]//g;
+ @has = split(/[,;. ]+/, $list_str);
+ } elsif (/^\s*C[:,;.\s]+([^\n]+)$/) {
+ $list_str = $1;
+ $list_str =~ s/[\(\)\[\]]//g;
+ @comm_percs = split(/[,;. ]+/, $list_str);
+ } elsif (/^\s*S[:,;.\s]+([^\n]+)$/) {
+ $list_str = $1;
+ $list_str =~ s/[\(\)\[\]]//g;
+ @sparks = split(/[,;. ]+/, $list_str);
+ } elsif (/^\s*g[:,;.\s]+([\S]+)$/) {
+ ($gran_file_name,$gran_global_file_name, $gran_local_file_name) =
+ &mk_global_local_names($1);
+ } elsif (/^\s*f[:,;.\s]+([\S]+)$/) {
+ ($ft_file_name,$ft_global_file_name, $ft_local_file_name) =
+ &mk_global_local_names($1);
+ } elsif (/^\s*c[:,;.\s]+([\S]+)$/) {
+ ($comm_file_name, $comm_global_file_name, $comm_local_file_name) =
+ &mk_global_local_names($1);
+ } elsif (/^\s*s[:,;.\s]+([\S]+)$/) {
+ ($spark_file_name, $spark_global_file_name, $spark_local_file_name) =
+ &mk_global_local_names($1);
+ } elsif (/^\s*a[:,;.\s]+([\S]+)$/) {
+ ($ha_file_name, $ha_global_file_name, $ha_local_file_name) =
+ &mk_global_local_names($1);
+ } elsif (/^\s*p[:,;.\s]+([\S]+)$/) {
+ $gp_file_name = $1;
+ $ps_file_name = &dat2ps_name($gp_file_name);
+
+ } elsif (/^\s*Xcorr[:,;.\s]+([\S]+)$/) {
+ $corr_file_name = $1;
+ } elsif (/^\s*Xcumulat-rts[:,;.\s]+([\S]+)$/) {
+ $cumulat_rts_file_name = $1;
+ } elsif (/^\s*Xcumulat-has[:,;.\s]+([\S]+)$/) {
+ $cumulat_has_file_name = $1;
+ } elsif (/^\s*Xcumulat-fts[:,;.\s]+([\S]+)$/) {
+ $cumulat_fts_file_name = $1;
+ } elsif (/^\s*Xcumulat-cps[:,;.\s]+([\S]+)$/) {
+ $cumulat_cps_file_name = $1;
+ } elsif (/^\s*Xclust-rts[:,;.\s]+([\S]+)$/) {
+ $clust_rts_file_name = $1;
+ } elsif (/^\s*Xclust-has[:,;.\s]+([\S]+)$/) {
+ $clust_has_file_name = $1;
+ } elsif (/^\s*Xclust-fts[:,;.\s]+([\S]+)$/) {
+ $clust_fts_file_name = $1;
+ } elsif (/^\s*Xclust-cps[:,;.\s]+([\S]+)$/) {
+ $clust_cps_file_name = $1;
+ } elsif (/^\s*Xpe[:,;.\s]+([\S]+)$/) {
+ $pe_file_name = $1;
+ } elsif (/^\s*Xsn[:,;.\s]+([\S]+)$/) {
+ $sn_file_name = $1;
+
+ } elsif (/^\s*XRTS[:,;.\s]+([\S]+)$/) {
+ $rts_file_name = $1;
+ } elsif (/^\s*XHAS[:,;.\s]+([\S]+)$/) {
+ $has_file_name = $1;
+ } elsif (/^\s*XFTS[:,;.\s]+([\S]+)$/) {
+ $fts_file_name = $1;
+ } elsif (/^\s*XLSPS[:,;.\s]+([\S]+)$/) {
+ $lsps_file_name = $1;
+ } elsif (/^\s*XGSPS[:,;.\s]+([\S]+)$/) {
+ $gsps_file_name = $1;
+ } elsif (/^\s*XCPS[:,;.\s]+([\S]+)$/) {
+ $cps_file_name = $1;
+ } elsif (/^\s*XCCPS[:,;.\s]+([\S]+)$/) {
+ $ccps_file_name = $1;
+
+ } elsif (/^\s*\-[:,;.\s]+([\S]+)$/) {
+ $input = $1;
+ } elsif (/^\s*L[:,;\s]+(.*)$/) {
+ $str = $1;
+ %logscale = ('g',"xy",'a',"xy",'Cg',"xy",'Ca',"xy",'Yp',"y",'Ys',"y") , next if $str eq ".";
+ $str =~ s/[\(\)\[\]]//g;
+ %logscale = split(/[,;. ]+/, $str);
+ } elsif (/^\s*i[:,;.\s]+([\S]+)$/) {
+ $gray = $1;
+ } elsif (/^\s*k[:,;.\s]+([\S]+)$/) {
+ $no_of_clusters = $1;
+ } elsif (/^\s*e[:,;.\s]+([\S]+)$/) {
+ $ext_size = $1;
+ } elsif (/^\s*v.*$/) {
+ $verbose = 1;
+ } elsif (/^\s*T.*$/) {
+ $opt_T = 1;
+ } elsif (/^\s*m.*$/) {
+ $opt_m = 1;
+ }
+ }
+ close(TEMPLATE);
+}
+
+# ----------------------------------------------------------------------------
+
+sub mk_global_local_names {
+ local ($file_name) = @_;
+
+ $file_name .= ".dat" unless $file_name =~ /\.dat$/;
+ $global_file_name = $file_name;
+ $global_file_name =~ s/\.dat/\-global\.dat/ ;
+ $local_file_name = $file_name;
+ $local_file_name =~ s/\.dat/\-local\.dat/ ;
+
+ return ( ($file_name, $global_file_name, $local_file_name) );
+}
+
+# ----------------------------------------------------------------------------
+
+# ----------------------------------------------------------------------------
+
+sub pre_process {
+ local ($lines) = @_;
+
+ local (@all_rts, @all_comm_percs, @all_sparks, @all_local_sparks,
+ @all_global_sparks, @all_has, @fields,
+ $line_no, $elem, $total_rt, $comm_perc,
+ $pe, $start, $end, $is_global, $bbs, $ha, $rt, $bt, $ft,
+ $lsp, $gsp, $my);
+
+ if ( $opt_v ) {
+ print "Preprocessing file $input ... \n";
+ }
+
+ open(INPUT,"<$input") || die "Couldn't open input file $input";
+
+ do skip_header();
+
+ $line_no = 0;
+ while (<INPUT>) {
+ $line_no++;
+ last if $line_no > $lines;
+
+ @fields = split(/,/,$_);
+
+ foreach $elem (@fields) {
+ foo : {
+ $pe = $1 , last foo if $elem =~ /^\s*PE\s+(\d+).*$/;
+ $start = $1 , last foo if $elem =~ /^\s*ST\s+(\d+).*$/;
+ $end = $1 , last foo if $elem =~ /^\s*END\s+(\d+).*$/;
+ $is_global = $1 , last foo if $elem =~ /^\s*GBL\s+(T|F).*$/;
+ $bbs = $1 , last foo if $elem =~ /^\s*BB\s+(\d+).*$/;
+ $ha = $1 , last foo if $elem =~ /^\s*HA\s+(\d+).*$/;
+ $rt = $1 , last foo if $elem =~ /^\s*RT\s+(\d+).*$/;
+ $bt = $1, $bc = $2 , last foo if $elem =~ /^\s*BT\s+(\d+)\s+\((\d+)\).*$/;
+ $ft = $1, $fc = $2 , last foo if $elem =~ /^\s*FT\s+(\d+)\s+\((\d+)\).*$/;
+ $lsp = $1 , last foo if $elem =~ /^\s*LS\s+(\d+).*$/;
+ $gsp = $1 , last foo if $elem =~ /^\s*GS\s+(\d+).*$/;
+ $my = $1 , last foo if $elem =~ /^\s*MY\s+(T|F).*$/;
+ }
+ }
+
+ $total_rt = $end - $start;
+ $comm_perc = ( $total_rt == 0 ? 100 : (100 * $ft)/$total_rt );
+ $sp = $lsp + $gsp;
+
+ push(@all_rts,$rt);
+
+ push(@all_comm_percs,$comm_perc);
+
+ push(@all_sparks,$sp);
+ push(@all_local_sparks,$lsp);
+ push(@all_global_sparks,$gsp);
+
+ push(@all_has,$ha);
+ }
+
+ close(INPUT);
+
+ @exec_times = &guess_interval(@all_rts);
+ @sparks = &guess_interval(@all_sparks);
+ @has = &guess_interval(@all_has);
+
+ ($m,$std_dev) = &_mean_std_dev(@all_comm_percs);
+ @comm_percs = (0, int($m), int($std_dev), 100) unless int($m) == 0;
+ @comm_percs = (0, 1, 2, 5, 10, 50, 100) if int($m) == 0;
+}
+
+# ----------------------------------------------------------------------------
+
+sub process_options {
+ if ( $opt_h ) {
+ open(ME,$0) || die "Can't open myself ($0)";
+ $n = 0;
+ while (<ME>) {
+ last if $_ =~ /^$/;
+ print $_;
+ $n++;
+ }
+ close(ME);
+
+ # system "cat $0 | awk 'BEGIN { n = 0; } \
+ # /^$/ { print n; \
+ # exit; } \
+ # { n++; }'"
+ exit ;
+ }
+
+ if ( $opt_W ) {
+ $pedantic = 1;
+ } else {
+ $pedantic = 0;
+ }
+
+ $input = $#ARGV == -1 ? "-" : $ARGV[0] ;
+
+ if ( $#ARGV != 0 ) {
+ #print "Usage: gran-extr [options] <sim-file>\n";
+ #print "Use -h option to get details\n";
+ #exit 1;
+
+ }
+
+
+ if ( ! $opt_t ) {
+ do pre_process(20);
+ }
+
+ if ( $opt_g ) {
+ ($gran_file_name, $gran_global_file_name, $gran_local_file_name) =
+ do mk_global_local_names($opt_g);
+ } else {
+ $gran_file_name = "gran.dat";
+ $gran_global_file_name = "gran-global.dat";
+ $gran_local_file_name = "gran-local.dat";
+ }
+
+ if ( $opt_c ) {
+ ($comm_file_name, $comm_global_file_name, $comm_local_file_name) =
+ do mk_global_local_names($opt_c);
+ } else {
+ $comm_file_name = "comm.dat";
+ $comm_global_file_name = "comm-global.dat";
+ $comm_local_file_name = "comm-local.dat";
+ }
+
+ if ( $opt_f ) {
+ ($ft_file_name, $ft_global_file_name, $ft_local_file_name) =
+ do mk_global_local_names($opt_c);
+ } else {
+ $ft_file_name = "ft.dat";
+ $ft_global_file_name = "ft-global.dat";
+ $ft_local_file_name = "ft-local.dat";
+ }
+
+ if ( $opt_s ) {
+ ($spark_file_name, $spark_global_file_name, $spark_local_file_name) =
+ do mk_global_local_names($opt_s);
+ } else {
+ $spark_file_name = "spark.dat";
+ $spark_global_file_name = "spark-global.dat";
+ $spark_local_file_name = "spark-local.dat";
+ }
+
+ if ( $opt_a ) {
+ ($ha_file_name, $ha_global_file_name, $ha_local_file_name) =
+ do mk_global_local_names($opt_a);
+ } else {
+ $ha_file_name = "ha.dat";
+ }
+
+ if ( $opt_p ) {
+ $gp_file_name = $opt_p;
+ } else {
+ $gp_file_name = "gran.gp";
+ }
+
+ $ps_file_name = &dat2ps_name($gp_file_name);
+
+ $corr_file_name = "CORR";
+ $cumulat_rts_file_name = "cumulative-rts.dat";
+ $cumulat_has_file_name = "cumulative-has.dat";
+ $cumulat_fts_file_name = "cumulative-fts.dat";
+ $cumulat_cps_file_name = "cumulative-cps.dat";
+ $clust_rts_file_name = "clusters-rts.dat";
+ $clust_has_file_name = "clusters-has.dat";
+ $clust_fts_file_name = "clusters-fts.dat";
+ $clust_cps_file_name = "clusters-cps.dat";
+ $pe_file_name = "pe.dat";
+ $sn_file_name = "sn.dat";
+
+ $pie_file_name = "Pie.ps";
+
+ $cps_file_name = "CPS";
+ $fts_file_name = "FTS";
+ $rts_file_name = "RTS";
+ $has_file_name = "HAS";
+ $lsps_file_name = "LSPS";
+ $gsps_file_name = "GSPS";
+ $ccps_file_name = "CCPS";
+
+ if ( $opt_l ) {
+ $left_margin = $opt_l;
+ } else {
+ $left_margin = 0;
+ }
+ $left_perc_margin = 0;
+
+ if ( $opt_r ) {
+ $right_margin = $opt_r;
+ } else {
+ $right_margin = 0;
+ }
+ $right_perc_margin = 0;
+
+ if ( $opt_x ) {
+ $xsize = $opt_x;
+ } else {
+ $xsize = 1;
+ }
+
+ if ( $opt_y ) {
+ $ysize = $opt_y;
+ } else {
+ $ysize = 1;
+ }
+
+ if ( $opt_e ) {
+ $ext_size = $opt_e;
+ } else {
+ $ext_size = 200;
+ }
+
+ if ( $opt_i ) {
+ $gray = $opt_i;
+ } else {
+ $gray = 0;
+ }
+
+ if ( $opt_k ) {
+ $no_of_clusters = $opt_k;
+ } else {
+ $no_of_clusters = 5;
+ }
+
+ if ( $opt_L ) {
+ $str = $opt_L;
+ $str =~ s/[\(\)\[\]]//g;
+ %logscale = split(/[,;. ]+/, $str);
+ # $logscale = $opt_L;
+ } else {
+ %logscale = (); # ('g',"xy",'a',"xy",'Cg',"xy",'Ca',"xy");
+ }
+
+# $delta = do compute_delta(@exec_times);
+# $no_of_exec_times = $#exec_times;
+
+ if ( $opt_G ) {
+ $opt_G =~ s/[\(\)\[\]]//g;
+ @exec_times = split(/[,;. ]+/, $opt_G);
+ # @exec_times = split(/[,;. ]+/, ($opt_G =~ s/[\(\)]//g));
+ } else {
+ # @exec_times = (50, 100, 200, 300, 400, 500, 700);
+ }
+
+ if ( $opt_F ) {
+ $opt_F =~ s/[\(\)\[\]]//g;
+ @fetch_times = split(/[,;. ]+/, $opt_F);
+ # @fetch_times = split(/[,;. ]+/, ($opt_F =~ s/[\(\)]//g));
+ } else {
+ # @fetch_times = (50, 100, 200, 300, 400, 500, 700);
+ }
+
+ if ( $opt_C ) {
+ $opt_C =~ s/[\(\)\[\]]//g;
+ @comm_percs = split(/[,;. ]+/, $opt_C);
+ } else {
+ # @comm_percs = (0,10,20,30,50,100);
+ }
+
+ if ( $opt_S ) {
+ $opt_S =~ s/[\(\)\[\]]//g;
+ @sparks = split(/[,;. ]+/, $opt_S);
+ } else {
+ # @sparks = (0,5,10,50);
+ }
+
+# $delta_comm = do compute_delta(@comm_percs);
+
+ if ( $opt_A ) {
+ $opt_A =~ s/[\(\)\[\]]//g;
+ @has = split(/[,;. ]+/, $opt_A);
+ } else {
+ # @has = (10, 100, 200, 300, 500, 1000);
+ }
+
+ if ( $opt_t ) {
+ $templ_file_name = ( $opt_t eq '.' ? "TEMPL" # default file name
+ : $opt_t eq ',' ? "/users/fp/hwloidl/grasp/GrAn/bin/TEMPL" # global master template
+ : $opt_t eq '/' ? "/users/fp/hwloidl/grasp/GrAn/bin/T0" # template, that throws away most of the info
+ : $opt_t );
+ do read_template();
+ # see RTS2gran for use of template-package
+ }
+
+ $ylabel = $opt_P ? "% of threads" : "No. of threads";
+}
+
+# ----------------------------------------------------------------------------
+
+sub print_verbose_message {
+
+ print "-" x 70 . "\n";
+ print "Setup: \n";
+ print "-" x 70 . "\n";
+ print "\nFilenames: \n";
+ print " Input file: $input\n";
+ print " Gran files: $gran_file_name $gran_global_file_name $gran_local_file_name\n";
+ print " Comm files: $comm_file_name $comm_global_file_name $comm_local_file_name\n";
+ print " Sparked threads file: $spark_file_name $spark_local_file_name $spark_global_file_name\n";
+ print " Heap file: $ha_file_name\n";
+ print " GNUPLOT file name: $gp_file_name Correlation file name: $corr_file_name\n";
+ print " Cumulative RT file name: $cumulat_rts_file_name \n Cumulative HA file name: $cumulat_has_file_name\n";
+ print " Cluster RT file name: $clust_rts_file_name \n Cluster HA file name: $clust_has_file_name\n";
+ print " Cumulative runtimes file name: $cumulat_rts_file_name\n";
+ print " Cumulative heap allocations file name $cumulat_has_file_name\n";
+ print " Cluster run times file name: $clust_rts_file_name\n";
+ print " Cluster heap allocations file name: $clust_has_file_name\n";
+ print " PE load file name: $pe_file_name\n";
+ print " Site size file name: $sn_file_name\n";
+ print "\nBoundaries: \n";
+ print " Gran boundaries: @exec_times\n";
+ print " Comm boundaries: @comm_percs\n";
+ print " Sparked threads boundaries: @sparks\n";
+ print " Heap boundaries: @has\n";
+ print "\nOther pars: \n";
+ print " Left margin: $left_margin Right margin: $right_margin\n";
+ print " GP-extension: $ext_size GP xsize: $xsize GP ysize: $ysize\n";
+ print " Gray scale: $gray Smart x-tics is " . ($opt_T ? "ON" : "OFF") .
+ " Percentage y-axis is " . ($opt_P ? "ON" : "OFF") . "\n";
+ print " Log. scaling assoc list: ";
+ while (($key,$value) = each %logscale) {
+ print "$key: $value, ";
+ }
+ print "\n";
+ print " Active template file: $templ_file\n" if $opt_t;
+ print "-" x 70 . "\n";
+}
+
+# ----------------------------------------------------------------------------
+
+sub sort_and_cum {
+
+@sorted_rts = sort {$a <=> $b} @all_rts;
+
+($xstart_cluster_rts,$xend_cluster_rts,$max_cluster_rts,$xtics_cluster_rts) =
+ &write_cumulative_data($cumulat_rts_file_name,$clust_rts_file_name,@sorted_rts);
+
+$xend_cum_rts = pop(@sorted_rts);
+$yend_cum_rts = 100;
+$yend_cum0_rts = $#sorted_rts+1; # unpercentified cum graph
+
+open(RTS,">$rts_file_name") || die "$rts_file_name: $!";
+print RTS "Sorted list of all runtimes:\n";
+print RTS join("\n",@sorted_rts);
+close(RTS);
+
+@sorted_has = sort {$a <=> $b} @all_has;
+
+($xstart_cluster_has,$xend_cluster_has,$max_cluster_has,$xtics_cluster_has) =
+ &write_cumulative_data($cumulat_has_file_name,$clust_has_file_name,@sorted_has);
+
+$xend_cum_has = pop(@sorted_has);
+$yend_cum_has = 100;
+$yend_cum0_has = $#sorted_has+1; # unpercentified cum graph
+
+open(HAS,">$has_file_name") || die "$has_file_name: $!";
+print HAS "Sorted list of all heap allocations:\n";
+print HAS join("\n",@sorted_has);
+close(HAS);
+
+@sorted_lsps = sort {$a <=> $b} @all_local_sparks;
+
+open(LSPS,">$lsps_file_name") || die "$lsps_file_name: $!";
+print LSPS "Sorted list of all local sparks:\n";
+print LSPS join("\n",@sorted_lsps);
+close(LSPS);
+
+@sorted_gsps = sort {$a <=> $b} @all_global_sparks;
+
+open(GSPS,">$gsps_file_name") || die "$gsps_file_name: $!";
+print GSPS "Sorted list of all global sparks:\n";
+print GSPS join("\n",@sorted_gsps);
+close(GSPS);
+
+@sorted_fts = sort {$a <=> $b} @all_fts;
+
+($xstart_cluster_fts,$xend_cluster_fts,$max_cluster_fts,$xtics_cluster_fts) =
+ &write_cumulative_data($cumulat_fts_file_name,$clust_fts_file_name,@sorted_fts);
+
+$xend_cum_fts = pop(@sorted_fts);
+$yend_cum_fts = 100;
+$yend_cum0_fts = $#sorted_fts+1; # unpercentified cum graph
+
+open(FTS,">$fts_file_name") || die "$FTS_file_name: $!";
+print FTS "Sorted list of all communication times:\n";
+print FTS join("\n",@sorted_fts);
+close(FTS);
+
+@sorted_comm_percs = sort {$a <=> $b} @all_comm_percs;
+
+($xstart_cluster_cps,$xend_cluster_cps,$max_cluster_cps,$xtics_cluster_cps) =
+ &write_cumulative_data($cumulat_cps_file_name,$clust_cps_file_name,@sorted_comm_percs);
+
+$xend_cum_cps = 100; # pop(@sorted_comm_percs);
+$yend_cum_cps = 100;
+$yend_cum0_cps = $#sorted_comm_percs+1; # unpercentified cum graph
+
+open(CCPS,">$ccps_file_name") || die "$ccps_file_name: $!";
+print CCPS "Sorted list of all communication percentages:\n";
+print CCPS join("\n",@sorted_comm_percs);
+close(CCPS);
+
+($xstart_pe,$xend_pe,$max_pe,$xtics_pe) =
+ &write_array($pe_file_name,$#pe_load,@pe_load);
+
+($xstart_sn,$xend_sn,$max_sn,$xtics_sn) =
+ &write_array($sn_file_name,$#site_size,@site_size);
+
+if ( $opt_D ) {
+ print "After write_array: xstart, xend, max _sn: $xstart_sn,$xend_sn,$max_sn,$xtics_sn\n";
+}
+}
+
+# ----------------------------------------------------------------------------
+# Compute statistical values (like mean, std_dev and especially corr coeff).
+# Write the important info to a file.
+# ----------------------------------------------------------------------------
+
+sub do_statistics {
+ local ($n) = @_;
+
+ if ( $n <= 1 ) {
+ print "Sorry, no statistics for just $n threads\n";
+ return -1;
+ }
+
+# Compute mean values and std deviations
+# ......................................
+
+ ($mean_rt,$std_dev_rt) = &mean_std_dev($sum_rt,@all_rts);
+ ($mean_comm_perc,$std_dev_comm_perc) = &mean_std_dev($sum_comm_perc,@all_comm_percs);
+ ($mean_spark,$std_dev_spark) = &mean_std_dev($sum_sp,@all_sparks);
+ ($mean_local_spark,$std_dev_local_spark) = &mean_std_dev($sum_local_sp,@all_local_sparks);
+ ($mean_global_spark,$std_dev_global_spark) = &mean_std_dev($sum_global_sp,@all_global_sparks);
+ ($mean_ha,$std_dev_ha) = &mean_std_dev($sum_ha,@all_has);
+ ($mean_ft,$std_dev_ft) = &mean_std_dev($sum_ft,@all_fts);
+
+# Compute correlation coefficients
+# ................................
+
+ $c_exec_ha = &corr($#all_rts+1,$sum_rt,@all_rts,$sum_ha,@all_has);
+ $c_exec_sp = &corr($#all_rts+1,$sum_rt,@all_rts,$sum_sp,@all_sparks);
+ $c_exec_lsp = &corr($#all_rts+1,$sum_rt,@all_rts,$sum_local_sp,@all_local_sparks);
+ $c_exec_gsp = &corr($#all_rts+1,$sum_rt,@all_rts,$sum_global_sp,@all_global_sparks);
+ $c_ha_sp = &corr($#all_has+1,$sum_ha,@all_has,$sum_sp,@all_sparks);
+ $c_ha_lsp = &corr($#all_has+1,$sum_ha,@all_has,$sum_local_sp,@all_local_sparks);
+ $c_ha_gsp = &corr($#all_has+1,$sum_ha,@all_has,$sum_global_sp,@all_global_sparks);
+ $c_exec_ft = &corr($#all_rts+1,$sum_rt,@all_rts,$sum_ft,@all_fts);
+ $c_ha_ft = &corr($#all_has+1,$sum_ha,@all_has,$sum_ft,@all_fts);
+ $c_lsp_ft = &corr($#all_local_sparks+1,$sum_local_sp,@all_local_sparks,$sum_ft,@all_fts);
+ $c_gsp_ft = &corr($#all_global_sparks+1,$sum_global_sp,@all_global_sparks,$sum_ft,@all_fts);
+
+# Write corr coeffs into a file
+# .............................
+
+ open(CORR,">$corr_file_name") || die "Couldn't open file $corr_file_name\n";
+ #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) ;
+ printf CORR ("CORR of runtime and heap alloc: %f\n",$c_exec_ha);
+ printf CORR ("CORR of runtime and no. of sparks: %f\n",$c_exec_sp);
+ printf CORR ("CORR of heap alloc and no. sparks: %f\n",$c_ha_sp);
+ printf CORR ("CORR of runtime and no. of local sparks: %f\n",$c_exec_lsp);
+ printf CORR ("CORR of runtime and no. of global sparks: %f\n",$c_exec_gsp);
+ printf CORR ("CORR of heap alloc and no. local sparks: %f\n",$c_ha_lsp);
+ printf CORR ("CORR of heap alloc and no. global sparks: %f\n",$c_ha_gsp);
+ printf CORR ("CORR of runtime and communication time: %f\n",$c_exec_ft);
+ printf CORR ("CORR of heap alloc and communication time: %f\n",$c_ha_ft);
+ printf CORR ("CORR of no. of local sparks and communication time: %f\n",$c_lsp_ft);
+ printf CORR ("CORR of no. of global sparks and communication time: %f\n",$c_gsp_ft);
+ close(CORR);
+
+# These are needed later in the GNUPLOT files
+# ...........................................
+
+ $max_rt_class = &list_max(@exec_class);
+ $max_rt_global_class = &list_max(@exec_global_class);
+ $max_rt_local_class = &list_max(@exec_local_class);
+ $max_comm_perc_class = &list_max(@comm_class);
+ $max_comm_perc_global_class = &list_max(@comm_global_class);
+ $max_comm_perc_local_class = &list_max(@comm_local_class);
+ $max_spark_class = &list_max(@spark_class);
+ $max_spark_local_class = &list_max(@spark_local_class);
+ $max_spark_global_class = &list_max(@spark_global_class);
+ $max_ha_class = &list_max(@ha_class);
+ $max_ft_class = &list_max(@fetch_class);
+
+}
+
+# ----------------------------------------------------------------------------
+# This is written to STDOUT at the end of the file processing (before
+# gnuplotting and such) if the verbose option is given.
+# ----------------------------------------------------------------------------
+
+sub print_general_info {
+
+ printf("\nTotal number of lines: %d\n", $line_no);
+
+ print "\nDistribution of execution times: \n";
+ print " Intervals: " . join('|',@exec_times) . "\n";
+ print " Total: " . join('|',@exec_class) . "\n";
+ print " Global: " . join('|',@exec_global_class) . "\n";
+ print " Local: " . join('|',@exec_local_class) . "\n";
+
+ $total=0; foreach $i (@exec_class) { $total += $i ; }
+ $global=0; foreach $i (@exec_global_class) { $global += $i ; }
+ $local=0; foreach $i (@exec_local_class) { $local += $i ; }
+
+ print " Sum of classes (should be " . $line_no . "): " . $total .
+ " (global/local)=(" . $global . "/" . $local . ")\n";
+ print " Mean value: $mean_rt Std dev: $std_dev_rt\n";
+
+ print "\nPercentage of communication: \n";
+ print " Intervals: " . join('|',@comm_percs) . "\n";
+ print " Total: " . join('|',@comm_class) . "\n";
+ print " Global: " . join('|',@comm_global_class) . "\n";
+ print " Local: " . join('|',@comm_local_class) . "\n";
+ print " Values outside closed int: Total: " . $outside .
+ " Global: " . $outside_global . " Local: " . $outside_local . "\n";
+
+ $total=0; foreach $i (@comm_class) { $total += $i ; }
+ $global=0; foreach $i (@comm_global_class) { $global += $i ; }
+ $local=0; foreach $i (@comm_local_class) { $local += $i ; }
+
+ print " Sum of classes (should be " . $line_no . "): " . $total .
+ " (global/local)=(" . $global . "/" . $local . ")\n";
+ print " Mean value: $mean_comm_perc Std dev: $std_dev_comm_perc\n";
+
+ print "\nSparked threads: \n";
+ print " Intervals: " . join('|',@sparks) . "\n";
+ print " Total allocs: " . join('|',@spark_class) . "\n";
+
+ $total=0; foreach $i (@spark_class) { $total += $i ; }
+
+ print " Sum of classes (should be " . $line_no . "): " . $total . "\n";
+ print " Mean value: $mean_spark Std dev: $std_dev_spark\n";
+
+ print "\nHeap Allcoations: \n";
+ print " Intervals: " . join('|',@has) . "\n";
+ print " Total allocs: " . join('|',@ha_class) . "\n";
+
+ $total=0; foreach $i (@ha_class) { $total += $i ; }
+
+ print " Sum of classes (should be " . $line_no . "): " . $total . "\n";
+ print " Mean value: $mean_ha Std dev: $std_dev_ha\n";
+ print "\n";
+ print "CORRELATION between runtimes and heap allocations: $c_exec_ha \n";
+ print "CORRELATION between runtime and no. of sparks: $c_exec_sp \n";
+ print "CORRELATION between heap alloc and no. sparks: $c_ha_sp \n";
+ print "CORRELATION between runtimes and locally sparked threads: $c_exec_lsp \n";
+ print "CORRELATION between runtimes and globally sparked threads: $c_exec_gsp \n";
+ print "CORRELATION between heap allocations and locally sparked threads: $c_ha_lsp \n";
+ print "CORRELATION between heap allocations and globally sparked threads: $c_ha_gsp \n";
+ print "CORRELATION between runtime and communication time: $c_exec_ft\n";
+ print "CORRELATION between heap alloc and communication time: $c_ha_ft\n";
+ print "CORRELATION between no. of local sparks and communication time: $c_lsp_ft\n";
+ print "CORRELATION between no. of global sparks and communication time: $c_gsp_ft\n";
+ print "\n";
+
+}
+
+# ----------------------------------------------------------------------------
+# Old (obsolete) stuff
+# ----------------------------------------------------------------------------
+#
+#for ($index=0;
+# $index <= &list_max($#spark_local_class,$#spark_local_class);
+# $index++) {
+# $spark_class[$index] = $spark_local_class[$index] + $spark_global_class[$index];
+#}
+#
+#for ($index=0, $sum_sp=0;
+# $index <= &list_max($#all_local_sparks,$#all_global_sparks);
+# $index++) {
+# $all_sparks[$index] = $all_local_sparks[$index] + $all_global_sparks[$index];
+# $sum_sp += $all_sparks[$index];
+#}
+#
+# ----------------------------------------------------------------------------
+#
+#sub compute_delta {
+# local (@times) = @_;
+#
+# return ($times[$#times] - $times[$#times-1]);
+#}
+#
+# ----------------------------------------------------------------------------
+
+sub insert_elem {
+ local ($elem,$val,$n,*list1,*list2) = @_;
+ local (@small_part, $i, $len);
+
+ if ( $opt_D ) {
+ print "Inserting val $val (with elem $elem) in the following list: \n" .
+ @list . "\n yields the lists: \n ";
+ }
+
+ for ($i=0; $i<=$#list2 && $list2[$i]>$val; $i++) { }
+ $len = $#list2 - $i + 1;
+ if ( $len == 0 ) {
+ push(@list1,$elem);
+ push(@list2,$val);
+ } else {
+ splice(@list1,$i,0,$elem);
+ splice(@list2,$i,0,$val);
+ }
+
+ if ( $opt_D ) {
+ print @list1 . "\n and \n" . @list2;
+ }
+
+}
+
+# ----------------------------------------------------------------------------
+
+sub skip_header {
+ local ($in_header);
+
+ $in_header = 9;
+ while (<INPUT>) {
+ if ( $in_header = 9 ) {
+ if (/^=/) {
+ $gum_style_gr = 1;
+ $in_header = 0;
+ $prg = "????"; #
+ $pars = "-b??????"; #
+ $nPEs = 1; #
+ $lat = 1;
+ return ($prg, $pars, $nPEs, $lat);
+ } else {
+ $gum_style_gr = 0;
+ $in_header = 1;
+ }
+
+ }
+ $prg = $1, $pars = $2 if /^Granularity Simulation for\s+(\w+)\s+(.*)$/;
+ $nPEs = $1 if /^PEs\s+(\d+)/;
+ $lat = $1, $fetch = $2 if /^Latency\s+(\d+)[^F]+Fetch\s+(\d+)/;
+
+ last if /^\+\+\+\+\+/;
+ }
+}
+
+# ----------------------------------------------------------------------------
+
+sub write_pie_chart {
+ local ($rt_perc, $bt_perc, $ft_perc, $it_perc);
+ local ($title, $title_sz, $label_sz, $x_center, $y_center, $radius);
+
+ $PieChart = "/users/fp/hwloidl/grasp/GrAn/bin/PieChart.ps";
+
+ $title = "Original Glaswegian Communication Pie (tm)";
+ $title_sz = 24;
+ $label_sz = 12;
+ $x_center = 300;
+ $y_center = 400;
+ $radius = 100;
+
+ open(PIE,">$pie_file_name") || die "$pie_file_name: $!";
+
+ print PIE "%!PS-Adobe-2.0\n";
+ print PIE "%%Title: Pie Chart\n";
+ print PIE "%%Creator: gran-extr\n";
+ print PIE "%%CreationDate: Ides of March 44 B.C.\n";
+ print PIE "%%EndComments\n";
+ print PIE "\n";
+ print PIE "% Def of PieChart is taken from:\n";
+ print PIE "% ($PieChart) run\n";
+ print PIE "\n";
+
+ open(PIE_CHART,"<$PieChart") || die "$PieChart: $!";
+ while (<PIE_CHART>){
+ print PIE $_;
+ }
+ close (PIE_CHART);
+ print PIE "\n";
+
+ $rt_perc = $tot_rt / $tot_total_rt;
+ $bt_perc = $tot_bt / $tot_total_rt;
+ $ft_perc = $tot_ft / $tot_total_rt;
+ $it_perc = $tot_it / $tot_total_rt;
+
+ print PIE "($title) $title_sz $label_sz % Title, title size and label size\n" .
+ "[ % PS Array of (descrition, percentage [0, .., 1])\n" .
+ "[(Run Time) $rt_perc]\n" .
+ "[(Block Time) $bt_perc]\n" .
+ "[(Fetch Time) $ft_perc]\n" .
+ "[(Ready Time) $it_perc]\n" .
+ "] $x_center $y_center $radius DrawPieChart\n";
+ print PIE "showpage\n";
+
+ close(PIE);
+}
+
+# ----------------------------------------------------------------------------
+
+sub basename {
+ local ($in_str) = @_;
+ local ($str,$i) ;
+
+ $i = rindex($in_str,"/");
+ if ($i == -1) {
+ $str = $in_str;
+ } else {
+ $str = substr($in_str,$i+1) ;
+ }
+
+ return $str;
+}
+
+# ----------------------------------------------------------------------------
+
+sub dirname {
+ local ($in_str) = @_;
+ local ($str,$i) ;
+
+ $i = rindex($in_str,"/");
+ if ($i == -1) {
+ $str = "";
+ } else {
+ $str = substr($in_str,0,$i+1) ;
+ }
+
+ return $str;
+}
+
+# ----------------------------------------------------------------------------
+