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:
parent
7e34bae813
commit
809134a2b1
3 changed files with 192 additions and 2 deletions
|
@ -150,6 +150,11 @@ def addCommonOptions(parser):
|
||||||
help="Enable basic block profiling for SimPoints")
|
help="Enable basic block profiling for SimPoints")
|
||||||
parser.add_option("--simpoint-interval", type="int", default=10000000,
|
parser.add_option("--simpoint-interval", type="int", default=10000000,
|
||||||
help="SimPoint interval in num of instructions")
|
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
|
# Checkpointing options
|
||||||
###Note that performing checkpointing via python script files will override
|
###Note that performing checkpointing via python script files will override
|
||||||
|
|
|
@ -140,9 +140,46 @@ def findCptDir(options, cptdir, testsys):
|
||||||
checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst))
|
checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst))
|
||||||
if not exists(checkpoint_dir):
|
if not exists(checkpoint_dir):
|
||||||
fatal("Unable to find checkpoint directory %s", 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:
|
else:
|
||||||
dirs = listdir(cptdir)
|
dirs = listdir(cptdir)
|
||||||
expr = re.compile('cpt\.([0-9]*)')
|
expr = re.compile('cpt\.([0-9]+)')
|
||||||
cpts = []
|
cpts = []
|
||||||
for dir in dirs:
|
for dir in dirs:
|
||||||
match = expr.match(dir)
|
match = expr.match(dir)
|
||||||
|
@ -239,6 +276,131 @@ def benchCheckpoints(options, maxtick, cptdir):
|
||||||
|
|
||||||
return exit_event
|
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):
|
def repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq):
|
||||||
print "starting switch loop"
|
print "starting switch loop"
|
||||||
while True:
|
while True:
|
||||||
|
@ -411,6 +573,9 @@ def run(options, root, testsys, cpu_class):
|
||||||
for i in xrange(np):
|
for i in xrange(np):
|
||||||
testsys.cpu[i].max_insts_any_thread = offset
|
testsys.cpu[i].max_insts_any_thread = offset
|
||||||
|
|
||||||
|
if options.take_simpoint_checkpoints != None:
|
||||||
|
simpoints, interval_length = parseSimpointAnalysisFile(options, testsys)
|
||||||
|
|
||||||
checkpoint_dir = None
|
checkpoint_dir = None
|
||||||
if options.checkpoint_restore:
|
if options.checkpoint_restore:
|
||||||
cpt_starttick, checkpoint_dir = findCptDir(options, cptdir, testsys)
|
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
|
# option only for finding the checkpoints to restore from. This
|
||||||
# lets us test checkpointing by restoring from one set of
|
# lets us test checkpointing by restoring from one set of
|
||||||
# checkpoints, generating a second set, and then comparing them.
|
# 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:
|
if m5.options.outdir:
|
||||||
cptdir = m5.options.outdir
|
cptdir = m5.options.outdir
|
||||||
else:
|
else:
|
||||||
|
@ -497,6 +664,15 @@ def run(options, root, testsys, cpu_class):
|
||||||
# received from the benchmark running are ignored and skipped in
|
# received from the benchmark running are ignored and skipped in
|
||||||
# favor of command line checkpoint instructions.
|
# favor of command line checkpoint instructions.
|
||||||
exit_event = scriptCheckpoints(options, maxtick, cptdir)
|
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:
|
else:
|
||||||
if options.fast_forward:
|
if options.fast_forward:
|
||||||
m5.stats.reset()
|
m5.stats.reset()
|
||||||
|
|
|
@ -197,9 +197,18 @@ def build_test_system(np):
|
||||||
if (options.caches or options.l2cache):
|
if (options.caches or options.l2cache):
|
||||||
fatal("You cannot use fastmem in combination with caches!")
|
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):
|
for i in xrange(np):
|
||||||
if options.fastmem:
|
if options.fastmem:
|
||||||
test_sys.cpu[i].fastmem = True
|
test_sys.cpu[i].fastmem = True
|
||||||
|
if options.simpoint_profile:
|
||||||
|
test_sys.cpu[i].addSimPointProbe(options.simpoint_interval)
|
||||||
if options.checker:
|
if options.checker:
|
||||||
test_sys.cpu[i].addCheckerCpu()
|
test_sys.cpu[i].addCheckerCpu()
|
||||||
test_sys.cpu[i].createThreads()
|
test_sys.cpu[i].createThreads()
|
||||||
|
|
Loading…
Reference in a new issue