#!/usr/bin/perl -w

#Converts bps output log files to html documents
#Takes one argument, the directory containing the log files

$numargs=@ARGV;
if ($numargs!=1) {
printf "Error: Invalid arguments\n";
printusage();
exit 1;
}

$logdirname=$ARGV[0];
$logdirname=~s/\/[ 	]*$//;

if (! -e $logdirname) {
printf "Error: %s does not exist\n",$logdirname;
printusage();
exit 1;
}

if (! -w $logdirname) {
printf "Error: %s is not writable\n",$logdirname;
printusage();
exit 1;
}

opendir(DIR, $logdirname);
@nasbname= grep { /^npb(\.\w+){3}\.\d+$/ } readdir(DIR);
closedir(DIR);
$count=0;

#nas log handling
foreach $naslog (@nasbname){
	$naslogs[$count]="${logdirname}/${naslog}";
	$count++;
}

#logfile handling
%logs = (
    bonnie   =>   "${logdirname}/bonnie.log",
    netpipe   =>   "${logdirname}/netpipe.log",
    netperf   =>   "${logdirname}/netperf.log",
    stream   =>   "${logdirname}/stream.log",
    unixbench   =>   "${logdirname}/unixbench.log",
    lmbench	=>	"${logdirname}/lmbench.log",
);

#basenames needed for file handling
%bname = (
	bonnie => "bonnie.log",
	netpipe => "netpipe.log",
	netperf => "netperf.log",
	stream => "stream.log",
	unixbench => "unixbench.log",
	lmbench => "lmbench.log",
);

#first handle NAS benchlogs
if (open(INDEX, ">${logdirname}/index.html")) {

InitIndex(INDEX);

$count=0;
foreach $filename (@naslogs) {
	$logname=$nasbname[$count];
	if ( open(LOG, $filename) ) {
		$htmlfile= $filename . ".html";
    
		if (open(HTML,">" . $htmlfile )) {
   	printf "Generating: ${logname}.html\n";
	printf INDEX "<LI><A HREF=\"" . $logname . ".html\">NAS Parallel:${logname} results</A>\n";
 
      PrintHTMLHeader(HTML, $logname);
            
      while ( <LOG> ) {
			next if /^\s*$/; # Ignore blank lines
      
			if($_ =~ /\[.start.*NAS.*\]/) {
				NAS(LOG, HTML, "NAS", $logname);
			} else { # no start header... don't know what to do
				next	#s/\n/<BR>\n/g;
				#printf HTML "%s", $_;
			}
        }
        
		PrintHTMLFooter(HTML, $logname);
	}
	close(HTML);    
     }
     $count++;
}

#handle all other bench logs
foreach $log (sort(keys %logs)) {
	$filename=$logs{$log};	
	$logname=$bname{$log};

	if ( open(LOG, $filename) ) {
		$htmlfile= $filename . ".html";
    
		if (open(HTML,">" . $htmlfile )) {
   	printf "Generating: ${logname}.html\n";
	printf INDEX "<LI><A HREF=\"" . $logname . ".html\">" . $log . " results</A>\n";
 
      PrintHTMLHeader(HTML, $logname);
            
      while ( <LOG> ) {
			next if /^\s*$/; # Ignore blank lines
      
      	# s/\[.(start|end).*$log.*\]/<B>$&<\/B>/g;
      	# s/\]/\]<\/B>/g;
      
			if($_ =~ /\[.start.*$log.*\]/) {
				$log->(LOG, HTML, $log, $logname); # call the function named $log
			} else { # no start header... don't know what to do
				next	#s/\n/<BR>\n/g;
				#printf HTML "%s", $_;
			}
		}
        
		PrintHTMLFooter(HTML, $logname);
	}
	close(HTML);    
}
else{
	printf "$logname not found, no file generated\n";
}
close(LOG);
}

printf INDEX "</UL>\n";
PrintHTMLFooter(INDEX, "Beowulf Performance Suite Reult Index");

close(INDEX);
}

sub printusage{
printf("Usage: %s <log directory>\n\n", $0);
}

#benchmark specific functions, processes the output files
sub lmbench{
   my ($file, $output, $benchname, $logfile) =@_;
	while(<$file>) {
		my $line = $_ ;
		$line =~ s/\[.end.*$//;
		printf $output "${line}\n";
	}
   printf $output "%s", "<P>Click <A HREF=\"$logfile\">here</A> for full lmbench output.\n";
}

sub NAS{
   my ($file, $output, $benchname, $logfile) = @_;
   my %benchval ;
   my $time=""; my $mopstot=""; my $mopsproc=""; my $program=""; my $info="";
   printf $output "%s\n", "<CENTER>";
   printf $output "%s\n", "<P><H1>NAS Results Summary</H1>";
   printf $output "%s\n", "<TABLE BORDER=1>"; # table header
   printf $output "%s\n", "<TR>" . 
                          "<TD><B>Test Name" . 
                          "<TD><B>MOPS Total" . 
                          "<TD><B>MOPS/CPU" .
                          "<TD><B>Time</TR>";
   while(<$file>) {
       if(/^.*(Mop\/s\ total|Mop\/s\/process|Time|PROGRAM|Compiler:|MPI:|Processors:|Size:).*$/) {
	   my $line = $_ ;
	   my @temp = split;
	   if ($temp[0] eq "Compiler:")
	   {
	   	$info = $line;
	   }
	   if ($temp[0] eq "Time")
	   {
	       $time=$temp[4];
	   }
	   if ($temp[0] eq "Mop/s")
	   {
	       $mopstot=$temp[3];
	   }
	   if ($temp[0] eq "Mop/s/process")
	   {
	       $mopsproc=$temp[2];
	       if ($mopsproc ne "NOT") {
	       printf $output "\t<TR><TD>${program}<TD>${mopstot}<TD>${mopsproc}<TD>${time}</TR>\n";
	   }
	   }
	   if ($temp[1] eq "PROGRAM")
	   {
	       $program = $temp[2];
	   }
        }
   }
   printf $output "%s", "</TABLE>\n"; # table footer
   printf $output "${info}\n";
   printf $output "%s\n", "</CENTER>";
   printf $output "%s", "<P>Click <A HREF=\"$logfile\">here</A> for full NAS benchmarks output.\n";
}

sub bonnie{
   my ($file, $output, $benchname, $logfile) = @_;
   my %benchval ;
   @bonnietests = ("Seq Output Per Chr", "Seq Output Block", "Seq Output Rewrite", "Seq Input Per Chr", "Seq Input Block", "Random Seeks","Seq Create","Seq Read","Seq Delete","Random Create","Random Read","Random Delete"); 
   printf $output "%s\n", "<CENTER>";
   printf $output "%s\n", "<P><H1>Bonnie Results Summary</H1>";
   printf $output "%s\n", "<P><P>Data I/O Results";
   printf $output "%s\n", "<TABLE BORDER=1>"; # table header
   while(<$file>) {
      if( /^.*\d\,\d.*$/ ) { 
         my $i = 0 ;
	 my $j = 0 ;
         my $line = $_ ;
	 my $temp;
         foreach $temp (split("," , $line)) {
	   if ($temp=~/^\s*\d.*$/) {
            if($i == 0) {
		#$temp=~s/\D//;
               printf $output "%s", "<TR>" . 
               "<TD BGCOLOR=BLACK><FONT COLOR=WHITE>${temp} file" ;
               printf $output "%s\n", "<TD><B>kB/sec</B><TD><B>%CPU</B></TR>";
            }
	    elsif($i == 13) {
	       printf $output "%s", "</TABLE>\n";
	       printf $output "%s\n", "<P><P>File Creation Results";
	       printf $output "%s\n", "<TABLE BORDER=1>"; # table header
               printf $output "%s", "<TR>" . 		
               "<TD BGCOLOR=BLACK><FONT COLOR=WHITE>${temp} files" ;
               printf $output "%s\n", "<TD><B>files/sec</B><TD><B>%CPU</B></TR>";
	       $i++;
	    }
	    else {
               if($i % 2 == 1) {
                  printf $output "%s", "<TR><TD>" . $bonnietests[$j] . "<TD>$temp</TD>";
		  $j++;
               } else {
                   printf $output "%s\n", "<TD>$temp</TR>";
               }
            }
	    $i++;	               
	  }
         }
      } 
   }
   printf $output "%s", "</TABLE>\n"; # table footer
   printf $output "%s\n", "</CENTER>";
   printf $output "%s", "<P>Click <A HREF=\"$logfile\">here</A> for full $benchname output.\n";
}

sub netpipe{
   #next;
   my $interface=0;
   system ("cp /opt/bps/bin/netpipe.*.gp $logdirname");
   system ("cd $logdirname; gnuplot netpipe.network_signature_graph.gp; gnuplot netpipe.throughput_vs_blocksize.gp");
   system ("rm $logdirname/netpipe.*.gp");
   my ($file, $output, $benchname, $logfile) = @_;
   printf $output "%s\n", "<CENTER>";
   printf $output "%s\n", "<P><H1>NetPipe TCP Results Summary</H1>";
   printf $output "</CENTER>\n";
   my $greatest=0;
   my @line;
   while(<$file>) {
	next if /^\s*$/; # Ignore blank lines
	my @temp = split ;
	if ($temp[0] eq "Netpipe") {
	    $interface=$temp[2];
	}
	if ($temp[0] eq "Latency:") {
		printf $output "<P>%s %s (microseconds)\n",$temp[0],$temp[1];
	}
	if ($temp[6]) {
		if ($temp[6] >= $greatest) {
			$greatest = $temp[6];
			@line = @temp;
		}
	}
	    
   }
   printf $output "<P>Interface: ${interface}\n";
   printf $output "%s", "<P>Greatest throughput at <B>$greatest Mbps</B>:\n" . 
   "<BR>&nbsp;&nbsp;&nbsp;&nbsp;@line\n";
   printf $output "%s","<BR><img src= \"netpipe.network_signature_graph.png\" border = \"5\" height=\"500\" width=\"700\" align=\"right,left,center\">\n";
   printf $output "%s","<BR><img src=\"netpipe.throughput_vs_blocksize.png\" border = \"5\" height=\"500\" width=\"700\" align=\"right,left,center\">\n";
   printf $output "%s", "<P>Click <A HREF=\"$logfile\">here</A> for full $benchname output.<BR>\n"; 

}

sub netperf{
   #my @line = /^.*start netperf.*$/;
   my ($file, $output, $benchname, $logfile) = @_;
   my $interface=0;
   printf $output "%s\n", "<CENTER>";
   printf $output "%s\n", "<P><H1>NetPerf Results Summary</H1>";
   printf $output "%s\n", "<TABLE BORDER=1>"; # table header
   printf $output "%s\n", "<TR BGCOLOR=BLACK>" . 
	"<TD COLSPAN=6><FONT COLOR=WHITE><B>UDP Unidirectional Send Test</TR>";
   printf $output "%s\n", "<TR BGCOLOR=BLACK>" .
   			"<TD><FONT COLOR=WHITE>Socket Size<BR>(Bytes)" . 
			"<TD><FONT COLOR=WHITE>Message Size<BR>(Bytes)" .
			"<TD><FONT COLOR=WHITE>Elapsed Time<BR>(Secs)" .
			"<TD><FONT COLOR=WHITE>Messages Okay<BR>(#)" .
			"<TD><FONT COLOR=WHITE>Message Errors<BR>(#)" .
			"<TD><FONT COLOR=WHITE>Throughput<BR>(10^6bits/sec)" .
			"</TR>\n";
   my $state=0;
   while(<$file>) {
	next if /^\s*$/; # Ignore blank lines
	if (/^\s*Netperf.*$/) {
	    my @temp = split;
	    $interface=$temp[2];
	}
	if (/^\s*TCP.*$/) {
		$state=1 ;
	  	printf $output "</TABLE>\n" . "<BR><BR>" . "<TABLE BORDER=1>\n";
		printf $output "%s\n", "<TR BGCOLOR=BLACK>" . 
			"<TD COLSPAN=5><FONT COLOR=WHITE>" .
			"<B>TCP Stream Test</B>" . "</TR>";
		printf $output "%s\n", "<TR BGCOLOR=BLACK>" .
			"<TD><FONT COLOR=WHITE>Recv Socket Size<BR>(Bytes)" .
			"<TD><FONT COLOR=WHITE>Send Socket Size<BR>(Bytes)" .
			"<TD><FONT COLOR=WHITE>Send Message Size<BR>(Bytes)" .
			"<TD><FONT COLOR=WHITE>Elapsed Time<BR>(Secs)" .
			"<TD><FONT COLOR=WHITE>Throughput<BR>(10^6bits/sec)" .
			"</TR>";
	}
      	if($state==0) {
		if(/^\s*(\d+(\.\d+)?\s*){1,6}$/) {
			printf $output "<TR>";
			my @temp = split ;
			if(scalar(@temp)==4) {
				printf $output
				"<TD>%s<TD><TD>%s<TD>%s<TD><TD><B>%s", @temp ;
			} else {
				printf $output
				"<TD>%s<TD>%s<TD>%s<TD>%s<TD><FONT " .
				"COLOR=RED>%s<TD><B>%s", @temp;
			}
			printf $output "</TR>\n";
		}
	} else {
		if(/^\s*(\d+(\.\d+)?\s*){1,6}$/) {
			printf $output "<TR>";
			my $x=0;
			foreach(split) {
				$x++;
				if($x==5) {
					printf $output "<TD><B>%s", $_;
				} else {
					printf $output "<TD>%s", $_;
				}
			}
			printf $output "</TR>\n";
		}
	}
   }
   printf $output "%s", "</TABLE>\n"; # table footer
   printf $output "<P>Interface: ${interface}\n";
   printf $output "%s\n", "</CENTER>";
   printf $output "%s", "<P>Click <A HREF=\"$logfile\">here</A> for full $benchname output.\n"; 
}

sub stream{
   my ($file, $output, $benchname, $logfile) = @_;
   my @temp;
   printf $output "%s\n", "<CENTER>";
   printf $output "%s\n", "<P><H1>Stream Results Summary</H1>";
   printf $output "%s\n", "<TABLE BORDER=1>";
   printf $output "%s\n", "<TR>" . 
                          "<TD><B>Function" .
                          "<TD><B>Rate (MB/s)" . 
                          "<TD><B>RMS time" .
                          "<TD><B>Min time" .
                          "<TD><B>Max time</TR>";
   while(<$file>) {
      if(/^\s*(Array size|Total memory required).*$/) {
	push  (@temp,$_)
      }
      if(/^\s*(Copy|Scale|Add|Triad)\d?.*$/) {
         my $i=0;
         printf $output "%s", "\t<TR>";
         foreach (split) {
            if ($i==0) { s/://g ; } # remove the :
            printf $output "%s", "<TD>$_";
            $i++;
         }
         printf $output "%s\n", "</TR>";
      }
   }
   printf $output "%s\n", "</TABLE>"; # table footer
   foreach $line (@temp) {
	printf $output "<P>${line}\n";
   }
   printf $output "%s\n", "</CENTER>";
   printf $output "%s", "<P>Click <A HREF=\"$logfile\">here</A> for full $benchname output.\n"; 
}

sub unixbench{
   my ($file, $output, $benchname, $logfile) = @_;
   printf $output "%s\n", "<CENTER>";
   printf $output "%s\n", "<P><H1>UnixBench Results Summary</H1>";
   printf $output "%s\n", "<TABLE BORDER=1>";
   printf $output "%s\n", "<TR>" . 
                          "<TD><B>Test" . 
                          "<TD><B>Baseline" . 
                          "<TD><B>Result" .
                          "<TD><B>Index";
   while (<$file>) {
      if(/^.*\s?\d?\.\d$/) {
         my @temp = split ;
         if (/FINAL\sSCORE.*$/) { 
            $temp[-2] .= "<TD ALIGN=RIGHT>" ;
            printf $output "%s\n", "<TR><TD COLSPAN=3><B>@temp";
         } else {
            # s/\d?\.\d/<TD>$&/g ;
            $temp[-2] .= "<TD ALIGN=RIGHT>";
            $temp[-3] .= "<TD ALIGN=RIGHT>";
            $temp[-4] .= "<TD ALIGN=RIGHT>";
            printf $output "%s\n", "\t<TR><TD>@temp</TR>";
         }
      }
   }
   printf $output "%s\n", "</TABLE>"; # table footer
   printf $output "%s\n", "</CENTER>";
   printf $output "%s", "<P>Click <A HREF=\"$logfile\">here</A> for full $benchname output.\n"; 
}

#header and footer functions for general benchmark html files
sub PrintHTMLHeader {
   my ( $file, $title ) = @_ ;
   printf $file "<!DOCTYPE HTML PUBLIC\"-//W3C//DTD HTML 3.2 Final//EN\">\n";
   printf $file "<HTML>\n<HEAD>\n<TITLE>" . $title . "</TITLE>\n</HEAD>\n<BODY BGCOLOR=WHITE>\n";
}

sub PrintHTMLFooter {
   # $title not needed... just in for consistency of function calls
   my ( $file, $title ) = @_ ;
   printf $file "</BODY>\n</HTML>\n";
}

#Initialization function for html files
sub InitIndex {
   my ($index) = @_;
   my $line;
   my @templine;
   PrintHTMLHeader($index, "Beowulf Performance Suite Results");
   printf $index "<P><B><H1>Beowulf Performance Suite Results</H1></B>\n";
   printf $index "Generated on ". `date +%Y-%m-%d` .
           " at " . `date +%H:%M` . " by Beowulf Performance Suite</A><P>\n";
   printf $index "<P><B>Beowulf Performance Suite.</B> <br>";
   printf $index "Test suite information is available <A HREF=\"/usr/share/doc/bps-1.4/tests.html\">here</A>.<br> License information is available <A HREF=\"/usr/share/doc/bps-1.4/LICENSE\">here.</A></P>\n";
printf $index "<B>Machine Data:</B>\n";
   my $machine = "${logdirname}/machine.data";
   my $cpuNumber=1;
   my $cpumhzNumber=1;
   if (open(FILE, $machine)) {
   printf $index "%s\n", "<TABLE BORDER=1>";
    while (<FILE>) {
	if(/^\s*(Motherboard|Memory:|Interconnects:|Linux Version:).*$/) {
	    $line=$_;
	    $line=~s/: /<TD>/;
	}
	else {
	    $line=$_;
	    @templine = split;
	    if ($templine[0] eq "model") {
		$line=~s/model name/CPU ${cpuNumber} Model/;
		$line=~s/: /<TD>/;
		$cpuNumber++;
	    }
	    elsif($templine[0] eq "cpu") {
		$line=~s/cpu/CPU ${cpumhzNumber}/;
		$line=~s/: /<TD>/;
		$cpumhzNumber++;
	    }
	    else {
		$line = "Machine Name <TD>${templine[1]}<TR><TD>Kernel<TD>${templine[2]}";	    
	    }
	}
 	printf $index "<TR><TD>%s</TR>\n", $line;
    }
   printf $index "</TABLE>\n";
   printf $index "<P><B>Benchmarks:</B>\n";
   printf $index "<UL>\n";
  }
}









