summaryrefslogtreecommitdiff
path: root/configs
diff options
context:
space:
mode:
authorDam Sunwoo <dam.sunwoo@arm.com>2014-12-23 09:31:17 -0500
committerDam Sunwoo <dam.sunwoo@arm.com>2014-12-23 09:31:17 -0500
commit809134a2b151f82c29593e64086393b31bc110b7 (patch)
tree281d9bf15f3ee736ffbd0b4202915a429944b074 /configs
parent7e34bae813a2dc1dc15cea53183840622ac4394e (diff)
downloadgem5-809134a2b151f82c29593e64086393b31bc110b7.tar.xz
config: Add options to take/resume from SimPoint checkpoints
More documentation at http://gem5.org/Simpoints Steps to profile, generate, and use SimPoints with gem5: 1. To profile workload and generate SimPoint BBV file, use the following option: --simpoint-profile --simpoint-interval <interval length> Requires single Atomic CPU and fastmem. <interval length> is in number of instructions. 2. Generate SimPoint analysis using SimPoint 3.2 from UCSD. (SimPoint 3.2 not included with this flow.) 3. To take gem5 checkpoints based on SimPoint analysis, use the following option: --take-simpoint-checkpoint=<simpoint file path>,<weight file path>,<interval length>,<warmup length> <simpoint file> and <weight file> is generated by SimPoint analysis tool from UCSD. SimPoint 3.2 format expected. <interval length> and <warmup length> are in number of instructions. 4. To resume from gem5 SimPoint checkpoints, use the following option: --restore-simpoint-checkpoint -r <N> --checkpoint-dir <simpoint checkpoint path> <N> is (SimPoint index + 1). E.g., "-r 1" will resume from SimPoint #0.
Diffstat (limited to 'configs')
-rw-r--r--configs/common/Options.py5
-rw-r--r--configs/common/Simulation.py180
-rw-r--r--configs/example/fs.py9
3 files changed, 192 insertions, 2 deletions
diff --git a/configs/common/Options.py b/configs/common/Options.py
index a788af290..cb5ffad2e 100644
--- a/configs/common/Options.py
+++ b/configs/common/Options.py
@@ -150,6 +150,11 @@ def addCommonOptions(parser):
help="Enable basic block profiling for SimPoints")
parser.add_option("--simpoint-interval", type="int", default=10000000,
help="SimPoint interval in num of instructions")
+ parser.add_option("--take-simpoint-checkpoints", action="store", type="string",
+ help="<simpoint file,weight file,interval-length,warmup-length>")
+ parser.add_option("--restore-simpoint-checkpoint", action="store_true",
+ help="restore from a simpoint checkpoint taken with " +
+ "--take-simpoint-checkpoints")
# Checkpointing options
###Note that performing checkpointing via python script files will override
diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py
index 5d4398c80..72d3d0e97 100644
--- a/configs/common/Simulation.py
+++ b/configs/common/Simulation.py
@@ -140,9 +140,46 @@ def findCptDir(options, cptdir, testsys):
checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst))
if not exists(checkpoint_dir):
fatal("Unable to find checkpoint directory %s", checkpoint_dir)
+
+ elif options.restore_simpoint_checkpoint:
+ # Restore from SimPoint checkpoints
+ # Assumes that the checkpoint dir names are formatted as follows:
+ dirs = listdir(cptdir)
+ expr = re.compile('cpt\.simpoint_(\d+)_inst_(\d+)' +
+ '_weight_([\d\.e\-]+)_interval_(\d+)_warmup_(\d+)')
+ cpts = []
+ for dir in dirs:
+ match = expr.match(dir)
+ if match:
+ cpts.append(dir)
+ cpts.sort()
+
+ cpt_num = options.checkpoint_restore
+ if cpt_num > len(cpts):
+ fatal('Checkpoint %d not found', cpt_num)
+ checkpoint_dir = joinpath(cptdir, cpts[cpt_num - 1])
+ match = expr.match(cpts[cpt_num - 1])
+ if match:
+ index = int(match.group(1))
+ start_inst = int(match.group(2))
+ weight_inst = float(match.group(3))
+ interval_length = int(match.group(4))
+ warmup_length = int(match.group(5))
+ print "Resuming from", checkpoint_dir
+ simpoint_start_insts = []
+ simpoint_start_insts.append(warmup_length)
+ simpoint_start_insts.append(warmup_length + interval_length)
+ testsys.cpu[0].simpoint_start_insts = simpoint_start_insts
+ if testsys.switch_cpus != None:
+ testsys.switch_cpus[0].simpoint_start_insts = simpoint_start_insts
+
+ print "Resuming from SimPoint",
+ print "#%d, start_inst:%d, weight:%f, interval:%d, warmup:%d" % \
+ (index, start_inst, weight_inst, interval_length, warmup_length)
+
else:
dirs = listdir(cptdir)
- expr = re.compile('cpt\.([0-9]*)')
+ expr = re.compile('cpt\.([0-9]+)')
cpts = []
for dir in dirs:
match = expr.match(dir)
@@ -239,6 +276,131 @@ def benchCheckpoints(options, maxtick, cptdir):
return exit_event
+# Set up environment for taking SimPoint checkpoints
+# Expecting SimPoint files generated by SimPoint 3.2
+def parseSimpointAnalysisFile(options, testsys):
+ import re
+
+ simpoint_filename, weight_filename, interval_length, warmup_length = \
+ options.take_simpoint_checkpoints.split(",", 3)
+ print "simpoint analysis file:", simpoint_filename
+ print "simpoint weight file:", weight_filename
+ print "interval length:", interval_length
+ print "warmup length:", warmup_length
+
+ interval_length = int(interval_length)
+ warmup_length = int(warmup_length)
+
+ # Simpoint analysis output starts interval counts with 0.
+ simpoints = []
+ simpoint_start_insts = []
+
+ # Read in SimPoint analysis files
+ simpoint_file = open(simpoint_filename)
+ weight_file = open(weight_filename)
+ while True:
+ line = simpoint_file.readline()
+ if not line:
+ break
+ m = re.match("(\d+)\s+(\d+)", line)
+ if m:
+ interval = int(m.group(1))
+ else:
+ fatal('unrecognized line in simpoint file!')
+
+ line = weight_file.readline()
+ if not line:
+ fatal('not enough lines in simpoint weight file!')
+ m = re.match("([0-9\.e\-]+)\s+(\d+)", line)
+ if m:
+ weight = float(m.group(1))
+ else:
+ fatal('unrecognized line in simpoint weight file!')
+
+ if (interval * interval_length - warmup_length > 0):
+ starting_inst_count = \
+ interval * interval_length - warmup_length
+ actual_warmup_length = warmup_length
+ else:
+ # Not enough room for proper warmup
+ # Just starting from the beginning
+ starting_inst_count = 0
+ actual_warmup_length = interval * interval_length
+
+ simpoints.append((interval, weight, starting_inst_count,
+ actual_warmup_length))
+
+ # Sort SimPoints by starting inst count
+ simpoints.sort(key=lambda obj: obj[2])
+ for s in simpoints:
+ interval, weight, starting_inst_count, actual_warmup_length = s
+ print str(interval), str(weight), starting_inst_count, \
+ actual_warmup_length
+ simpoint_start_insts.append(starting_inst_count)
+
+ print "Total # of simpoints:", len(simpoints)
+ testsys.cpu[0].simpoint_start_insts = simpoint_start_insts
+
+ return (simpoints, interval_length)
+
+def takeSimpointCheckpoints(simpoints, interval_length, cptdir):
+ num_checkpoints = 0
+ index = 0
+ last_chkpnt_inst_count = -1
+ for simpoint in simpoints:
+ interval, weight, starting_inst_count, actual_warmup_length = simpoint
+ if starting_inst_count == last_chkpnt_inst_count:
+ # checkpoint starting point same as last time
+ # (when warmup period longer than starting point)
+ exit_cause = "simpoint starting point found"
+ code = 0
+ else:
+ exit_event = m5.simulate()
+
+ # skip checkpoint instructions should they exist
+ while exit_event.getCause() == "checkpoint":
+ print "Found 'checkpoint' exit event...ignoring..."
+ exit_event = m5.simulate()
+
+ exit_cause = exit_event.getCause()
+ code = exit_event.getCode()
+
+ if exit_cause == "simpoint starting point found":
+ m5.checkpoint(joinpath(cptdir,
+ "cpt.simpoint_%02d_inst_%d_weight_%f_interval_%d_warmup_%d"
+ % (index, starting_inst_count, weight, interval_length,
+ actual_warmup_length)))
+ print "Checkpoint #%d written. start inst:%d weight:%f" % \
+ (num_checkpoints, starting_inst_count, weight)
+ num_checkpoints += 1
+ last_chkpnt_inst_count = starting_inst_count
+ else:
+ break
+ index += 1
+
+ print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)
+ print "%d checkpoints taken" % num_checkpoints
+ sys.exit(code)
+
+def restoreSimpointCheckpoint():
+ exit_event = m5.simulate()
+ exit_cause = exit_event.getCause()
+
+ if exit_cause == "simpoint starting point found":
+ print "Warmed up! Dumping and resetting stats!"
+ m5.stats.dump()
+ m5.stats.reset()
+
+ exit_event = m5.simulate()
+ exit_cause = exit_event.getCause()
+
+ if exit_cause == "simpoint starting point found":
+ print "Done running SimPoint!"
+ sys.exit(exit_event.getCode())
+
+ print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause)
+ sys.exit(exit_event.getCode())
+
def repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq):
print "starting switch loop"
while True:
@@ -411,6 +573,9 @@ def run(options, root, testsys, cpu_class):
for i in xrange(np):
testsys.cpu[i].max_insts_any_thread = offset
+ if options.take_simpoint_checkpoints != None:
+ simpoints, interval_length = parseSimpointAnalysisFile(options, testsys)
+
checkpoint_dir = None
if options.checkpoint_restore:
cpt_starttick, checkpoint_dir = findCptDir(options, cptdir, testsys)
@@ -485,7 +650,9 @@ def run(options, root, testsys, cpu_class):
# option only for finding the checkpoints to restore from. This
# lets us test checkpointing by restoring from one set of
# checkpoints, generating a second set, and then comparing them.
- if options.take_checkpoints and options.checkpoint_restore:
+ if (options.take_checkpoints or options.take_simpoint_checkpoints) \
+ and options.checkpoint_restore:
+
if m5.options.outdir:
cptdir = m5.options.outdir
else:
@@ -497,6 +664,15 @@ def run(options, root, testsys, cpu_class):
# received from the benchmark running are ignored and skipped in
# favor of command line checkpoint instructions.
exit_event = scriptCheckpoints(options, maxtick, cptdir)
+
+ # Take SimPoint checkpoints
+ elif options.take_simpoint_checkpoints != None:
+ takeSimpointCheckpoints(simpoints, interval_length, cptdir)
+
+ # Restore from SimPoint checkpoints
+ elif options.restore_simpoint_checkpoint != None:
+ restoreSimpointCheckpoint()
+
else:
if options.fast_forward:
m5.stats.reset()
diff --git a/configs/example/fs.py b/configs/example/fs.py
index 62a298559..6fa0f8a11 100644
--- a/configs/example/fs.py
+++ b/configs/example/fs.py
@@ -197,9 +197,18 @@ def build_test_system(np):
if (options.caches or options.l2cache):
fatal("You cannot use fastmem in combination with caches!")
+ if options.simpoint_profile:
+ if not options.fastmem:
+ # Atomic CPU checked with fastmem option already
+ fatal("SimPoint generation should be done with atomic cpu and fastmem")
+ if np > 1:
+ fatal("SimPoint generation not supported with more than one CPUs")
+
for i in xrange(np):
if options.fastmem:
test_sys.cpu[i].fastmem = True
+ if options.simpoint_profile:
+ test_sys.cpu[i].addSimPointProbe(options.simpoint_interval)
if options.checker:
test_sys.cpu[i].addCheckerCpu()
test_sys.cpu[i].createThreads()