From: Dam Sunwoo Date: Tue, 23 Dec 2014 14:31:17 +0000 (-0500) Subject: config: Add options to take/resume from SimPoint checkpoints X-Git-Tag: stable_2015_04_15~59 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=809134a2b151f82c29593e64086393b31bc110b7;p=gem5.git 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 Requires single Atomic CPU and fastmem. 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=,,, and is generated by SimPoint analysis tool from UCSD. SimPoint 3.2 format expected. and are in number of instructions. 4. To resume from gem5 SimPoint checkpoints, use the following option: --restore-simpoint-checkpoint -r --checkpoint-dir is (SimPoint index + 1). E.g., "-r 1" will resume from SimPoint #0. --- 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="") + 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()