diff options
-rw-r--r-- | configs/common/Options.py | 5 | ||||
-rw-r--r-- | configs/common/Simulation.py | 180 | ||||
-rw-r--r-- | configs/example/fs.py | 9 |
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() |