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