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.
This commit is contained in:
Dam Sunwoo 2014-12-23 09:31:17 -05:00
parent 7e34bae813
commit 809134a2b1
3 changed files with 192 additions and 2 deletions

View file

@ -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

View file

@ -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()

View file

@ -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()