diff scripts/run.bmark @ 23:90197e3375e2 pygar svn.24

[svn r24] added testing, but something is wrong with our c++ file.
author rlm
date Wed, 28 Apr 2010 08:19:09 -0400
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/scripts/run.bmark	Wed Apr 28 08:19:09 2010 -0400
     1.3 @@ -0,0 +1,528 @@
     1.4 +#!/usr/bin/env perl
     1.5 +# -*- perl -*-
     1.6 +
     1.7 +use strict;
     1.8 +use warnings;
     1.9 +use Getopt::Long qw(:config no_auto_abbrev no_ignore_case pass_through);
    1.10 +use IO::Pty;
    1.11 +
    1.12 +#
    1.13 +# Turn on warnings
    1.14 +#
    1.15 +$^W = 1;
    1.16 +
    1.17 +##
    1.18 +## Benchmark run script
    1.19 +##
    1.20 +
    1.21 +sub ExecModel($);
    1.22 +sub Exec($$);
    1.23 +sub CompareOutput();
    1.24 +sub ReadConfig($$);
    1.25 +
    1.26 +
    1.27 +#############################################################################
    1.28 +#############################################################################
    1.29 +##
    1.30 +## Start by figuring out the model location and type.
    1.31 +##
    1.32 +#############################################################################
    1.33 +#############################################################################
    1.34 +
    1.35 +my %config;
    1.36 +
    1.37 +ReadConfig("config/env.sh", 1);
    1.38 +ReadConfig("$config{modelDir}/config/env.sh", 1);
    1.39 +ReadConfig("$config{modelDir}/config/signature.sh", 0);
    1.40 +
    1.41 +##
    1.42 +## Pseudo-enumeration of possible model types
    1.43 +##
    1.44 +my $MODEL_NONE = 0;
    1.45 +my $MODEL_FPGA = 1;                     # Model runs on FPGA hardware
    1.46 +my $MODEL_BLUESIM = 2;                  # Bluesim
    1.47 +my $MODEL_VSIM = 3;                     # Verilog simulator
    1.48 +
    1.49 +my $mType = $MODEL_NONE;
    1.50 +
    1.51 +
    1.52 +#############################################################################
    1.53 +#############################################################################
    1.54 +##
    1.55 +## Process command line arguments
    1.56 +##
    1.57 +#############################################################################
    1.58 +#############################################################################
    1.59 +
    1.60 +my $help = 0;
    1.61 +my $onlyCompare = 0;
    1.62 +my $noCompare = 0;
    1.63 +my $forceLoad = 0;
    1.64 +my $gdb = 0;
    1.65 +my $noProgram = 0;
    1.66 +my $noReserve = 0;
    1.67 +my $funcpPrefix = "";
    1.68 +my $funcpSuffix = "";
    1.69 +my $noshowfp = 0;
    1.70 +my $printCycle = undef;
    1.71 +my $showfp = undef;
    1.72 +my $bluesimCmd = undef;
    1.73 +my $vcdStart = undef;
    1.74 +my $vcdCycles = 20000;
    1.75 +my $m5run = 0;
    1.76 +
    1.77 +my $status = GetOptions("help!" => \$help,
    1.78 +                        "gdb!" => \$gdb,
    1.79 +                        "noprogram!" => \$noProgram,
    1.80 +                        "noreserve!" => \$noReserve,
    1.81 +                        "force-load!" => \$forceLoad,
    1.82 +                        "funcp-prefix=s" => \$funcpPrefix,
    1.83 +                        "funcp-suffix=s" => \$funcpSuffix,
    1.84 +                        "noshowfp!" => \$noshowfp,
    1.85 +                        "onlycompare!" => \$onlyCompare,
    1.86 +                        "nocompare!" => \$noCompare,
    1.87 +                        "pc=s" => \$printCycle,
    1.88 +                        "showfp:s" => \$showfp,
    1.89 +                        "bluesim=s" => \$bluesimCmd,
    1.90 +                        "vcdstart=i" => \$vcdStart,
    1.91 +                        "vcdcycles=i" => \$vcdCycles,
    1.92 +                        "m5!" => \$m5run,
    1.93 +                       );
    1.94 +
    1.95 +# Put quotation marks back on arguments that have spaces since they will be
    1.96 +# passed through a shell once more.
    1.97 +foreach my $i ( 0 .. $#ARGV ) {
    1.98 +    if (($ARGV[$i] =~ /\s/) && ! ($ARGV[$i] =~ /['"]$/)) {
    1.99 +        $ARGV[$i] = '"' . $ARGV[$i] . '"';
   1.100 +    }
   1.101 +}
   1.102 +
   1.103 +if ($onlyCompare != 0) {
   1.104 +    exit(CompareOutput());
   1.105 +}
   1.106 +
   1.107 +if ($m5run != 0) {
   1.108 +    $mType = $MODEL_NONE;
   1.109 +}
   1.110 +elsif (-f "$config{modelDir}/$config{model}_hw.errinfo") {
   1.111 +    $mType = $MODEL_FPGA;
   1.112 +}
   1.113 +elsif (-f "$config{modelDir}/$config{model}_hw.exe") {
   1.114 +    $mType = $MODEL_BLUESIM;
   1.115 +}
   1.116 +elsif (-f "$config{modelDir}/$config{model}_hw.vexe") {
   1.117 +    $mType = $MODEL_VSIM;
   1.118 +}
   1.119 +else {
   1.120 +    die("Can't determine model type");
   1.121 +}
   1.122 +
   1.123 +if ($help || ! $status) {
   1.124 +    print STDERR "\nArguments:\n";
   1.125 +    print STDERR "   [--gdb]                 Invokes the software side in gdb\n";
   1.126 +    print STDERR "   [--noprogram]           Skips the FPGA load and reservation steps\n";
   1.127 +    print STDERR "   [--noreserve]           Skips the FPGA reservation steps\n";
   1.128 +    print STDERR "   [--funcp-prefix=\"<prefix>\"]\n";
   1.129 +    print STDERR "                           Prepend prefix to HAsim's --funcp argument\n";
   1.130 +    print STDERR "   [--funcp-suffix=\"<suffix>\"]\n";
   1.131 +    print STDERR "                           Append suffix to HAsim's --funcp argument\n";
   1.132 +    print STDERR "   [--onlycompare]         Only compare output files (without running)\n";
   1.133 +    print STDERR "   [--nocompare]           Skip comparison of output files\n";
   1.134 +    print STDERR "   [--m5]                  Run workload in m5 without HAsim\n";
   1.135 +
   1.136 +    if ($mType == $MODEL_FPGA) {
   1.137 +        print STDERR "   [--force-load]          Load a bitfile to the FPGA even if it has errors\n";
   1.138 +    }
   1.139 +
   1.140 +    if ($mType == $MODEL_BLUESIM) {
   1.141 +        print STDERR "   [--vcdstart=<cycle>]    Generate VCD dump for wave viewer (e.g. gtkwave)\n";
   1.142 +        print STDERR "   [--vcdcycles=<cycles>]  VCD dump length (default = 20000)\n";
   1.143 +    }
   1.144 +
   1.145 +    if ($config{isHybridModel}) {
   1.146 +        my $cmd = "$config{modelDir}/$config{model} --help-run-append";
   1.147 +        system($cmd);
   1.148 +    }
   1.149 +
   1.150 +    exit(1);
   1.151 +}
   1.152 +
   1.153 +#############################################################################
   1.154 +#############################################################################
   1.155 +##
   1.156 +## Adjust model arguments
   1.157 +##
   1.158 +#############################################################################
   1.159 +#############################################################################
   1.160 +
   1.161 +# Show front panel?
   1.162 +if ($noshowfp) {
   1.163 +    $showfp = 'none';
   1.164 +}
   1.165 +elsif (defined($showfp)) {
   1.166 +    # Specified on the run command line
   1.167 +    $showfp = 'gui' if ($showfp eq '');
   1.168 +}
   1.169 +elsif ($config{feeder} eq 'none') {
   1.170 +    # For null feeder default to showing LEDs on stdout
   1.171 +    $showfp = 'stdout';
   1.172 +}
   1.173 +else {
   1.174 +    # Other models have heartbeats
   1.175 +    $showfp = 'none';
   1.176 +}
   1.177 +
   1.178 +my $feedFlags = "${funcpPrefix} $config{feedFlags} ${funcpSuffix}";
   1.179 +
   1.180 +if ($config{feeder} eq 'm5') {
   1.181 +    # Tell m5 to be quiet and not to enable the remote gdb port.  Under netbatch
   1.182 +    # it appears there are sometimes attempts to connect to the port, which
   1.183 +    # stops simulation.
   1.184 +    $feedFlags = "--quiet --remote-gdb-port=0 ${feedFlags}";
   1.185 +}
   1.186 +
   1.187 +my $cmd;
   1.188 +
   1.189 +if ($m5run == 0) {
   1.190 +    # Normal run
   1.191 +    $cmd = "$config{modelDir}/$config{model} --modeldir=$config{modelDir} --workload=$config{workload} --showfp=${showfp} --funcp=\"${feedFlags}\" $config{genFlags}";
   1.192 +    foreach my $c (@ARGV) {
   1.193 +        $cmd .= " $c";
   1.194 +    }
   1.195 +
   1.196 +    if (defined($printCycle)) {
   1.197 +        $cmd .= " --pc=${printCycle}";
   1.198 +    }
   1.199 +}
   1.200 +else {
   1.201 +    if ($config{feeder} ne 'm5') {
   1.202 +        die("This workload does not use m5");
   1.203 +    }
   1.204 +
   1.205 +    # Running inside m5 without HAsim
   1.206 +    my $m5cmd;
   1.207 +    if (exists($ENV{M5BIN})) {
   1.208 +        $m5cmd = $ENV{M5BIN};
   1.209 +    }
   1.210 +    else {
   1.211 +        my $m5bin = "platform/m5/build/ALPHA_SE/m5." . ($gdb ? "debug" : "opt");
   1.212 +        $m5cmd = `awb-resolver ${m5bin}`;
   1.213 +        chomp($m5cmd);
   1.214 +        die("Failed to find $m5bin") if ($m5cmd eq '');
   1.215 +    }
   1.216 +
   1.217 +    $cmd = "${m5cmd} ${feedFlags}";
   1.218 +
   1.219 +    # Drop --hasim-sim
   1.220 +    $cmd =~ s/--hasim-sim //;
   1.221 +    # Drop escaping of quotes
   1.222 +    $cmd =~ s/\\"/"/g;
   1.223 +
   1.224 +    $noProgram = 1;
   1.225 +}
   1.226 +
   1.227 +#
   1.228 +# Bluesim arguments
   1.229 +#
   1.230 +
   1.231 +# Generate dump.vcd for wave viewer (e.g. gtkwave)?
   1.232 +if (defined($vcdStart)) {
   1.233 +    my $vcdCmd = "sim vcd on; sim step $vcdCycles; sim stop";
   1.234 +    if ($vcdStart > 0) {
   1.235 +        $vcdCmd = "sim step ${vcdStart}; ${vcdCmd}";
   1.236 +    }
   1.237 +
   1.238 +    if (defined($bluesimCmd)) {
   1.239 +        $bluesimCmd .= " ";
   1.240 +    }
   1.241 +    else {
   1.242 +        $bluesimCmd = "";
   1.243 +    }
   1.244 +    $bluesimCmd .= "-c \"$vcdCmd\"";
   1.245 +}
   1.246 +
   1.247 +if (defined($bluesimCmd)) {
   1.248 +    $cmd .= " --bluesim=\'$bluesimCmd\'";
   1.249 +}
   1.250 +
   1.251 +# Adjust the arguments for Bluesim if it is being invoked directly
   1.252 +if (! $config{isHybridModel} && ($mType == $MODEL_BLUESIM)) {
   1.253 +    $cmd =~ s/\s--/ +--/g;
   1.254 +
   1.255 +    # Bluesim may expect to load a program from a well known file
   1.256 +    unlink('program.vmh');
   1.257 +    link("program/$config{workload}.$config{ISA}.vmh", 'program.vmh');
   1.258 +}
   1.259 +
   1.260 +
   1.261 +#############################################################################
   1.262 +#############################################################################
   1.263 +##
   1.264 +## Load the FPGA and run the model
   1.265 +##
   1.266 +#############################################################################
   1.267 +#############################################################################
   1.268 +
   1.269 +#
   1.270 +# Move old stats file so we are sure statistics come from this run
   1.271 +#
   1.272 +if (-f "$config{workload}.stats") {
   1.273 +    rename("$config{workload}.stats", "$config{workload}.stats.old");
   1.274 +}
   1.275 +
   1.276 +if ($mType == $MODEL_FPGA) {
   1.277 +    if (! defined($printCycle)) {
   1.278 +        # User didn't specify a cycle printing interval.  Pick one more reasonable
   1.279 +        # for HW.
   1.280 +        #$cmd .= " --pc=10000000";
   1.281 +    }
   1.282 +
   1.283 +    # Load FPGA
   1.284 +    $ENV{FPGA_BIT_FILE} = "$config{modelDir}/.xilinx/$config{model}_par.bit";
   1.285 +
   1.286 +    if (! $noProgram) {
   1.287 +        if (! $forceLoad && -s "$config{modelDir}/$config{model}_hw.errinfo") {
   1.288 +            print STDERR "FPGA bit file has errors:\n\n";
   1.289 +            system("cat $config{modelDir}/$config{model}_hw.errinfo > /dev/stderr");
   1.290 +            print STDERR "\nUse --force-load to ignore the error.\n";
   1.291 +            exit(1);
   1.292 +        }
   1.293 +
   1.294 +        if (! $noReserve) {
   1.295 +            Exec("hasim-fpga-ctrl --reserve", "Failed to reserve FPGA");
   1.296 +        }
   1.297 +
   1.298 +        # Does a download script exist to program the FPGA?
   1.299 +        my $needProgram = (-f "$config{modelDir}/config/$config{model}.download");
   1.300 +        $needProgram = 1;
   1.301 +
   1.302 +        # Is the FPGA already programmed with the correct bit file?
   1.303 +        if (exists($config{signature})) {
   1.304 +            my $curSignature = `hasim-fpga-ctrl --getsignature`;
   1.305 +            chomp($curSignature);
   1.306 +            if ($curSignature eq $config{signature}) {
   1.307 +                print "FPGA is already programmed (signature match)...\n";
   1.308 +                #$needProgram = 0;
   1.309 +            }
   1.310 +        }
   1.311 +
   1.312 +        if ($needProgram) {
   1.313 +            Exec("hasim-fpga-ctrl --program", "Failed to enter FPGA programming mode");
   1.314 +
   1.315 +            my $dir = `pwd`;
   1.316 +            chomp($dir);
   1.317 +            Exec("(cd $config{modelDir}; ./config/$config{model}.download ${dir}/FPGA_programming.log)", "Failed to program FPGA");
   1.318 +
   1.319 +            if (exists($config{signature})) {
   1.320 +                Exec("hasim-fpga-ctrl --setsignature=$config{signature}", "Failed to set FPGA bit image signature");
   1.321 +            }
   1.322 +        }
   1.323 +
   1.324 +        Exec("hasim-fpga-ctrl --activate", "Failed to activate FPGA or driver");
   1.325 +    }
   1.326 +}
   1.327 +
   1.328 +# Run the software side or a hardware simulator
   1.329 +my $run_status = 0;
   1.330 +if ($config{isHybridModel} || ($mType != $MODEL_FPGA)) {
   1.331 +    $cmd = $cmd." 2> proc.trace\n";
   1.332 +    $run_status = ExecModel($cmd);
   1.333 +}
   1.334 +
   1.335 +# Create a stats file for null workloads to make regression.launcher happy (HACK)
   1.336 +if ( $config{workload} eq "null" ) {
   1.337 +  system("touch null.stats");
   1.338 +}
   1.339 +
   1.340 +if (-f "hasim_events.out") {
   1.341 +    system("sort hasim_events.out -o hasim_events.out.$$; mv -f hasim_events.out.$$ hasim_events.out");
   1.342 +}
   1.343 +if (-f "$config{workload}.stats") {
   1.344 +    system("sort $config{workload}.stats -o $config{workload}.stats.$$; mv -f $config{workload}.stats.$$ $config{workload}.stats");
   1.345 +}
   1.346 +
   1.347 +if (($mType == $MODEL_FPGA) && ! $noProgram && ! $noReserve) {
   1.348 +    Exec("hasim-fpga-ctrl --drop-reservation", "Failed to drop FPGA reservation");
   1.349 +}
   1.350 +
   1.351 +if ($run_status != 0) {
   1.352 +    exit($run_status);
   1.353 +}
   1.354 +else {
   1.355 +    exit(CompareOutput());
   1.356 +}
   1.357 +
   1.358 +
   1.359 +sub ErrorExit($) {
   1.360 +    my $msg = shift;
   1.361 +
   1.362 +    print STDERR "${msg}\n";
   1.363 +
   1.364 +    if (($mType == $MODEL_FPGA) && ! $noProgram && ! $noReserve) {
   1.365 +        system("hasim-fpga-ctrl --drop-reservation");
   1.366 +    }
   1.367 +
   1.368 +    exit(1);
   1.369 +}
   1.370 +
   1.371 +
   1.372 +##
   1.373 +## ExecModel --
   1.374 +##   This is the routine that actually invokes the model.  stdout and stderr
   1.375 +##   are logged in a file.  The return value is the exit status of the model.
   1.376 +##
   1.377 +sub ExecModel($) {
   1.378 +    my $cmd = shift;
   1.379 +
   1.380 +    if ($gdb) {
   1.381 +        ## gdb needs stdin.  Just use system() and don't do logging.
   1.382 +        system("gdb -args " . $cmd);
   1.383 +        return 0;
   1.384 +    }
   1.385 +
   1.386 +    ##
   1.387 +    ## Invoke the model, but log its output both to stdout and to a file.
   1.388 +    ## Use a pty so the invoked program will use line buffering instead
   1.389 +    ## of fully buffered writes.  (Libc sets up stdout line buffered when
   1.390 +    ## it thinks it is writing to a terminal.  It uses fully buffered
   1.391 +    ## writing to a pipe.)
   1.392 +    ##
   1.393 +
   1.394 +    my $pty = new IO::Pty;
   1.395 +    my $slave = $pty->slave();
   1.396 +
   1.397 +    my $pid = fork();
   1.398 +    die "Couldn't fork: $!" unless defined $pid;
   1.399 +
   1.400 +    if (! $pid) {
   1.401 +        # Child process is the monitoring process
   1.402 +        $pty->make_slave_controlling_terminal();
   1.403 +
   1.404 +        my $output = "$config{workload}.$config{ISA}.out";  
   1.405 +        if(exists($config{silent})) {
   1.406 +	    $output = "/dev/null";
   1.407 +	}
   1.408 +
   1.409 +        if (! open(LOG, ">$output")) {
   1.410 +            print STDERR "Error opening log file $output\n";
   1.411 +        }
   1.412 +
   1.413 +        # Unbuffered I/O loop
   1.414 +        while (1) {
   1.415 +            my $buf;
   1.416 +            my $n = sysread($slave, $buf, 4096);
   1.417 +
   1.418 +            last if ($n == 0);
   1.419 +
   1.420 +            syswrite(STDOUT, $buf);
   1.421 +            syswrite(LOG, $buf);
   1.422 +        }
   1.423 +
   1.424 +        close(LOG);
   1.425 +        exit(0);
   1.426 +    }
   1.427 +
   1.428 +    # Bind new PTY to STDOUT (but save old STDOUT)
   1.429 +    $pty->close_slave();
   1.430 +    open(my $oldOut, ">&", STDOUT) or die $!;
   1.431 +    open(STDOUT, ">&", $pty) or die $!;
   1.432 +
   1.433 +    # Run model
   1.434 +    my $result = system("${cmd} 2>&1");
   1.435 +
   1.436 +    # Send ^d to end child logging thread
   1.437 +    print "\cD";
   1.438 +
   1.439 +    # Return to normal STDOUT
   1.440 +    close(STDOUT);
   1.441 +    open(STDOUT, ">&", $oldOut) or die $!;
   1.442 +    close($oldOut);
   1.443 +
   1.444 +    # Compute exit status of model
   1.445 +    my $status = 0;
   1.446 +    if ($result == -1) {
   1.447 +        print STDERR "Model execution failed\n";
   1.448 +        $status = 1;
   1.449 +    }
   1.450 +    elsif ($result & 127) {
   1.451 +        print STDERR "Child died with signal " . ($result & 127) . ", " . (($result & 128) ? 'with' : 'without') . " coredump\n";
   1.452 +        $status = 1;
   1.453 +    }
   1.454 +    elsif (($result >> 8) != 0) {
   1.455 +        $status = $result >> 8;
   1.456 +        print "Model exited with status $status\n";
   1.457 +    }
   1.458 +
   1.459 +    return $status;
   1.460 +}
   1.461 +
   1.462 +
   1.463 +sub Exec($$) {
   1.464 +    my $cmd = shift;
   1.465 +    my $errmsg = shift;
   1.466 +
   1.467 +    system($cmd);
   1.468 +    if ($? == -1) {
   1.469 +        ErrorExit("Failed to execute $cmd: $!");
   1.470 +    }
   1.471 +    elsif ($? & 127) {
   1.472 +        ErrorExit("Child died with signal " . ($? & 127) . ", " . (($? & 128) ? 'with' : 'without') . " coredump");
   1.473 +    }
   1.474 +    elsif (($? >> 8) != 0) {
   1.475 +        ErrorExit("${errmsg}");
   1.476 +    }
   1.477 +}
   1.478 +
   1.479 +
   1.480 +sub CompareOutput() {
   1.481 +    return 0 if ($noCompare != 0);
   1.482 +    return 0 if (! exists($config{compare}) || ($config{compare} eq ''));
   1.483 +
   1.484 +    # run the checker 
   1.485 +    `cd ./checker/ && make clean && make`;
   1.486 +    `./checker/checker input.wav out_gold.wav`;
   1.487 +    print "about to call compare_wavs\n";
   1.488 +    my $out=`./checker/compare_wavs/compare_wavs 10 out_gold.wav out_hw.wav`;
   1.489 +   
   1.490 +    if ($out !~ /fail/) {
   1.491 +        print "*** Output comparison passed ***\n";
   1.492 +        system("touch $config{workload}.stats");
   1.493 +        return 0;
   1.494 +    }
   1.495 +    else {
   1.496 +        print "*** Output comparison failed ***\n";
   1.497 +        return 1;
   1.498 +    }
   1.499 +}
   1.500 +
   1.501 +
   1.502 +#
   1.503 +# Read the configuration file
   1.504 +#
   1.505 +sub ReadConfig($$) {
   1.506 +    my $conf = shift;
   1.507 +    my $required = shift;
   1.508 +
   1.509 +    my $status = open(CONFIG, "< $conf");
   1.510 +    if (! $status) {
   1.511 +        return if (! $required);
   1.512 +        die("Failed to open $conf");
   1.513 +    }
   1.514 +
   1.515 +    while (<CONFIG>) {
   1.516 +        chomp;
   1.517 +        my $t = $_;
   1.518 +        $t =~ s/#.*//;
   1.519 +        if ($t =~ /^\s*([^\s]+)\s*=\s*"(.*)"\s*$/) {
   1.520 +            my $c = $1;
   1.521 +            my $v = $2;
   1.522 +            $v =~ s/^["'](.*)["']$/$1/;         # Drop quotation marks
   1.523 +            $config{$c} = $v;
   1.524 +        }
   1.525 +        elsif ($t =~ /^\s*([^\s]+)\s*=\s*([^\s]+)\s*$/) {
   1.526 +            my $c = $1;
   1.527 +            my $v = $2;
   1.528 +            $config{$c} = $v;
   1.529 +        }
   1.530 +    }
   1.531 +}