Mercurial > pygar
comparison 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 |
comparison
equal
deleted
inserted
replaced
22:0cfbb1e2de22 | 23:90197e3375e2 |
---|---|
1 #!/usr/bin/env perl | |
2 # -*- perl -*- | |
3 | |
4 use strict; | |
5 use warnings; | |
6 use Getopt::Long qw(:config no_auto_abbrev no_ignore_case pass_through); | |
7 use IO::Pty; | |
8 | |
9 # | |
10 # Turn on warnings | |
11 # | |
12 $^W = 1; | |
13 | |
14 ## | |
15 ## Benchmark run script | |
16 ## | |
17 | |
18 sub ExecModel($); | |
19 sub Exec($$); | |
20 sub CompareOutput(); | |
21 sub ReadConfig($$); | |
22 | |
23 | |
24 ############################################################################# | |
25 ############################################################################# | |
26 ## | |
27 ## Start by figuring out the model location and type. | |
28 ## | |
29 ############################################################################# | |
30 ############################################################################# | |
31 | |
32 my %config; | |
33 | |
34 ReadConfig("config/env.sh", 1); | |
35 ReadConfig("$config{modelDir}/config/env.sh", 1); | |
36 ReadConfig("$config{modelDir}/config/signature.sh", 0); | |
37 | |
38 ## | |
39 ## Pseudo-enumeration of possible model types | |
40 ## | |
41 my $MODEL_NONE = 0; | |
42 my $MODEL_FPGA = 1; # Model runs on FPGA hardware | |
43 my $MODEL_BLUESIM = 2; # Bluesim | |
44 my $MODEL_VSIM = 3; # Verilog simulator | |
45 | |
46 my $mType = $MODEL_NONE; | |
47 | |
48 | |
49 ############################################################################# | |
50 ############################################################################# | |
51 ## | |
52 ## Process command line arguments | |
53 ## | |
54 ############################################################################# | |
55 ############################################################################# | |
56 | |
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 $printCycle = undef; | |
67 my $bluesimCmd = undef; | |
68 my $vcdStart = undef; | |
69 my $vcdCycles = 20000; | |
70 my $m5run = 0; | |
71 | |
72 my $status = GetOptions("help!" => \$help, | |
73 "gdb!" => \$gdb, | |
74 "noprogram!" => \$noProgram, | |
75 "noreserve!" => \$noReserve, | |
76 "force-load!" => \$forceLoad, | |
77 "funcp-prefix=s" => \$funcpPrefix, | |
78 "funcp-suffix=s" => \$funcpSuffix, | |
79 "onlycompare!" => \$onlyCompare, | |
80 "nocompare!" => \$noCompare, | |
81 "pc=s" => \$printCycle, | |
82 "bluesim=s" => \$bluesimCmd, | |
83 "vcdstart=i" => \$vcdStart, | |
84 "vcdcycles=i" => \$vcdCycles, | |
85 "m5!" => \$m5run, | |
86 ); | |
87 | |
88 # Put quotation marks back on arguments that have spaces since they will be | |
89 # passed through a shell once more. | |
90 foreach my $i ( 0 .. $#ARGV ) { | |
91 if (($ARGV[$i] =~ /\s/) && ! ($ARGV[$i] =~ /['"]$/)) { | |
92 $ARGV[$i] = '"' . $ARGV[$i] . '"'; | |
93 } | |
94 } | |
95 | |
96 if ($onlyCompare != 0) { | |
97 exit(CompareOutput()); | |
98 } | |
99 | |
100 if ($m5run != 0) { | |
101 $mType = $MODEL_NONE; | |
102 } | |
103 elsif (-f "$config{modelDir}/$config{model}_hw.errinfo") { | |
104 $mType = $MODEL_FPGA; | |
105 } | |
106 elsif (-f "$config{modelDir}/$config{model}_hw.exe") { | |
107 $mType = $MODEL_BLUESIM; | |
108 } | |
109 elsif (-f "$config{modelDir}/$config{model}_hw.vexe") { | |
110 $mType = $MODEL_VSIM; | |
111 } | |
112 else { | |
113 die("Can't determine model type"); | |
114 } | |
115 | |
116 if ($help || ! $status) { | |
117 print STDERR "\nArguments:\n"; | |
118 print STDERR " [--gdb] Invokes the software side in gdb\n"; | |
119 print STDERR " [--noprogram] Skips the FPGA load and reservation steps\n"; | |
120 print STDERR " [--noreserve] Skips the FPGA reservation steps\n"; | |
121 print STDERR " [--funcp-prefix=\"<prefix>\"]\n"; | |
122 print STDERR " Prepend prefix to HAsim's --funcp argument\n"; | |
123 print STDERR " [--funcp-suffix=\"<suffix>\"]\n"; | |
124 print STDERR " Append suffix to HAsim's --funcp argument\n"; | |
125 print STDERR " [--onlycompare] Only compare output files (without running)\n"; | |
126 print STDERR " [--nocompare] Skip comparison of output files\n"; | |
127 print STDERR " [--m5] Run workload in m5 without HAsim\n"; | |
128 | |
129 if ($mType == $MODEL_FPGA) { | |
130 print STDERR " [--force-load] Load a bitfile to the FPGA even if it has errors\n"; | |
131 } | |
132 | |
133 if ($mType == $MODEL_BLUESIM) { | |
134 print STDERR " [--vcdstart=<cycle>] Generate VCD dump for wave viewer (e.g. gtkwave)\n"; | |
135 print STDERR " [--vcdcycles=<cycles>] VCD dump length (default = 20000)\n"; | |
136 } | |
137 | |
138 if ($config{isHybridModel}) { | |
139 my $cmd = "$config{modelDir}/$config{model} --help-run-append"; | |
140 system($cmd); | |
141 } | |
142 | |
143 exit(1); | |
144 } | |
145 | |
146 ############################################################################# | |
147 ############################################################################# | |
148 ## | |
149 ## Adjust model arguments | |
150 ## | |
151 ############################################################################# | |
152 ############################################################################# | |
153 | |
154 my $feedFlags = "${funcpPrefix} $config{feedFlags} ${funcpSuffix}"; | |
155 | |
156 if ($config{feeder} eq 'm5') { | |
157 # Tell m5 to be quiet and not to enable the remote gdb port. Under netbatch | |
158 # it appears there are sometimes attempts to connect to the port, which | |
159 # stops simulation. | |
160 $feedFlags = "--quiet --remote-gdb-port=0 ${feedFlags}"; | |
161 } | |
162 | |
163 my $cmd; | |
164 | |
165 if ($m5run == 0) { | |
166 # Normal run | |
167 $cmd = "$config{modelDir}/$config{model} --modeldir=$config{modelDir} --workload=$config{workload} --funcp=\"${feedFlags}\" $config{genFlags}"; | |
168 foreach my $c (@ARGV) { | |
169 $cmd .= " $c"; | |
170 } | |
171 | |
172 if (defined($printCycle)) { | |
173 $cmd .= " --pc=${printCycle}"; | |
174 } | |
175 } | |
176 else { | |
177 if ($config{feeder} ne 'm5') { | |
178 die("This workload does not use m5"); | |
179 } | |
180 | |
181 # Running inside m5 without HAsim | |
182 my $m5cmd; | |
183 if (exists($ENV{M5BIN})) { | |
184 $m5cmd = $ENV{M5BIN}; | |
185 } | |
186 else { | |
187 my $m5bin = "platform/m5/build/ALPHA_SE/m5." . ($gdb ? "debug" : "opt"); | |
188 $m5cmd = `awb-resolver ${m5bin}`; | |
189 chomp($m5cmd); | |
190 die("Failed to find $m5bin") if ($m5cmd eq ''); | |
191 } | |
192 | |
193 $cmd = "${m5cmd} ${feedFlags}"; | |
194 | |
195 # Drop --hasim-sim | |
196 $cmd =~ s/--hasim-sim //; | |
197 # Drop escaping of quotes | |
198 $cmd =~ s/\\"/"/g; | |
199 | |
200 $noProgram = 1; | |
201 } | |
202 | |
203 # | |
204 # Bluesim arguments | |
205 # | |
206 | |
207 # Generate dump.vcd for wave viewer (e.g. gtkwave)? | |
208 if (defined($vcdStart)) { | |
209 my $vcdCmd = "sim vcd on; sim step $vcdCycles; sim stop"; | |
210 if ($vcdStart > 0) { | |
211 $vcdCmd = "sim step ${vcdStart}; ${vcdCmd}"; | |
212 } | |
213 | |
214 if (defined($bluesimCmd)) { | |
215 $bluesimCmd .= " "; | |
216 } | |
217 else { | |
218 $bluesimCmd = ""; | |
219 } | |
220 $bluesimCmd .= "-c \"$vcdCmd\""; | |
221 } | |
222 | |
223 if (defined($bluesimCmd)) { | |
224 $cmd .= " --bluesim=\'$bluesimCmd\'"; | |
225 } | |
226 | |
227 # Adjust the arguments for Bluesim if it is being invoked directly | |
228 if (! $config{isHybridModel} && ($mType == $MODEL_BLUESIM)) { | |
229 $cmd =~ s/\s--/ +--/g; | |
230 | |
231 # Bluesim may expect to load a program from a well known file | |
232 unlink('program.vmh'); | |
233 link("program/$config{workload}.$config{ISA}.vmh", 'program.vmh'); | |
234 } | |
235 | |
236 | |
237 ############################################################################# | |
238 ############################################################################# | |
239 ## | |
240 ## Load the FPGA and run the model | |
241 ## | |
242 ############################################################################# | |
243 ############################################################################# | |
244 | |
245 # | |
246 # Move old stats file so we are sure statistics come from this run | |
247 # | |
248 if (-f "$config{workload}.stats") { | |
249 rename("$config{workload}.stats", "$config{workload}.stats.old"); | |
250 } | |
251 | |
252 if ($mType == $MODEL_FPGA) { | |
253 if (! defined($printCycle)) { | |
254 # User didn't specify a cycle printing interval. Pick one more reasonable | |
255 # for HW. | |
256 #$cmd .= " --pc=10000000"; | |
257 } | |
258 | |
259 # Load FPGA | |
260 $ENV{FPGA_BIT_FILE} = "$config{modelDir}/.xilinx/$config{model}_par.bit"; | |
261 | |
262 if (! $noProgram) { | |
263 if (! $forceLoad && -s "$config{modelDir}/$config{model}_hw.errinfo") { | |
264 print STDERR "FPGA bit file has errors:\n\n"; | |
265 system("cat $config{modelDir}/$config{model}_hw.errinfo > /dev/stderr"); | |
266 print STDERR "\nUse --force-load to ignore the error.\n"; | |
267 exit(1); | |
268 } | |
269 | |
270 if (! $noReserve) { | |
271 Exec("hasim-fpga-ctrl --reserve", "Failed to reserve FPGA"); | |
272 } | |
273 | |
274 # Does a download script exist to program the FPGA? | |
275 my $needProgram = (-f "$config{modelDir}/config/$config{model}.download"); | |
276 | |
277 $needProgram = 1; | |
278 | |
279 # Is the FPGA already programmed with the correct bit file? | |
280 if (exists($config{signature})) { | |
281 my $curSignature = `hasim-fpga-ctrl --getsignature`; | |
282 chomp($curSignature); | |
283 if ($curSignature eq $config{signature}) { | |
284 print "FPGA is already programmed (signature match)...\n"; | |
285 #$needProgram = 0; | |
286 } | |
287 } | |
288 | |
289 if ($needProgram) { | |
290 Exec("hasim-fpga-ctrl --program", "Failed to enter FPGA programming mode"); | |
291 | |
292 my $dir = `pwd`; | |
293 chomp($dir); | |
294 Exec("(cd $config{modelDir}; ./config/$config{model}.download ${dir}/FPGA_programming.log)", "Failed to program FPGA"); | |
295 | |
296 if (exists($config{signature})) { | |
297 Exec("hasim-fpga-ctrl --setsignature=$config{signature}", "Failed to set FPGA bit image signature"); | |
298 } | |
299 } | |
300 | |
301 Exec("hasim-fpga-ctrl --activate", "Failed to activate FPGA or driver"); | |
302 } | |
303 } | |
304 | |
305 # Run the software side or a hardware simulator | |
306 my $run_status = 0; | |
307 if ($config{isHybridModel} || ($mType != $MODEL_FPGA)) { | |
308 $run_status = ExecModel($cmd); | |
309 } | |
310 | |
311 # Create a stats file for null workloads to make regression.launcher happy (HACK) | |
312 if ( $config{workload} eq "null" ) { | |
313 system("touch null.stats"); | |
314 } | |
315 | |
316 if (-f "hasim_events.out") { | |
317 system("sort hasim_events.out -o hasim_events.out.$$; mv -f hasim_events.out.$$ hasim_events.out"); | |
318 } | |
319 if (-f "$config{workload}.stats") { | |
320 system("sort $config{workload}.stats -o $config{workload}.stats.$$; mv -f $config{workload}.stats.$$ $config{workload}.stats"); | |
321 } | |
322 | |
323 if (($mType == $MODEL_FPGA) && ! $noProgram && ! $noReserve) { | |
324 Exec("hasim-fpga-ctrl --drop-reservation", "Failed to drop FPGA reservation"); | |
325 } | |
326 | |
327 if ($run_status != 0) { | |
328 exit($run_status); | |
329 } | |
330 else { | |
331 exit(CompareOutput()); | |
332 } | |
333 | |
334 | |
335 sub ErrorExit($) { | |
336 my $msg = shift; | |
337 | |
338 print STDERR "${msg}\n"; | |
339 | |
340 if (($mType == $MODEL_FPGA) && ! $noProgram && ! $noReserve) { | |
341 system("hasim-fpga-ctrl --drop-reservation"); | |
342 } | |
343 | |
344 exit(1); | |
345 } | |
346 | |
347 | |
348 ## | |
349 ## ExecModel -- | |
350 ## This is the routine that actually invokes the model. stdout and stderr | |
351 ## are logged in a file. The return value is the exit status of the model. | |
352 ## | |
353 sub ExecModel($) { | |
354 my $cmd = shift; | |
355 | |
356 if ($gdb) { | |
357 ## gdb needs stdin. Just use system() and don't do logging. | |
358 system("gdb -args " . $cmd); | |
359 return 0; | |
360 } | |
361 | |
362 ## | |
363 ## Invoke the model, but log its output both to stdout and to a file. | |
364 ## Use a pty so the invoked program will use line buffering instead | |
365 ## of fully buffered writes. (Libc sets up stdout line buffered when | |
366 ## it thinks it is writing to a terminal. It uses fully buffered | |
367 ## writing to a pipe.) | |
368 ## | |
369 | |
370 my $pty = new IO::Pty; | |
371 my $slave = $pty->slave(); | |
372 | |
373 my $pid = fork(); | |
374 die "Couldn't fork: $!" unless defined $pid; | |
375 | |
376 if (! $pid) { | |
377 # Child process is the monitoring process | |
378 $pty->make_slave_controlling_terminal(); | |
379 | |
380 my $output = "$config{workload}.$config{ISA}.out"; | |
381 if(exists($config{silent})) { | |
382 $output = "/dev/null"; | |
383 } | |
384 | |
385 if (! open(LOG, ">$output")) { | |
386 print STDERR "Error opening log file $output\n"; | |
387 } | |
388 | |
389 # Unbuffered I/O loop | |
390 while (1) { | |
391 my $buf; | |
392 my $n = sysread($slave, $buf, 4096); | |
393 | |
394 last if ($n == 0); | |
395 | |
396 syswrite(STDOUT, $buf); | |
397 syswrite(LOG, $buf); | |
398 } | |
399 | |
400 close(LOG); | |
401 exit(0); | |
402 } | |
403 | |
404 # Bind new PTY to STDOUT (but save old STDOUT) | |
405 $pty->close_slave(); | |
406 open(my $oldOut, ">&", STDOUT) or die $!; | |
407 open(STDOUT, ">&", $pty) or die $!; | |
408 | |
409 # Run model | |
410 my $result = system("${cmd} 2>&1"); | |
411 | |
412 # Send ^d to end child logging thread | |
413 print "\cD"; | |
414 | |
415 # Return to normal STDOUT | |
416 close(STDOUT); | |
417 open(STDOUT, ">&", $oldOut) or die $!; | |
418 close($oldOut); | |
419 | |
420 # Compute exit status of model | |
421 my $status = 0; | |
422 if ($result == -1) { | |
423 print STDERR "Model execution failed\n"; | |
424 $status = 1; | |
425 } | |
426 elsif ($result & 127) { | |
427 print STDERR "Child died with signal " . ($result & 127) . ", " . (($result & 128) ? 'with' : 'without') . " coredump\n"; | |
428 $status = 1; | |
429 } | |
430 elsif (($result >> 8) != 0) { | |
431 $status = $result >> 8; | |
432 print "Model exited with status $status\n"; | |
433 } | |
434 | |
435 return $status; | |
436 } | |
437 | |
438 | |
439 sub Exec($$) { | |
440 my $cmd = shift; | |
441 my $errmsg = shift; | |
442 | |
443 system($cmd); | |
444 if ($? == -1) { | |
445 ErrorExit("Failed to execute $cmd: $!"); | |
446 } | |
447 elsif ($? & 127) { | |
448 ErrorExit("Child died with signal " . ($? & 127) . ", " . (($? & 128) ? 'with' : 'without') . " coredump"); | |
449 } | |
450 elsif (($? >> 8) != 0) { | |
451 ErrorExit("${errmsg}"); | |
452 } | |
453 } | |
454 | |
455 | |
456 sub CompareOutput() { | |
457 return 0 if ($noCompare != 0); | |
458 return 0 if (! exists($config{compare}) || ($config{compare} eq '')); | |
459 | |
460 } | |
461 | |
462 | |
463 # | |
464 # Read the configuration file | |
465 # | |
466 sub ReadConfig($$) { | |
467 my $conf = shift; | |
468 my $required = shift; | |
469 | |
470 my $status = open(CONFIG, "< $conf"); | |
471 if (! $status) { | |
472 return if (! $required); | |
473 die("Failed to open $conf"); | |
474 } | |
475 | |
476 while (<CONFIG>) { | |
477 chomp; | |
478 my $t = $_; | |
479 $t =~ s/#.*//; | |
480 if ($t =~ /^\s*([^\s]+)\s*=\s*"(.*)"\s*$/) { | |
481 my $c = $1; | |
482 my $v = $2; | |
483 $v =~ s/^["'](.*)["']$/$1/; # Drop quotation marks | |
484 $config{$c} = $v; | |
485 } | |
486 elsif ($t =~ /^\s*([^\s]+)\s*=\s*([^\s]+)\s*$/) { | |
487 my $c = $1; | |
488 my $v = $2; | |
489 $config{$c} = $v; | |
490 } | |
491 } | |
492 } |