# perf prints out a matlab-formatted performance profile, # as described in the report # Benchmarking Optimization Software with Performance Profiles, # E.D.Dolan and J.J.More', # Preprint ANL/MCS-P861-1200, # Mathematics and Computer Science, Argonne National Laboratory # January 2001 # # usage: perl perf [-log] [-error error_value] file1 file2 [file3..fileN] # # perf reads in data from files containing performance data # for some metric. # Each piece of software requires its own data file, and each # line in the file should have one positive metric value # representing the software's performance on a test problem. # Because each line corresponds to a test problem, the # order of the problem values should be maintained across files. # The required arguments (of which there must be at least 2) are the # names of the data files. # The optional argument -error allows you to specify a # number that will represent an error condition for solves. You are # free to choose a negative number to represent failed solves in your # data files. # There is an option (-log) to print a log (base 2) scaled performance # profile. # # Clearly, the readability of the graphs should be improved manually. # You can adjust the width of the axes with "axis([xmin xmax ymin ymax])" # on the command line in Matlab. # # Liz Dolan January 2001 if(($#ARGV) < 1) { &usage; } $LOG=0; $num_solvers=0; $count=0; $error_value = -27; $error_count = -1; @INPUT = ("left blank"); foreach $arg (@ARGV) { if($count==$error_count) { $count++; next; } if ($arg =~ /^\s*-log\s*$/) { $LOG=1; } else { if ($arg =~ /^\s*-error\s*$/) { if($#ARGV >= $count+1) { $error_value = $ARGV[$count+1]; $error_count = $count+1; } else { &usage; } } else { $num_solvers++; @INPUT = (@INPUT, $arg); } } $count++; } $MATLABMAX = 1; $largest = -1; #Once ratios have been found, choose a number for MATLABMAX that #if well above the largest ratio $num_probs = -1; #find the number of problems == #initial non-blank lines in first file @colors=("y", "m", "c", "r", "g", "b", "k"); @lines=("-", ":", "-.", "--"); for($sols=1; $sols <= $num_solvers; $sols++) { open(READ, "$INPUT[$sols]") or die "Could not open Input at $sols $INPUT[$sols]\n"; @metric = ; if($num_probs == -1) { $num_probs = 0; for($p=0;; $p++) { if($metric[$p] =~ /\S/) { $num_probs++; } else { last; } } } for($p=0; $p<$num_probs; $p++) { if(!($metric[$p] > 0.0)) { if($metric[$p] != $error_value) { print STDERR "All values in the file must be positive or equal to the error_value, \n$metric[$p] \non line $p of file $INPUT[$sols] is not.\n"; die; } } $solver[$sols][$p] = $metric[$p]; } close(READ); } # # Find a good value for MATLABMAX # for ($i=0; $i<$num_probs; $i++) { @prob_times=(); for($s=1; $s <= $num_solvers; $s++) { if($solver[$s][$i] != $error_value) { @prob_times = (@prob_times, $solver[$s][$i]); } } @ordered = sort {$a<=>$b} (@prob_times); if($#ordered >=0 ) { $ratio = $ordered[$#ordered] / $ordered[0]; if($LOG) { $ratio = log($ratio) / log(2); } if($ratio > $largest) { $largest = $ratio; } } } $MATLABMAX = 1.01 * ($largest); for ($i=0; $i<$num_probs; $i++) { @prob_times = (); for($s=1; $s <= $num_solvers; $s++) { if($solver[$s][$i] != $error_value) { @prob_times = (@prob_times, $solver[$s][$i]); } } @ordered = sort {$a<=>$b} (@prob_times); for($s=1; $s <= $num_solvers; $s++) { if($solver[$s][$i] == $error_value) { $prob_ratio = $MATLABMAX; } else { $prob_ratio = ((1.0 * $solver[$s][$i]) / $ordered[0]); if($LOG) { $prob_ratio = log($prob_ratio) / log(2); } } $solver_ratios[$s][$i] = $prob_ratio; } } for($s = 1; $s<=$num_solvers; $s++) { @rarray = (); for($p=0; $p<$num_probs; $p++) { @rarray = (@rarray, $solver_ratios[$s][$p]); } @ordered = sort {$a<=>$b} @rarray; $j = 1; print "solver$s = [\n"; print "0 0\n"; foreach $rat (@ordered) { printf ("%16.6f $j/$num_probs\n", $rat); $j++; } print "]\n"; if($s==1) { print "hold off\nstairs(solver$s(:,1),solver$s(:,2), '$lines[1]$colors[1]')\n"; } else { $col = $s % @colors; $lin = $s % @lines; print "hold on\nstairs(solver$s(:,1),solver$s(:,2), '$lines[$lin]$colors[$col]')\n"; } } $xlim = $MATLABMAX / 1.005; if($LOG) { print "axis([0 $xlim 0 1])\n"; } else { print "axis([1 $xlim 0 1])\n"; } sub usage { print "usage: perl perf [-log] [-error error_value] file1 file2 [file3..fileN]\n"; print "where -log produces log base 2 scaling of the performance profile,\n"; print "where error_value is an integer that indicates that a solve failed,\n"; print "and where each file contains performance data on the problems for one solver.\n"; print "The data should be given in the same order for each solver, one number per line.\n"; foreach $arg (@ARGV) { print "Arg: $arg\n"; } exit(1); }