It appears that a good number of people found my articles from 2013 on building gem5 and SPEC CPU2006 benchmarks for Alpha useful! So due to some requests I’ve decided to make an additional post on how to get the SPEC benchmarks and gem5 you set up actually running.
This tutorial will show you how to get individual SPEC CPU2006 Alpha binaries to run inside the gem5 simulator modeling an Alpha system. My host system is Ubuntu Linux x86-64, but any Unix-like OS should work similarly for this tutorial.
Edit September 21, 2014: Added some more steps to the code in spec06_config.py and fixed ARGC check in the run_gem5_alpha_spec06_benchmark.sh file based on feedback from a reader. Thanks and keep the feedback coming!
Edit September 28, 2014: Minor edits that don’t affect correctness of the tutorial.
Edit June 7, 2017: Changed LiveProcess() to Process() in spec06_benchmarks.py to suit newer versions of gem5. Thanks Wenbo for the suggestion!
Note
|
Some of the source code snippets below might not fit in the page width, and it does not wrap. If this happens, make sure you scroll to the right to see all the code. |
The SPEC CPU2006 benchmarks come nicely wrapped out of:q the box with the runspec
utility which makes benchmarking systems easier for most users, and helps to ensure valid results across systems.
However, this utility doesn’t work when we want to run the workloads in the simulator for two reasons.
First, we cross-compiled the benchmarks for Alpha, which means we can’t test the benchmarks on the host system using runspec, unless we are actually running an Alpha box (which is unlikely).
Second, gem5 wants a regular application binary input as well as some command-line arguments.
To get these, you have to dig pretty deep into the SPEC CPU2006 runspec utility and other wrappers to see exactly how each binary is called.
For example, if you were to run the perlbench
SPEC CPU2006 benchmark directly on your host system, you’d do something like this:
runspec --config=my-alpha-hack.cfg --size=ref --noreportable --tune=base --iterations=1 perlbench
If you look into what runspec actually does here, it eventually make a call to the perlbench binary in this sort of manner:
cd $PATH_TO_YOUR_SPEC_CPU2006_INSTALL/benchspec/CPU2006/400.perlbench/run/run_base_ref_my-alpha.0000 perlbench_base.my-alpha -I./lib checkspam.pl 2500 5 25 11 150 1 1 1 1
Basically, all we need to do to get the benchmarks running in gem5 is to somehow get this command line fed into the simulator. This can be a pain, because each benchmark has a long annoying path, and has multiple possible input data sets.
To solve this, I recommend modifying the Python scripts in the gem5 configuration to allow easy programmatic execution of the different benchmarks.
Assuming we are running the simulator in system call emulation mode, we will modify the example se.py
configuration script to suit our needs.
Basically, we will make it so you can run gem5 with individual SPEC CPU2006 benchmarks like this:
cd $PATH_TO_YOUR_GEM5_INSTALL build/ALPHA/gem5.opt configs/example/spec06_config.py $YOUR_NORMAL_GEM5_CONFIG_PARAMETERS_HERE --benchmark=perlbench
Note the use of the spec06_config.py
configuration.
This doesn’t exist in the gem5 distribution, so we will have to make it ourselves!
cd $PATH_TO_YOUR_GEM5_INSTALL/configs/example cp se.py spec06_config.py
Using your favorite text editor of choice (which should be vim! :D), open the new configuration file you created.
At the top, add the following line (don’t worry, we will create spec06_benchmarks.py soon!):
import spec06_benchmarks
Then navigate to the point right after the script adds common options and system call emulation mode options:
# ...snip... parser = optparse.OptionParser() Options.addCommonOptions(parser) Options.addSEOptions(parser) # NAVIGATE TO THIS POINT # ...snip...
At this spot, add a new Python command-line parser option to easily pass the benchmark name as the input to the simulator.
parser.add_option("-b", "--benchmark", type="string", default="", help="The SPEC benchmark to be loaded.") parser.add_option("--benchmark_stdout", type="string", default="", help="Absolute path for stdout redirection for the benchmark.") parser.add_option("--benchmark_stderr", type="string", default="", help="Absolute path for stderr redirection for the benchmark.")
Now that we have the command line option now it’s time to do something useful with it! Somewhere in the script below the new option you added, and above the part where it sets up process to CPU mappings, we need to do some basic decoding of the input to select the proper benchmark.
At the part in the script where it initializes the multiprocessing and threads part, override it so it is single process, single thread (all SPEC CPU2006 benchmarks are single-thread single apps):
# multiprocesses = [] numThreads = 1
Add these new lines to the script below the numThreads = 1
part:
if options.benchmark: print 'Selected SPEC_CPU2006 benchmark' if options.benchmark == 'perlbench': print '--> perlbench' process = spec06_benchmarks.perlbench elif options.benchmark == 'bzip2': print '--> bzip2' process = spec06_benchmarks.bzip2 elif options.benchmark == 'gcc': print '--> gcc' process = spec06_benchmarks.gcc elif options.benchmark == 'bwaves': print '--> bwaves' process = spec06_benchmarks.bwaves elif options.benchmark == 'gamess': print '--> gamess' process = spec06_benchmarks.gamess elif options.benchmark == 'mcf': print '--> mcf' process = spec06_benchmarks.mcf elif options.benchmark == 'milc': print '--> milc' process = spec06_benchmarks.milc elif options.benchmark == 'zeusmp': print '--> zeusmp' process = spec06_benchmarks.zeusmp elif options.benchmark == 'gromacs': print '--> gromacs' process = spec06_benchmarks.gromacs elif options.benchmark == 'cactusADM': print '--> cactusADM' process = spec06_benchmarks.cactusADM elif options.benchmark == 'leslie3d': print '--> leslie3d' process = spec06_benchmarks.leslie3d elif options.benchmark == 'namd': print '--> namd' process = spec06_benchmarks.namd elif options.benchmark == 'gobmk': print '--> gobmk' process = spec06_benchmarks.gobmk elif options.benchmark == 'dealII': print '--> dealII' process = spec06_benchmarks.dealII elif options.benchmark == 'soplex': print '--> soplex' process = spec06_benchmarks.soplex elif options.benchmark == 'povray': print '--> povray' process = spec06_benchmarks.povray elif options.benchmark == 'calculix': print '--> calculix' process = spec06_benchmarks.calculix elif options.benchmark == 'hmmer': print '--> hmmer' process = spec06_benchmarks.hmmer elif options.benchmark == 'sjeng': print '--> sjeng' process = spec06_benchmarks.sjeng elif options.benchmark == 'GemsFDTD': print '--> GemsFDTD' process = spec06_benchmarks.GemsFDTD elif options.benchmark == 'libquantum': print '--> libquantum' process = spec06_benchmarks.libquantum elif options.benchmark == 'h264ref': print '--> h264ref' process = spec06_benchmarks.h264ref elif options.benchmark == 'tonto': print '--> tonto' process = spec06_benchmarks.tonto elif options.benchmark == 'lbm': print '--> lbm' process = spec06_benchmarks.lbm elif options.benchmark == 'omnetpp': print '--> omnetpp' process = spec06_benchmarks.omnetpp elif options.benchmark == 'astar': print '--> astar' process = spec06_benchmarks.astar elif options.benchmark == 'wrf': print '--> wrf' process = spec06_benchmarks.wrf elif options.benchmark == 'sphinx3': print '--> sphinx3' process = spec06_benchmarks.sphinx3 elif options.benchmark == 'xalancbmk': print '--> xalancbmk' process = spec06_benchmarks.xalancbmk elif options.benchmark == 'specrand_i': print '--> specrand_i' process = spec06_benchmarks.specrand_i elif options.benchmark == 'specrand_f': print '--> specrand_f' process = spec06_benchmarks.specrand_f else: print "No recognized SPEC2006 benchmark selected! Exiting." sys.exit(1) else: print >> sys.stderr, "Need --benchmark switch to specify SPEC CPU2006 workload. Exiting!\n" sys.exit(1) # Set process stdout/stderr if options.benchmark_stdout: process.output = options.benchmark_stdout print "Process stdout file: " + process.output if options.benchmark_stderr: process.errout = options.benchmark_stderr print "Process stderr file: " + process.errout
Then comment out this bit of code in spec06_config.py
:
# if options.bench: # apps = options.bench.split("-") # if len(apps) != options.num_cpus: # print "number of benchmarks not equal to set num_cpus!" # sys.exit(1) # # for app in apps: # try: # if buildEnv['TARGET_ISA'] == 'alpha': # exec("workload = %s('alpha', 'tru64', '%s')" % ( # app, options.spec_input)) # elif buildEnv['TARGET_ISA'] == 'arm': # exec("workload = %s('arm_%s', 'linux', '%s')" % ( # app, options.arm_iset, options.spec_input)) # else: # exec("workload = %s(buildEnv['TARGET_ISA', 'linux', '%s')" % ( # app, options.spec_input)) # multiprocesses.append(workload.makeProcess()) # Update June 7, 2017: this used to be workload.makeLiveProcess() # except: # print >>sys.stderr, "Unable to find workload for %s: %s" % ( # buildEnv['TARGET_ISA'], app) # sys.exit(1) # elif options.cmd: # multiprocesses, numThreads = get_processes(options) # else: # print >> sys.stderr, "No workload specified. Exiting!\n" # sys.exit(1)
And comment this out:
# for i in xrange(np): # if options.smt: # system.cpu[i].workload = multiprocesses # elif len(multiprocesses) == 1: # system.cpu[i].workload = multiprocesses[0] # else: # system.cpu[i].workload = multiprocesses[i] # # if options.fastmem: # system.cpu[i].fastmem = True # # if options.simpoint_profile: # system.cpu[i].simpoint_profile = True # system.cpu[i].simpoint_interval = options.simpoint_interval # # if options.checker: # system.cpu[i].addCheckerCpu() # # system.cpu[i].createThreads()
And add this below the latter commented part:
for i in xrange(np): system.cpu[i].workload = process print process.cmd
Now we are done with spec06_config.py
. Let’s create the spec06_benchmarks.py
file.
touch $PATH_TO_YOUR_GEM5_INSTALL/configs/example/spec06_benchmarks.py
Paste the following code into spec06_benchmarks.py
.
The code isn’t polished, but it worked for me to get running quickly.
Note that for each benchmark there are multiple possible command line arguments (inputs).
For each gem5 run I only use one benchmark with one input.
With this code, by default each benchmark will use the first reference input.
If you wish to use a different one, simply swap the appropriate commented lines for that benchmark.
Also note that I was not able to get every benchmark working for various reasons that I forgot (I did this over a year ago). Those are marked in the source below. You can probably hack a quick fix.
import m5 from m5.objects import * # These three directory paths are not currently used. #gem5_dir = '<FULL_PATH_TO_YOUR_GEM5_INSTALL>' #spec_dir = '<FULL_PATH_TO_YOUR_SPEC_CPU2006_INSTALL>' #out_dir = '<FULL_PATH_TO_DESIRED_OUTPUT_DIRECTORY>' alpha_suffix = '_base.my-alpha' #temp #binary_dir = spec_dir #data_dir = spec_dir #400.perlbench perlbench = Process() # Update June 7, 2017: This used to be LiveProcess() perlbench.executable = 'perlbench' + alpha_suffix # TEST CMDS #perlbench.cmd = [perlbench.executable] + ['-I.', '-I./lib', 'attrs.pl'] # REF CMDS perlbench.cmd = [perlbench.executable] + ['-I./lib', 'checkspam.pl', '2500', '5', '25', '11', '150', '1', '1', '1', '1'] #perlbench.cmd = [perlbench.executable] + ['-I./lib', 'diffmail.pl', '4', '800', '10', '17', '19', '300'] #perlbench.cmd = [perlbench.executable] + ['-I./lib', 'splitmail.pl', '1600', '12', '26', '16', '4500'] #perlbench.output = out_dir+'perlbench.out' #401.bzip2 bzip2 = Process() # Update June 7, 2017: This used to be LiveProcess() bzip2.executable = 'bzip2' + alpha_suffix # TEST CMDS #bzip2.cmd = [bzip2.executable] + ['input.program', '5'] # REF CMDS bzip2.cmd = [bzip2.executable] + ['input.source', '280'] #bzip2.cmd = [bzip2.executable] + ['chicken.jpg', '30'] #bzip2.cmd = [bzip2.executable] + ['liberty.jpg', '30'] #bzip2.cmd = [bzip2.executable] + ['input.program', '280'] #bzip2.cmd = [bzip2.executable] + ['text.html', '280'] #bzip2.cmd = [bzip2.executable] + ['input.combined', '200'] #bzip2.output = out_dir + 'bzip2.out' #403.gcc gcc = Process() # Update June 7, 2017: This used to be LiveProcess() gcc.executable = 'gcc' + alpha_suffix # TEST CMDS #gcc.cmd = [gcc.executable] + ['cccp.i', '-o', 'cccp.s'] # REF CMDS gcc.cmd = [gcc.executable] + ['166.i', '-o', '166.s'] #gcc.cmd = [gcc.executable] + ['200.i', '-o', '200.s'] #gcc.cmd = [gcc.executable] + ['c-typeck.i', '-o', 'c-typeck.s'] #gcc.cmd = [gcc.executable] + ['cp-decl.i', '-o', 'cp-decl.s'] #gcc.cmd = [gcc.executable] + ['expr.i', '-o', 'expr.s'] #gcc.cmd = [gcc.executable] + ['expr2.i', '-o', 'expr2.s'] #gcc.cmd = [gcc.executable] + ['g23.i', '-o', 'g23.s'] #gcc.cmd = [gcc.executable] + ['s04.i', '-o', 's04.s'] #gcc.cmd = [gcc.executable] + ['scilab.i', '-o', 'scilab.s'] #gcc.output = out_dir + 'gcc.out' #410.bwaves bwaves = Process() # Update June 7, 2017: This used to be LiveProcess() bwaves.executable = 'bwaves' + alpha_suffix # TEST CMDS #bwaves.cmd = [bwaves.executable] # REF CMDS bwaves.cmd = [bwaves.executable] #bwaves.output = out_dir + 'bwaves.out' #416.gamess gamess = Process() # Update June 7, 2017: This used to be LiveProcess() gamess.executable = 'gamess' + alpha_suffix # TEST CMDS #gamess.cmd = [gamess.executable] #gamess.input = 'exam29.config' # REF CMDS gamess.cmd = [gamess.executable] gamess.input = 'cytosine.2.config' #gamess.cmd = [gamess.executable] #gamess.input = 'h2ocu2+.gradient.config' #gamess.cmd = [gamess.executable] #gamess.input = 'triazolium.config' #gamess.output = out_dir + 'gamess.out' #429.mcf mcf = Process() # Update June 7, 2017: This used to be LiveProcess() mcf.executable = 'mcf' + alpha_suffix # TEST CMDS #mcf.cmd = [mcf.executable] + ['inp.in'] # REF CMDS mcf.cmd = [mcf.executable] + ['inp.in'] #mcf.output = out_dir + 'mcf.out' #433.milc milc = Process() # Update June 7, 2017: This used to be LiveProcess() milc.executable = 'milc' + alpha_suffix # TEST CMDS #milc.cmd = [milc.executable] #milc.input = 'su3imp.in' # REF CMDS milc.cmd = [milc.executable] milc.input = 'su3imp.in' #milc.output = out_dir + 'milc.out' #434.zeusmp zeusmp = Process() # Update June 7, 2017: This used to be LiveProcess() zeusmp.executable = 'zeusmp' + alpha_suffix # TEST CMDS #zeusmp.cmd = [zeusmp.executable] # REF CMDS zeusmp.cmd = [zeusmp.executable] #zeusmp.output = out_dir + 'zeusmp.out' #435.gromacs gromacs = Process() # Update June 7, 2017: This used to be LiveProcess() gromacs.executable = 'gromacs' + alpha_suffix # TEST CMDS #gromacs.cmd = [gromacs.executable] + ['-silent','-deffnm', 'gromacs', '-nice','0'] # REF CMDS gromacs.cmd = [gromacs.executable] + ['-silent','-deffnm', 'gromacs', '-nice','0'] #gromacs.output = out_dir + 'gromacs.out' #436.cactusADM cactusADM = Process() # Update June 7, 2017: This used to be LiveProcess() cactusADM.executable = 'cactusADM' + alpha_suffix # TEST CMDS #cactusADM.cmd = [cactusADM.executable] + ['benchADM.par'] # REF CMDS cactusADM.cmd = [cactusADM.executable] + ['benchADM.par'] #cactusADM.output = out_dir + 'cactusADM.out' #437.leslie3d leslie3d = Process() # Update June 7, 2017: This used to be LiveProcess() leslie3d.executable = 'leslie3d' + alpha_suffix # TEST CMDS #leslie3d.cmd = [leslie3d.executable] #leslie3d.input = 'leslie3d.in' # REF CMDS leslie3d.cmd = [leslie3d.executable] leslie3d.input = 'leslie3d.in' #leslie3d.output = out_dir + 'leslie3d.out' #444.namd namd = Process() # Update June 7, 2017: This used to be LiveProcess() namd.executable = 'namd' + alpha_suffix # TEST CMDS #namd.cmd = [namd.executable] + ['--input', 'namd.input', '--output', 'namd.out', '--iterations', '1'] # REF CMDS namd.cmd = [namd.executable] + ['--input', 'namd.input', '--output', 'namd.out', '--iterations', '38'] #namd.output = out_dir + 'namd.out' #445.gobmk gobmk = Process() # Update June 7, 2017: This used to be LiveProcess() gobmk.executable = 'gobmk' + alpha_suffix # TEST CMDS #gobmk.cmd = [gobmk.executable] + ['--quiet','--mode', 'gtp'] #gobmk.input = 'dniwog.tst' # REF CMDS gobmk.cmd = [gobmk.executable] + ['--quiet','--mode', 'gtp'] gobmk.input = '13x13.tst' #gobmk.cmd = [gobmk.executable] + ['--quiet','--mode', 'gtp'] #gobmk.input = 'nngs.tst' #gobmk.cmd = [gobmk.executable] + ['--quiet','--mode', 'gtp'] #gobmk.input = 'score2.tst' #gobmk.cmd = [gobmk.executable] + ['--quiet','--mode', 'gtp'] #gobmk.input = 'trevorc.tst' #gobmk.cmd = [gobmk.executable] + ['--quiet','--mode', 'gtp'] #gobmk.input = 'trevord.tst' #gobmk.output = out_dir + 'gobmk.out' #447.dealII ####### NOT WORKING ######### dealII = Process() # Update June 7, 2017: This used to be LiveProcess() dealII.executable = 'dealII' + alpha_suffix # TEST CMDS ####### NOT WORKING ######### #dealII.cmd = [gobmk.executable]+['8'] # REF CMDS ####### NOT WORKING ######### #dealII.output = out_dir + 'dealII.out' #450.soplex soplex = Process() # Update June 7, 2017: This used to be LiveProcess() soplex.executable = 'soplex' + alpha_suffix # TEST CMDS #soplex.cmd = [soplex.executable] + ['-m10000', 'test.mps'] # REF CMDS soplex.cmd = [soplex.executable] + ['-m45000', 'pds-50.mps'] #soplex.cmd = [soplex.executable] + ['-m3500', 'ref.mps'] #soplex.output = out_dir + 'soplex.out' #453.povray povray = Process() # Update June 7, 2017: This used to be LiveProcess() povray.executable = 'povray' + alpha_suffix # TEST CMDS #povray.cmd = [povray.executable] + ['SPEC-benchmark-test.ini'] # REF CMDS povray.cmd = [povray.executable] + ['SPEC-benchmark-ref.ini'] #povray.output = out_dir + 'povray.out' #454.calculix calculix = Process() # Update June 7, 2017: This used to be LiveProcess() calculix.executable = 'calculix' + alpha_suffix # TEST CMDS #calculix.cmd = [calculix.executable] + ['-i', 'beampic'] # REF CMDS calculix.cmd = [calculix.executable] + ['-i', 'hyperviscoplastic'] #calculix.output = out_dir + 'calculix.out' #456.hmmer hmmer = Process() # Update June 7, 2017: This used to be LiveProcess() hmmer.executable = 'hmmer' + alpha_suffix # TEST CMDS #hmmer.cmd = [hmmer.executable] + ['--fixed', '0', '--mean', '325', '--num', '45000', '--sd', '200', '--seed', '0', 'bombesin.hmm'] # REF CMDS hmmer.cmd = [hmmer.executable] + ['nph3.hmm', 'swiss41'] #hmmer.cmd = [hmmer.executable] + ['--fixed', '0', '--mean', '500', '--num', '500000', '--sd', '350', '--seed', '0', 'retro.hmm'] #hmmer.output = out_dir + 'hmmer.out' #458.sjeng sjeng = Process() # Update June 7, 2017: This used to be LiveProcess() sjeng.executable = 'sjeng' + alpha_suffix # TEST CMDS #sjeng.cmd = [sjeng.executable] + ['test.txt'] # REF CMDS sjeng.cmd = [sjeng.executable] + ['ref.txt'] #sjeng.output = out_dir + 'sjeng.out' #459.GemsFDTD GemsFDTD = Process() # Update June 7, 2017: This used to be LiveProcess() GemsFDTD.executable = 'GemsFDTD' + alpha_suffix # TEST CMDS #GemsFDTD.cmd = [GemsFDTD.executable] # REF CMDS GemsFDTD.cmd = [GemsFDTD.executable] #GemsFDTD.output = out_dir + 'GemsFDTD.out' #462.libquantum libquantum = Process() # Update June 7, 2017: This used to be LiveProcess() libquantum.executable = 'libquantum' + alpha_suffix # TEST CMDS #libquantum.cmd = [libquantum.executable] + ['33','5'] # REF CMDS [UPDATE 10/2/2015]: Sparsh Mittal has pointed out the correct input for libquantum should be 1397 and 8, not 1297 and 8. Thanks! libquantum.cmd = [libquantum.executable] + ['1397','8'] #libquantum.output = out_dir + 'libquantum.out' #464.h264ref h264ref = Process() # Update June 7, 2017: This used to be LiveProcess() h264ref.executable = 'h264ref' + alpha_suffix # TEST CMDS #h264ref.cmd = [h264ref.executable] + ['-d', 'foreman_test_encoder_baseline.cfg'] # REF CMDS h264ref.cmd = [h264ref.executable] + ['-d', 'foreman_ref_encoder_baseline.cfg'] #h264ref.cmd = [h264ref.executable] + ['-d', 'foreman_ref_encoder_main.cfg'] #h264ref.cmd = [h264ref.executable] + ['-d', 'sss_encoder_main.cfg'] #h264ref.output = out_dir + 'h264ref.out' #465.tonto tonto = Process() # Update June 7, 2017: This used to be LiveProcess() tonto.executable = 'tonto' + alpha_suffix # TEST CMDS #tonto.cmd = [tonto.executable] # REF CMDS tonto.cmd = [tonto.executable] #tonto.output = out_dir + 'tonto.out' #470.lbm lbm = Process() # Update June 7, 2017: This used to be LiveProcess() lbm.executable = 'lbm' + alpha_suffix # TEST CMDS #lbm.cmd = [lbm.executable] + ['20', 'reference.dat', '0', '1', '100_100_130_cf_a.of'] # REF CMDS lbm.cmd = [lbm.executable] + ['300', 'reference.dat', '0', '0', '100_100_130_ldc.of'] #lbm.output = out_dir + 'lbm.out' #471.omnetpp omnetpp = Process() # Update June 7, 2017: This used to be LiveProcess() omnetpp.executable = 'omnetpp' + alpha_suffix # TEST CMDS #omnetpp.cmd = [omnetpp.executable] + ['omnetpp.ini'] # REF CMDS omnetpp.cmd = [omnetpp.executable] + ['omnetpp.ini'] #omnetpp.output = out_dir + 'omnetpp.out' #473.astar astar = Process() # Update June 7, 2017: This used to be LiveProcess() astar.executable = 'astar' + alpha_suffix # TEST CMDS #astar.cmd = [astar.executable] + ['lake.cfg'] # REF CMDS astar.cmd = [astar.executable] + ['rivers.cfg'] #astar.output = out_dir + 'astar.out' #481.wrf wrf = Process() # Update June 7, 2017: This used to be LiveProcess() wrf.executable = 'wrf' + alpha_suffix # TEST CMDS #wrf.cmd = [wrf.executable] # REF CMDS wrf.cmd = [wrf.executable] #wrf.output = out_dir + 'wrf.out' #482.sphinx3 sphinx3 = Process() # Update June 7, 2017: This used to be LiveProcess() sphinx3.executable = 'sphinx_livepretend' + alpha_suffix # TEST CMDS #sphinx3.cmd = [sphinx3.executable] + ['ctlfile', '.', 'args.an4'] # REF CMDS sphinx3.cmd = [sphinx3.executable] + ['ctlfile', '.', 'args.an4'] #sphinx3.output = out_dir + 'sphinx3.out' #483.xalancbmk ######## NOT WORKING ########### xalancbmk = Process() # Update June 7, 2017: This used to be LiveProcess() xalancbmk.executable = 'xalancbmk' + alpha_suffix # TEST CMDS ######## NOT WORKING ########### #xalancbmk.cmd = [xalancbmk.executable] + ['-v','test.xml','xalanc.xsl'] # REF CMDS ######## NOT WORKING ########### #xalancbmk.output = out_dir + 'xalancbmk.out' #998.specrand specrand_i = Process() # Update June 7, 2017: This used to be LiveProcess() specrand_i.executable = 'specrand' + alpha_suffix # TEST CMDS #specrand_i.cmd = [specrand_i.executable] + ['324342', '24239'] # REF CMDS specrand_i.cmd = [specrand_i.executable] + ['1255432124', '234923'] #specrand_i.output = out_dir + 'specrand_i.out' #999.specrand specrand_f = Process() # Update June 7, 2017: This used to be LiveProcess() specrand_f.executable = 'specrand' + alpha_suffix # TEST CMDS #specrand_f.cmd = [specrand_f.executable] + ['324342', '24239'] # REF CMDS specrand_f.cmd = [specrand_f.executable] + ['1255432124', '234923'] #specrand_f.output = out_dir + 'specrand_f.out'
However, we still have a problem: gem5 does not know the path to the SPEC binary and its input. I solved it using a wrapper shell script around the gem5 call. I’ve provided the full script here.
Create a new file wherever you’d like to launch the simulator. This will probably be in the root directory of the gem5 installation.
cd $PATH_TO_YOUR_GEM5_INSTALL touch run_gem5_alpha_spec06_benchmark.sh
Paste the following code into run_gem5_alpha_spec06_benchmark.sh
:
#!/bin/bash # # run_gem5_alpha_spec06_benchmark.sh # Author: Mark Gottscho Email: mgottscho@ucla.edu # Copyright (C) 2014 Mark Gottscho # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <https://www.gnu.org/licenses/>. ############ DIRECTORY VARIABLES: MODIFY ACCORDINGLY ############# GEM5_DIR=<PATH_TO_YOUR_GEM5_INSTALL> # Install location of gem5 SPEC_DIR=<PATH_TO_YOUR_SPEC_CPU2006_INSTALL> # Install location of your SPEC2006 benchmarks ################################################################## ARGC=$# # Get number of arguments excluding arg0 (the script itself). Check for help message condition. if [[ "$ARGC" != 2 ]]; then # Bad number of arguments. echo "run_gem5_alpha_spec06_benchmark.sh Copyright (C) 2014 Mark Gottscho" echo "This program comes with ABSOLUTELY NO WARRANTY; for details see <https://www.gnu.org/licenses/>." echo "This is free software, and you are welcome to redistribute it under certain conditions; see <https://www.gnu.org/licenses/> for details." echo "" echo "Author: Mark Gottscho" echo "mgottscho@ucla.edu" echo "" echo "This script runs a single gem5 simulation of a single SPEC CPU2006 benchmark for Alpha ISA." echo "" echo "USAGE: run_gem5_alpha_spec06_benchmark.sh <BENCHMARK> <OUTPUT_DIR>" echo "EXAMPLE: ./run_gem5_alpha_spec06_benchmark.sh bzip2 /FULL/PATH/TO/output_dir" echo "" echo "A single --help help or -h argument will bring this message back." exit fi # Get command line input. We will need to check these. BENCHMARK=$1 # Benchmark name, e.g. bzip2 OUTPUT_DIR=$2 # Directory to place run output. Make sure this exists! ######################### BENCHMARK CODENAMES #################### PERLBENCH_CODE=400.perlbench BZIP2_CODE=401.bzip2 GCC_CODE=403.gcc BWAVES_CODE=410.bwaves GAMESS_CODE=416.gamess MCF_CODE=429.mcf MILC_CODE=433.milc ZEUSMP_CODE=434.zeusmp GROMACS_CODE=435.gromacs CACTUSADM_CODE=436.cactusADM LESLIE3D_CODE=437.leslie3d NAMD_CODE=444.namd GOBMK_CODE=445.gobmk DEALII_CODE=447.dealII SOPLEX_CODE=450.soplex POVRAY_CODE=453.povray CALCULIX_CODE=454.calculix HMMER_CODE=456.hmmer SJENG_CODE=458.sjeng GEMSFDTD_CODE=459.GemsFDTD LIBQUANTUM_CODE=462.libquantum H264REF_CODE=464.h264ref TONTO_CODE=465.tonto LBM_CODE=470.lbm OMNETPP_CODE=471.omnetpp ASTAR_CODE=473.astar WRF_CODE=481.wrf SPHINX3_CODE=482.sphinx3 XALANCBMK_CODE=483.xalancbmk SPECRAND_INT_CODE=998.specrand SPECRAND_FLOAT_CODE=999.specrand ################################################################## # Check BENCHMARK input #################### BENCHMARK CODE MAPPING ###################### BENCHMARK_CODE="none" if [[ "$BENCHMARK" == "perlbench" ]]; then BENCHMARK_CODE=$PERLBENCH_CODE fi if [[ "$BENCHMARK" == "bzip2" ]]; then BENCHMARK_CODE=$BZIP2_CODE fi if [[ "$BENCHMARK" == "gcc" ]]; then BENCHMARK_CODE=$GCC_CODE fi if [[ "$BENCHMARK" == "bwaves" ]]; then BENCHMARK_CODE=$BWAVES_CODE fi if [[ "$BENCHMARK" == "gamess" ]]; then BENCHMARK_CODE=$GAMESS_CODE fi if [[ "$BENCHMARK" == "mcf" ]]; then BENCHMARK_CODE=$MCF_CODE fi if [[ "$BENCHMARK" == "milc" ]]; then BENCHMARK_CODE=$MILC_CODE fi if [[ "$BENCHMARK" == "zeusmp" ]]; then BENCHMARK_CODE=$ZEUSMP_CODE fi if [[ "$BENCHMARK" == "gromacs" ]]; then BENCHMARK_CODE=$GROMACS_CODE fi if [[ "$BENCHMARK" == "cactusADM" ]]; then BENCHMARK_CODE=$CACTUSADM_CODE fi if [[ "$BENCHMARK" == "leslie3d" ]]; then BENCHMARK_CODE=$LESLIE3D_CODE fi if [[ "$BENCHMARK" == "namd" ]]; then BENCHMARK_CODE=$NAMD_CODE fi if [[ "$BENCHMARK" == "gobmk" ]]; then BENCHMARK_CODE=$GOBMK_CODE fi if [[ "$BENCHMARK" == "dealII" ]]; then # DOES NOT WORK BENCHMARK_CODE=$DEALII_CODE fi if [[ "$BENCHMARK" == "soplex" ]]; then BENCHMARK_CODE=$SOPLEX_CODE fi if [[ "$BENCHMARK" == "povray" ]]; then BENCHMARK_CODE=$POVRAY_CODE fi if [[ "$BENCHMARK" == "calculix" ]]; then BENCHMARK_CODE=$CALCULIX_CODE fi if [[ "$BENCHMARK" == "hmmer" ]]; then BENCHMARK_CODE=$HMMER_CODE fi if [[ "$BENCHMARK" == "sjeng" ]]; then BENCHMARK_CODE=$SJENG_CODE fi if [[ "$BENCHMARK" == "GemsFDTD" ]]; then BENCHMARK_CODE=$GEMSFDTD_CODE fi if [[ "$BENCHMARK" == "libquantum" ]]; then BENCHMARK_CODE=$LIBQUANTUM_CODE fi if [[ "$BENCHMARK" == "h264ref" ]]; then BENCHMARK_CODE=$H264REF_CODE fi if [[ "$BENCHMARK" == "tonto" ]]; then BENCHMARK_CODE=$TONTO_CODE fi if [[ "$BENCHMARK" == "lbm" ]]; then BENCHMARK_CODE=$LBM_CODE fi if [[ "$BENCHMARK" == "omnetpp" ]]; then BENCHMARK_CODE=$OMNETPP_CODE fi if [[ "$BENCHMARK" == "astar" ]]; then BENCHMARK_CODE=$ASTAR_CODE fi if [[ "$BENCHMARK" == "wrf" ]]; then BENCHMARK_CODE=$WRF_CODE fi if [[ "$BENCHMARK" == "sphinx3" ]]; then BENCHMARK_CODE=$SPHINX3_CODE fi if [[ "$BENCHMARK" == "xalancbmk" ]]; then # DOES NOT WORK BENCHMARK_CODE=$XALANCBMK_CODE fi if [[ "$BENCHMARK" == "specrand_i" ]]; then BENCHMARK_CODE=$SPECRAND_INT_CODE fi if [[ "$BENCHMARK" == "specrand_f" ]]; then BENCHMARK_CODE=$SPECRAND_FLOAT_CODE fi # Sanity check if [[ "$BENCHMARK_CODE" == "none" ]]; then echo "Input benchmark selection $BENCHMARK did not match any known SPEC CPU2006 benchmarks! Exiting." exit 1 fi ################################################################## # Check OUTPUT_DIR existence if [[ !(-d "$OUTPUT_DIR") ]]; then echo "Output directory $OUTPUT_DIR does not exist! Exiting." exit 1 fi RUN_DIR=$SPEC_DIR/benchspec/CPU2006/$BENCHMARK_CODE/run/run_base_ref\_my-alpha.0000 # Run directory for the selected SPEC benchmark SCRIPT_OUT=$OUTPUT_DIR/runscript.log # File log for this script's stdout henceforth ################## REPORT SCRIPT CONFIGURATION ################### echo "Command line:" | tee $SCRIPT_OUT echo "$0 $*" | tee -a $SCRIPT_OUT echo "================= Hardcoded directories ==================" | tee -a $SCRIPT_OUT echo "GEM5_DIR: $GEM5_DIR" | tee -a $SCRIPT_OUT echo "SPEC_DIR: $SPEC_DIR" | tee -a $SCRIPT_OUT echo "==================== Script inputs =======================" | tee -a $SCRIPT_OUT echo "BENCHMARK: $BENCHMARK" | tee -a $SCRIPT_OUT echo "OUTPUT_DIR: $OUTPUT_DIR" | tee -a $SCRIPT_OUT echo "==========================================================" | tee -a $SCRIPT_OUT ################################################################## #################### LAUNCH GEM5 SIMULATION ###################### echo "" echo "Changing to SPEC benchmark runtime directory: $RUN_DIR" | tee -a $SCRIPT_OUT cd $RUN_DIR echo "" | tee -a $SCRIPT_OUT echo "" | tee -a $SCRIPT_OUT echo "--------- Here goes nothing! Starting gem5! ------------" | tee -a $SCRIPT_OUT echo "" | tee -a $SCRIPT_OUT echo "" | tee -a $SCRIPT_OUT # Actually launch gem5! $GEM5_DIR/build/ALPHA/gem5.opt --outdir=$OUTPUT_DIR $GEM5_DIR/configs/example/spec06_config.py --benchmark=$BENCHMARK --benchmark_stdout=$OUTPUT_DIR/$BENCHMARK.out --benchmark_stderr=$OUTPUT_DIR/$BENCHMARK.err <YOUR_SIMULATOR_OPTIONS_HERE> | tee -a $SCRIPT_OUT
With all this code in place, all you should need to do now is to run gem5 like so:
cd $PATH_TO_YOUR_GEM5_INSTALL ./run_gem5_alpha_spec06_benchmark.sh <BENCHMARK_NAME> <FULL_PATH_TO_OUTPUT_DIRECTORY>
That’s it! If you have problems getting this to work, please feel free to respond to this post. Furthermore, if you find a bug in this code, please post as well so it can be fixed for others. I have modified the scripts somewhat in order to remove content directly related to conducting my research, so I may have left out something important. If you found this post helpful, please share it with others who would benefit. Finally, if you have any requests for other computer engineering and/or research-related tutorials, please feel free to contact me. Happy simulating! =]