#!/usr/local/bin/perl

use Getopt::Long;

# Read the dump file into "all_funcs_file"
&GetOptions("file=s" => \$all_funcs_file);

# temporary output file
$out_file = "__$all_funcs_file.out";

# Open the input file
open (AF_FILE, "<$all_funcs_file") || die "Can't open input file $all_funcs_file\n";


#
# Arguments to cdriver to index into its dimension array
# {0, 1, 2, 3, 4};
# And the corresponding dimensions are
# {64.0, 128.0, 256.0, 512.0, 1024.0};
#
while (<AF_FILE>) { # for each benchmark in the input file
  # Open the output file
  open (OUT_FILE, ">$out_file") || die "can't open $out_file\n";
  print (OUT_FILE $_);
  close (OUT_FILE);
  
  $ret_code = (0xffff & system("./cdriver -f $out_file -v 2> /dev/null")) >> 8;
  print "\n";
  if ($ret_code == 0xfd) { next; } # look at the next benchmark

  for($dim_idx=0; $dim_idx < 5; $dim_idx++) { # for each dimension
    # Get the return code
    $rc = (0xffff & system("./cdriver -n $dim_idx -f $out_file 1> __cdriver.out.tmp 2> /dev/null")) >> 8;
    if ($rc == 139) { # Check for seg fault
      system("/bin/rm -f core");
      $misses[$dim_idx] = -1000000;
      $denom[$dim_idx] = 1 << (6+$dim_idx);
      print "\nFatal error: Seg Fault in cdriver for dimension $denom[$dim_idx]\n";
      system("/bin/rm -f __cdriver.out.tmp");
      next;  # look at the next dim_idx
    }
    elsif ($rc == 253) {
      $misses[$dim_idx] = -1000000;
      $denom[$dim_idx] = 1 << (6+$dim_idx);
      print "\nFatal error: Error in your implementation for dimension $denom[$dim_idx]\n";
      system("cat __cdriver.out.tmp; /bin/rm -f __cdriver.out.tmp");
      next;  # look at the next dim_idx
    }
    else {
      system("/bin/rm -f __cdriver.out.tmp");
    }
    sleep(0.1); # To allow cacheprof's files to go to disk

    $cache_count = `tail -1 cacheprof.out.summary`;
    @line = split(/[,\)]\s+/, $cache_count);
    # 1 == reads, 2 == writes, 3 == read misses, 4 == write misses
    # We need to eat the trailing ',' in the number.
    $misses[$dim_idx] = $line[3] + $line[4];
    $denom[$dim_idx] = 1 << (6+$dim_idx);
  }
  print "Version: $_";
  print "Dim";
  for($dim_idx=0; $dim_idx < 5; $dim_idx++) {
    print "\t  " . $denom[$dim_idx];
  }
  print "\n";
  print "Score";
  for($dim_idx=0; $dim_idx < 5; $dim_idx++) {
    printf "\t %.4f",
      $misses[$dim_idx]/($denom[$dim_idx]*$denom[$dim_idx]);
  }
  print "\n";
}

# clean up
system("/bin/rm -f $out_file");
close (AF_FILE);



