Mercurial > pygar
view pygar-benchmarks/setup/run-sim.bmark @ 75:a15cc186e07d pygar svn.76
[svn r76] should be fully parameterized for however many cores we want (not fully tested)
author | punk |
---|---|
date | Wed, 12 May 2010 03:14:53 -0400 |
parents | 0ede0715dbd6 |
children |
line wrap: on
line source
1 #!/usr/bin/env perl2 # -*- perl -*-4 use strict;5 use warnings;6 use Getopt::Long qw(:config no_auto_abbrev no_ignore_case pass_through);7 use IO::Pty;9 #10 # Turn on warnings11 #12 $^W = 1;14 ##15 ## Benchmark run script16 ##18 sub ExecModel($);19 sub Exec($$);20 sub CompareOutput();21 sub ReadConfig($$);24 #############################################################################25 #############################################################################26 ##27 ## Start by figuring out the model location and type.28 ##29 #############################################################################30 #############################################################################32 my %config;34 ReadConfig("config/env.sh", 1);35 ReadConfig("$config{modelDir}/config/env.sh", 1);36 ReadConfig("$config{modelDir}/config/signature.sh", 0);38 ##39 ## Pseudo-enumeration of possible model types40 ##41 my $MODEL_NONE = 0;42 my $MODEL_FPGA = 1; # Model runs on FPGA hardware43 my $MODEL_BLUESIM = 2; # Bluesim44 my $MODEL_VSIM = 3; # Verilog simulator46 my $mType = $MODEL_NONE;49 #############################################################################50 #############################################################################51 ##52 ## Process command line arguments53 ##54 #############################################################################55 #############################################################################57 my $help = 0;58 my $onlyCompare = 0;59 my $noCompare = 0;60 my $forceLoad = 0;61 my $gdb = 0;62 my $noProgram = 0;63 my $noReserve = 0;64 my $funcpPrefix = "";65 my $funcpSuffix = "";66 my $noshowfp = 0;67 my $printCycle = undef;68 my $showfp = undef;69 my $bluesimCmd = undef;70 my $vcdStart = undef;71 my $vcdCycles = 20000;72 my $m5run = 0;74 my $status = GetOptions("help!" => \$help,75 "gdb!" => \$gdb,76 "noprogram!" => \$noProgram,77 "noreserve!" => \$noReserve,78 "force-load!" => \$forceLoad,79 "funcp-prefix=s" => \$funcpPrefix,80 "funcp-suffix=s" => \$funcpSuffix,81 "noshowfp!" => \$noshowfp,82 "onlycompare!" => \$onlyCompare,83 "nocompare!" => \$noCompare,84 "pc=s" => \$printCycle,85 "showfp:s" => \$showfp,86 "bluesim=s" => \$bluesimCmd,87 "vcdstart=i" => \$vcdStart,88 "vcdcycles=i" => \$vcdCycles,89 "m5!" => \$m5run,90 );92 # Put quotation marks back on arguments that have spaces since they will be93 # passed through a shell once more.94 foreach my $i ( 0 .. $#ARGV ) {95 if (($ARGV[$i] =~ /\s/) && ! ($ARGV[$i] =~ /['"]$/)) {96 $ARGV[$i] = '"' . $ARGV[$i] . '"';97 }98 }100 if ($onlyCompare != 0) {101 exit(CompareOutput());102 }104 if ($m5run != 0) {105 $mType = $MODEL_NONE;106 }107 elsif (-f "$config{modelDir}/$config{model}_hw.errinfo") {108 $mType = $MODEL_FPGA;109 }110 elsif (-f "$config{modelDir}/$config{model}_hw.exe") {111 $mType = $MODEL_BLUESIM;112 }113 elsif (-f "$config{modelDir}/$config{model}_hw.vexe") {114 $mType = $MODEL_VSIM;115 }116 else {117 die("Can't determine model type");118 }120 if ($help || ! $status) {121 print STDERR "\nArguments:\n";122 print STDERR " [--gdb] Invokes the software side in gdb\n";123 print STDERR " [--noprogram] Skips the FPGA load and reservation steps\n";124 print STDERR " [--noreserve] Skips the FPGA reservation steps\n";125 print STDERR " [--funcp-prefix=\"<prefix>\"]\n";126 print STDERR " Prepend prefix to HAsim's --funcp argument\n";127 print STDERR " [--funcp-suffix=\"<suffix>\"]\n";128 print STDERR " Append suffix to HAsim's --funcp argument\n";129 print STDERR " [--onlycompare] Only compare output files (without running)\n";130 print STDERR " [--nocompare] Skip comparison of output files\n";131 print STDERR " [--m5] Run workload in m5 without HAsim\n";133 if ($mType == $MODEL_FPGA) {134 print STDERR " [--force-load] Load a bitfile to the FPGA even if it has errors\n";135 }137 if ($mType == $MODEL_BLUESIM) {138 print STDERR " [--vcdstart=<cycle>] Generate VCD dump for wave viewer (e.g. gtkwave)\n";139 print STDERR " [--vcdcycles=<cycles>] VCD dump length (default = 20000)\n";140 }142 if ($config{isHybridModel}) {143 my $cmd = "$config{modelDir}/$config{model} --help-run-append";144 system($cmd);145 }147 exit(1);148 }150 #############################################################################151 #############################################################################152 ##153 ## Adjust model arguments154 ##155 #############################################################################156 #############################################################################158 # Show front panel?159 if ($noshowfp) {160 $showfp = 'none';161 }162 elsif (defined($showfp)) {163 # Specified on the run command line164 $showfp = 'gui' if ($showfp eq '');165 }166 elsif ($config{feeder} eq 'none') {167 # For null feeder default to showing LEDs on stdout168 $showfp = 'stdout';169 }170 else {171 # Other models have heartbeats172 $showfp = 'none';173 }175 my $feedFlags = "${funcpPrefix} $config{feedFlags} ${funcpSuffix}";177 if ($config{feeder} eq 'm5') {178 # Tell m5 to be quiet and not to enable the remote gdb port. Under netbatch179 # it appears there are sometimes attempts to connect to the port, which180 # stops simulation.181 $feedFlags = "--quiet --remote-gdb-port=0 ${feedFlags}";182 }184 my $cmd;186 if ($m5run == 0) {187 # Normal run188 $cmd = "$config{modelDir}/$config{model} --modeldir=$config{modelDir} --workload=$config{workload} --showfp=${showfp} --funcp=\"${feedFlags}\" $config{genFlags}";189 foreach my $c (@ARGV) {190 $cmd .= " $c";191 }193 if (defined($printCycle)) {194 $cmd .= " --pc=${printCycle}";195 }196 }197 else {198 if ($config{feeder} ne 'm5') {199 die("This workload does not use m5");200 }202 # Running inside m5 without HAsim203 my $m5cmd;204 if (exists($ENV{M5BIN})) {205 $m5cmd = $ENV{M5BIN};206 }207 else {208 my $m5bin = "platform/m5/build/ALPHA_SE/m5." . ($gdb ? "debug" : "opt");209 $m5cmd = `awb-resolver ${m5bin}`;210 chomp($m5cmd);211 die("Failed to find $m5bin") if ($m5cmd eq '');212 }214 $cmd = "${m5cmd} ${feedFlags}";216 # Drop --hasim-sim217 $cmd =~ s/--hasim-sim //;218 # Drop escaping of quotes219 $cmd =~ s/\\"/"/g;221 $noProgram = 1;222 }224 #225 # Bluesim arguments226 #228 # Generate dump.vcd for wave viewer (e.g. gtkwave)?229 if (defined($vcdStart)) {230 my $vcdCmd = "sim vcd on; sim step $vcdCycles; sim stop";231 if ($vcdStart > 0) {232 $vcdCmd = "sim step ${vcdStart}; ${vcdCmd}";233 }235 if (defined($bluesimCmd)) {236 $bluesimCmd .= " ";237 }238 else {239 $bluesimCmd = "";240 }241 $bluesimCmd .= "-c \"$vcdCmd\"";242 }244 if (defined($bluesimCmd)) {245 $cmd .= " --bluesim=\'$bluesimCmd\'";246 }248 # Adjust the arguments for Bluesim if it is being invoked directly249 if (! $config{isHybridModel} && ($mType == $MODEL_BLUESIM)) {250 $cmd =~ s/\s--/ +--/g;252 # Bluesim may expect to load a program from a well known file253 unlink('program.vmh');254 link("program/$config{workload}.$config{ISA}.vmh", 'program.vmh');255 }258 #############################################################################259 #############################################################################260 ##261 ## Load the FPGA and run the model262 ##263 #############################################################################264 #############################################################################266 #267 # Move old stats file so we are sure statistics come from this run268 #269 if (-f "$config{workload}.stats") {270 rename("$config{workload}.stats", "$config{workload}.stats.old");271 }273 if ($mType == $MODEL_FPGA) {274 if (! defined($printCycle)) {275 # User didn't specify a cycle printing interval. Pick one more reasonable276 # for HW.277 #$cmd .= " --pc=10000000";278 }280 # Load FPGA281 $ENV{FPGA_BIT_FILE} = "$config{modelDir}/.xilinx/$config{model}_par.bit";283 if (! $noProgram) {284 if (! $forceLoad && -s "$config{modelDir}/$config{model}_hw.errinfo") {285 print STDERR "FPGA bit file has errors:\n\n";286 system("cat $config{modelDir}/$config{model}_hw.errinfo > /dev/stderr");287 print STDERR "\nUse --force-load to ignore the error.\n";288 exit(1);289 }291 if (! $noReserve) {292 Exec("hasim-fpga-ctrl --reserve", "Failed to reserve FPGA");293 }295 # Does a download script exist to program the FPGA?296 my $needProgram = (-f "$config{modelDir}/config/$config{model}.download");297 $needProgram = 1;299 # Is the FPGA already programmed with the correct bit file?300 if (exists($config{signature})) {301 my $curSignature = `hasim-fpga-ctrl --getsignature`;302 chomp($curSignature);303 if ($curSignature eq $config{signature}) {304 print "FPGA is already programmed (signature match)...\n";305 #$needProgram = 0;306 }307 }309 if ($needProgram) {310 Exec("hasim-fpga-ctrl --program", "Failed to enter FPGA programming mode");312 my $dir = `pwd`;313 chomp($dir);314 Exec("(cd $config{modelDir}; ./config/$config{model}.download ${dir}/FPGA_programming.log)", "Failed to program FPGA");316 if (exists($config{signature})) {317 Exec("hasim-fpga-ctrl --setsignature=$config{signature}", "Failed to set FPGA bit image signature");318 }319 }321 Exec("hasim-fpga-ctrl --activate", "Failed to activate FPGA or driver");322 }323 }325 # Run the software side or a hardware simulator326 my $run_status = 0;327 if ($config{isHybridModel} || ($mType != $MODEL_FPGA)) {328 $cmd = $cmd." 2> proc.trace\n";329 $run_status = ExecModel($cmd);330 }332 # Create a stats file for null workloads to make regression.launcher happy (HACK)333 if ( $config{workload} eq "null" ) {334 system("touch null.stats");335 }337 if (-f "hasim_events.out") {338 system("sort hasim_events.out -o hasim_events.out.$$; mv -f hasim_events.out.$$ hasim_events.out");339 }340 if (-f "$config{workload}.stats") {341 system("sort $config{workload}.stats -o $config{workload}.stats.$$; mv -f $config{workload}.stats.$$ $config{workload}.stats");342 }344 if (($mType == $MODEL_FPGA) && ! $noProgram && ! $noReserve) {345 Exec("hasim-fpga-ctrl --drop-reservation", "Failed to drop FPGA reservation");346 }348 if ($run_status != 0) {349 exit($run_status);350 }351 else {352 exit(CompareOutput());353 }356 sub ErrorExit($) {357 my $msg = shift;359 print STDERR "${msg}\n";361 if (($mType == $MODEL_FPGA) && ! $noProgram && ! $noReserve) {362 system("hasim-fpga-ctrl --drop-reservation");363 }365 exit(1);366 }369 ##370 ## ExecModel --371 ## This is the routine that actually invokes the model. stdout and stderr372 ## are logged in a file. The return value is the exit status of the model.373 ##374 sub ExecModel($) {375 my $cmd = shift;377 if ($gdb) {378 ## gdb needs stdin. Just use system() and don't do logging.379 system("gdb -args " . $cmd);380 return 0;381 }383 ##384 ## Invoke the model, but log its output both to stdout and to a file.385 ## Use a pty so the invoked program will use line buffering instead386 ## of fully buffered writes. (Libc sets up stdout line buffered when387 ## it thinks it is writing to a terminal. It uses fully buffered388 ## writing to a pipe.)389 ##391 my $pty = new IO::Pty;392 my $slave = $pty->slave();394 my $pid = fork();395 die "Couldn't fork: $!" unless defined $pid;397 if (! $pid) {398 # Child process is the monitoring process399 $pty->make_slave_controlling_terminal();401 my $output = "$config{workload}.$config{ISA}.out";402 if(exists($config{silent})) {403 $output = "/dev/null";404 }406 if (! open(LOG, ">$output")) {407 print STDERR "Error opening log file $output\n";408 }410 # Unbuffered I/O loop411 while (1) {412 my $buf;413 my $n = sysread($slave, $buf, 4096);415 last if ($n == 0);417 syswrite(STDOUT, $buf);418 syswrite(LOG, $buf);419 }421 close(LOG);422 exit(0);423 }425 # Bind new PTY to STDOUT (but save old STDOUT)426 $pty->close_slave();427 open(my $oldOut, ">&", STDOUT) or die $!;428 open(STDOUT, ">&", $pty) or die $!;430 # Run model431 my $result = system("${cmd} 2>&1");433 # Send ^d to end child logging thread434 print "\cD";436 # Return to normal STDOUT437 close(STDOUT);438 open(STDOUT, ">&", $oldOut) or die $!;439 close($oldOut);441 # Compute exit status of model442 my $status = 0;443 if ($result == -1) {444 print STDERR "Model execution failed\n";445 $status = 1;446 }447 elsif ($result & 127) {448 print STDERR "Child died with signal " . ($result & 127) . ", " . (($result & 128) ? 'with' : 'without') . " coredump\n";449 $status = 1;450 }451 elsif (($result >> 8) != 0) {452 $status = $result >> 8;453 print "Model exited with status $status\n";454 }456 return $status;457 }460 sub Exec($$) {461 my $cmd = shift;462 my $errmsg = shift;464 system($cmd);465 if ($? == -1) {466 ErrorExit("Failed to execute $cmd: $!");467 }468 elsif ($? & 127) {469 ErrorExit("Child died with signal " . ($? & 127) . ", " . (($? & 128) ? 'with' : 'without') . " coredump");470 }471 elsif (($? >> 8) != 0) {472 ErrorExit("${errmsg}");473 }474 }477 sub CompareOutput() {478 return 0 if ($noCompare != 0);479 return 0 if (! exists($config{compare}) || ($config{compare} eq ''));481 # run the checker482 `cd ./checker/ && make clean && make`;483 `./checker/checker input.wav out_gold.wav`;484 print "about to call compare_wavs\n";485 my $out=`./checker/compare_wavs/compare_wavs 10 out_gold.wav out_hw.wav`;487 if ($out !~ /fail/) {488 print "*** Output comparison passed ***\n";489 system("touch $config{workload}.stats");490 return 0;491 }492 else {493 print "*** Output comparison failed ***\n";494 return 1;495 }496 }499 #500 # Read the configuration file501 #502 sub ReadConfig($$) {503 my $conf = shift;504 my $required = shift;506 my $status = open(CONFIG, "< $conf");507 if (! $status) {508 return if (! $required);509 die("Failed to open $conf");510 }512 while (<CONFIG>) {513 chomp;514 my $t = $_;515 $t =~ s/#.*//;516 if ($t =~ /^\s*([^\s]+)\s*=\s*"(.*)"\s*$/) {517 my $c = $1;518 my $v = $2;519 $v =~ s/^["'](.*)["']$/$1/; # Drop quotation marks520 $config{$c} = $v;521 }522 elsif ($t =~ /^\s*([^\s]+)\s*=\s*([^\s]+)\s*$/) {523 my $c = $1;524 my $v = $2;525 $config{$c} = $v;526 }527 }528 }