def run_test(root, switcher=None, freq=1000): """Test runner for CPU switcheroo tests. The switcheroo test runner is used to switch CPUs in a system that has been prepared for CPU switching. Such systems should have multiple CPUs when they are instantiated, but only one should be switched in. Such configurations can be created using the base_config.BaseFSSwitcheroo class. A CPU switcher object is used to control switching. The default switcher sequentially switches between all CPUs in a system, starting with the CPU that is currently switched in. Unlike most other test runners, this one automatically configures the memory mode of the system based on the first CPU the switcher reports. Keyword Arguments: switcher -- CPU switcher implementation. See Sequential for an example implementation. period -- Switching frequency in Hz. """ if switcher == None: switcher = Sequential(root.system.cpu) current_cpu = switcher.first() system = root.system system.mem_mode = type(current_cpu).memory_mode() # instantiate configuration m5.instantiate() # Determine the switching period, this has to be done after # instantiating the system since the time base must be fixed. period = m5.ticks.fromSeconds(1.0 / freq) while True: exit_event = m5.simulate(period) exit_cause = exit_event.getCause() if exit_cause == "simulate() limit reached": next_cpu = switcher.next() print "Switching CPUs..." print "Next CPU: %s" % type(next_cpu) m5.drain(system) if current_cpu != next_cpu: m5.switchCpus(system, [(current_cpu, next_cpu)], do_drain=False) else: print "Source CPU and destination CPU are the same, skipping..." m5.resume(system) current_cpu = next_cpu elif exit_cause == "target called exit()" or \ exit_cause == "m5_exit instruction encountered": sys.exit(0) else: print "Test failed: Unknown exit cause: %s" % exit_cause sys.exit(1)
def run_test(root, switcher=None, freq=1000): """Test runner for CPU switcheroo tests. The switcheroo test runner is used to switch CPUs in a system that has been prepared for CPU switching. Such systems should have multiple CPUs when they are instantiated, but only one should be switched in. Such configurations can be created using the base_config.BaseFSSwitcheroo class. A CPU switcher object is used to control switching. The default switcher sequentially switches between all CPUs in a system, starting with the CPU that is currently switched in. Unlike most other test runners, this one automatically configures the memory mode of the system based on the first CPU the switcher reports. Keyword Arguments: switcher -- CPU switcher implementation. See Sequential for an example implementation. period -- Switching frequency in Hz. """ if switcher == None: switcher = Sequential(root.system.cpu) current_cpu = switcher.first() system = root.system system.mem_mode = type(current_cpu).memory_mode() # instantiate configuration m5.instantiate() # Determine the switching period, this has to be done after # instantiating the system since the time base must be fixed. period = m5.ticks.fromSeconds(1.0 / freq) while True: exit_event = m5.simulate(period) exit_cause = exit_event.getCause() if exit_cause == "simulate() limit reached": next_cpu = switcher.next() print "Switching CPUs..." print "Next CPU: %s" % type(next_cpu) m5.drain(system) if current_cpu != next_cpu: m5.switchCpus(system, [ (current_cpu, next_cpu) ], do_drain=False) else: print "Source CPU and destination CPU are the same, skipping..." m5.resume(system) current_cpu = next_cpu elif exit_cause == "target called exit()" or \ exit_cause == "m5_exit instruction encountered": sys.exit(0) else: print "Test failed: Unknown exit cause: %s" % exit_cause sys.exit(1)
def repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq): print "starting switch loop" while True: exit_event = m5.simulate() exit_cause = exit_event.getCause() if exit_cause != "switchcpu": return exit_event m5.switchCpus(testsys, repeat_switch_cpu_list) tmp_cpu_list = [] for old_cpu, new_cpu in repeat_switch_cpu_list: tmp_cpu_list.append((new_cpu, old_cpu)) repeat_switch_cpu_list = tmp_cpu_list
def repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, switch_freq): print("starting switch loop") while True: exit_event = m5.simulate(switch_freq) exit_cause = exit_event.getCause() if exit_cause != "simulate() limit reached": return exit_event m5.switchCpus(testsys, repeat_switch_cpu_list) tmp_cpu_list = [] for old_cpu, new_cpu in repeat_switch_cpu_list: tmp_cpu_list.append((new_cpu, old_cpu)) repeat_switch_cpu_list = tmp_cpu_list if (maxtick - m5.curTick()) <= switch_freq: exit_event = m5.simulate(maxtick - m5.curTick()) return exit_event
def run(root, options, checkpoint_dir=m5.options.outdir): # start simulation (and drop checkpoints when requested) while True: event = m5.simulate() exit_msg = event.getCause() if exit_msg == "checkpoint": print("Dropping checkpoint at tick %d" % m5.curTick()) cpt_dir = os.path.join(checkpoint_dir, "cpt.%d" % m5.curTick()) m5.checkpoint(cpt_dir) print("Checkpoint done.") else: print(exit_msg, " @ ", m5.curTick()) break switch_cpu_list = [] if options.fast_forward: if options.big_cpus: sw_tmp_list = [(root.system.bigCluster.cpus[i], root.system.bigCluster.switch_cpus[i]) for i in range(options.big_cpus)] switch_cpu_list += sw_tmp_list if options.mid_cpus: sw_tmp_list = [(root.system.midCluster.cpus[i], root.system.midCluster.switch_cpus[i]) for i in range(options.mid_cpus)] switch_cpu_list += sw_tmp_list if options.little_cpus: sw_tmp_list = [(root.system.littleCluster.cpus[i], root.system.littleCluster.switch_cpus[i]) for i in range(options.little_cpus)] switch_cpu_list += sw_tmp_list print("Shift CPU at tick %d" % m5.curTick()) m5.switchCpus(root.system, switch_cpu_list) m5.stats.reset() event = m5.simulate() sys.exit(event.getCode())
def switch_to_processor(self, switchable_core_key: Any): # Run various checks. if not hasattr(self, "_board"): raise AssertionError("The processor has not been incorporated.") if switchable_core_key not in self._switchable_cores.keys(): raise AssertionError( f"Key {switchable_core_key} is not a key in the" " switchable_processor dictionary.") # Select the correct processor to switch to. to_switch = self._switchable_cores[switchable_core_key] # Run more checks. if to_switch == self._current_cores: raise AssertionError( "Cannot swap current cores with the current cores") if len(to_switch) != len(self._current_cores): raise AssertionError( "The number of cores to swap in is not the same as the number " "already swapped in. This is not allowed.") current_core_simobj = [ core.get_simobject() for core in self._current_cores ] to_switch_simobj = [core.get_simobject() for core in to_switch] # Switch the CPUs m5.switchCpus( self._board, list(zip(current_core_simobj, to_switch_simobj)), ) # Ensure the current processor is updated. self._current_cores = to_switch
def run(options, root, testsys, cpu_class, numpids): if options.maxtick: maxtick = options.maxtick elif options.maxtime: simtime = m5.ticks.seconds(simtime) print "simulating for: ", simtime maxtick = simtime else: maxtick = m5.MaxTick if options.checkpoint_dir: cptdir = options.checkpoint_dir elif m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.fast_forward and options.checkpoint_restore != None: fatal("Can't specify both --fast-forward and --checkpoint-restore") if options.standard_switch and not options.caches: fatal("Must specify --caches when using --standard-switch") if options.standard_switch and options.repeat_switch: fatal("Can't specify both --standard-switch and --repeat-switch") if options.repeat_switch and options.take_checkpoints: fatal("Can't specify both --repeat-switch and --take-checkpoints") np = options.num_cpus switch_cpus = None if options.prog_interval: for i in xrange(np): testsys.cpu[i].progress_interval = options.prog_interval if options.maxinsts: for i in xrange(np): testsys.cpu[i].max_insts_any_thread = options.maxinsts if cpu_class: switch_cpus = [cpu_class(defer_registration=True, cpu_id=(i)) for i in xrange(np)] for i in xrange(np): if options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) switch_cpus[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[i].clock # simulation period if options.maxinsts: switch_cpus[i].max_insts_any_thread = options.maxinsts # Add checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() testsys.switch_cpus = switch_cpus switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] if options.repeat_switch: if options.cpu_type == "arm_detailed": if not options.caches: print "O3 CPU must be used with caches" sys.exit(1) repeat_switch_cpus = [O3_ARM_v7a_3(defer_registration=True, cpu_id=(i)) for i in xrange(np)] elif options.cpu_type == "detailed": if not options.caches: print "O3 CPU must be used with caches" sys.exit(1) repeat_switch_cpus = [DerivO3CPU(defer_registration=True, cpu_id=(i)) for i in xrange(np)] elif options.cpu_type == "inorder": print "inorder CPU switching not supported" sys.exit(1) elif options.cpu_type == "timing": repeat_switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(i)) for i in xrange(np)] else: repeat_switch_cpus = [AtomicSimpleCPU(defer_registration=True, cpu_id=(i)) for i in xrange(np)] for i in xrange(np): repeat_switch_cpus[i].system = testsys repeat_switch_cpus[i].workload = testsys.cpu[i].workload repeat_switch_cpus[i].clock = testsys.cpu[i].clock if options.maxinsts: repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts if options.checker: repeat_switch_cpus[i].addCheckerCpu() testsys.repeat_switch_cpus = repeat_switch_cpus if cpu_class: repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i]) for i in xrange(np)] else: repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i]) for i in xrange(np)] if options.standard_switch: switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(i)) for i in xrange(np)] switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(i)) for i in xrange(np)] for i in xrange(np): switch_cpus[i].system = testsys switch_cpus_1[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus_1[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[i].clock switch_cpus_1[i].clock = testsys.cpu[i].clock # if restoring, make atomic cpu simulate only a few instructions if options.checkpoint_restore != None: testsys.cpu[i].max_insts_any_thread = 1 # Fast forward to specified location if we are not restoring elif options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) # Fast forward to a simpoint (warning: time consuming) elif options.simpoint: if testsys.cpu[i].workload[0].simpoint == 0: fatal("simpoint not found") testsys.cpu[i].max_insts_any_thread = testsys.cpu[i].workload[0].simpoint # No distance specified, just switch else: testsys.cpu[i].max_insts_any_thread = 1 # warmup period if options.warmup_insts: switch_cpus[i].max_insts_any_thread = options.warmup_insts # simulation period if options.maxinsts: switch_cpus_1[i].max_insts_any_thread = options.maxinsts # attach the checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() switch_cpus_1[i].addCheckerCpu() testsys.switch_cpus = switch_cpus testsys.switch_cpus_1 = switch_cpus_1 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)] # set the checkpoint in the cpu before m5.instantiate is called if options.take_checkpoints != None and (options.simpoint or options.at_instruction): offset = int(options.take_checkpoints) # Set an instruction break point if options.simpoint: for i in xrange(np): if testsys.cpu[i].workload[0].simpoint == 0: fatal("no simpoint for testsys.cpu[%d].workload[0]", i) checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset testsys.cpu[i].max_insts_any_thread = checkpoint_inst # used for output below options.take_checkpoints = checkpoint_inst else: options.take_checkpoints = offset # Set all test cpus with the right number of instructions # for the upcoming simulation for i in xrange(np): testsys.cpu[i].max_insts_any_thread = offset checkpoint_dir = None if options.checkpoint_restore != None: maxtick, checkpoint_dir = findCptDir(options, maxtick, cptdir, testsys) m5.instantiate(checkpoint_dir) if options.standard_switch or cpu_class: if options.standard_switch: print "Switch at instruction count:%s" % str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate(maxtick, numpids) elif cpu_class and options.fast_forward: print "Switch at instruction count:%s" % str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate(maxtick, numpids) else: print "Switch at curTick count:%s" % str(10000) exit_event = m5.simulate(10000) print "Switched CPUS @ tick %s" % (m5.curTick()) # when you change to Timing (or Atomic), you halt the system # given as argument. When you are finished with the system # changes (including switchCpus), you must resume the system # manually. You DON'T need to resume after just switching # CPUs if you haven't changed anything on the system level. m5.changeToTiming(testsys) m5.switchCpus(switch_cpu_list) m5.resume(testsys) if options.standard_switch: print "Switch at instruction count:%d" % (testsys.switch_cpus[0].max_insts_any_thread) # warmup instruction count may have already been set if options.warmup_insts: exit_event = m5.simulate(maxtick, numpids) else: exit_event = m5.simulate(options.standard_switch, numpids) print "Switching CPUS @ tick %s" % (m5.curTick()) print "Simulation ends instruction count:%d" % (testsys.switch_cpus_1[0].max_insts_any_thread) m5.drain(testsys) m5.switchCpus(switch_cpu_list1) m5.resume(testsys) # If we're taking and restoring checkpoints, use checkpoint_dir # 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 m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.take_checkpoints != None: # Checkpoints being taken via the command line at <when> and at # subsequent periods of <period>. Checkpoint instructions # received from the benchmark running are ignored and skipped in # favor of command line checkpoint instructions. exit_cause = scriptCheckpoints(options, cptdir) else: if options.fast_forward: m5.stats.reset() print "**** REAL SIMULATION ****" # If checkpoints are being taken, then the checkpoint instruction # will occur in the benchmark code it self. if options.repeat_switch and maxtick > options.repeat_switch: exit_cause = repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, options.repeat_switch) else: exit_cause = benchCheckpoints(options, maxtick, cptdir, numpids) print "Exiting @ tick %i because %s" % (m5.curTick(), exit_cause) if options.checkpoint_at_end: m5.checkpoint(joinpath(cptdir, "cpt.%d"))
def run(options, root, testsys, cpu_class): if options.disable_ports: m5.disableAllListeners() if options.checkpoint_dir: cptdir = options.checkpoint_dir elif m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.fast_forward and options.checkpoint_restore != None: fatal("Can't specify both --fast-forward and --checkpoint-restore") if options.standard_switch and not options.caches: fatal("Must specify --caches when using --standard-switch") if options.standard_switch and options.repeat_switch: fatal("Can't specify both --standard-switch and --repeat-switch") if options.repeat_switch and options.take_checkpoints: fatal("Can't specify both --repeat-switch and --take-checkpoints") np = options.num_cpus switch_cpus = None if options.prog_interval: for i in xrange(np): testsys.cpu[i].progress_interval = options.prog_interval if options.maxinsts: for i in xrange(np): testsys.cpu[i].max_insts_any_thread = options.maxinsts if cpu_class: switch_cpus = [ cpu_class(switched_out=True, cpu_id=(i)) for i in xrange(np) ] for i in xrange(np): if options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) switch_cpus[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain switch_cpus[i].progress_interval = \ testsys.cpu[i].progress_interval # simulation period if options.maxinsts: switch_cpus[i].max_insts_any_thread = options.maxinsts # Add checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() # If elastic tracing is enabled attach the elastic trace probe # to the switch CPUs if options.elastic_trace_en: CpuConfig.config_etrace(cpu_class, switch_cpus, options) testsys.switch_cpus = switch_cpus switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] if cpu_class == getCPUClass("detailed"): config_O3cpu(options, testsys.switch_cpus) if options.repeat_switch: switch_class = getCPUClass(options.cpu_type)[0] if switch_class.require_caches() and \ not options.caches: print "%s: Must be used with caches" % str(switch_class) sys.exit(1) if not switch_class.support_take_over(): print "%s: CPU switching not supported" % str(switch_class) sys.exit(1) repeat_switch_cpus = [switch_class(switched_out=True, \ cpu_id=(i)) for i in xrange(np)] for i in xrange(np): repeat_switch_cpus[i].system = testsys repeat_switch_cpus[i].workload = testsys.cpu[i].workload repeat_switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain if options.maxinsts: repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts if options.checker: repeat_switch_cpus[i].addCheckerCpu() testsys.repeat_switch_cpus = repeat_switch_cpus if cpu_class: repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i]) for i in xrange(np)] else: repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i]) for i in xrange(np)] if options.standard_switch: timing_cpus = [ TimingSimpleCPU(switched_out=True, cpu_id=(i)) for i in xrange(np) ] o3_cpus = [ DerivO3CPU(switched_out=True, cpu_id=(i)) for i in xrange(np) ] config_O3cpu(options, o3_cpus) for i in xrange(np): timing_cpus[i].system = testsys o3_cpus[i].system = testsys timing_cpus[i].workload = testsys.cpu[i].workload o3_cpus[i].workload = testsys.cpu[i].workload timing_cpus[i].clk_domain = testsys.cpu[i].clk_domain o3_cpus[i].clk_domain = testsys.cpu[i].clk_domain # if restoring, make atomic cpu simulate only a few instructions if options.checkpoint_restore != None: testsys.cpu[i].max_insts_any_thread = 1 # Fast forward to specified location if we are not restoring elif options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) # Fast forward to a simpoint (warning: time consuming) elif options.simpoint: if testsys.cpu[i].workload[0].simpoint == 0: fatal('simpoint not found') testsys.cpu[i].max_insts_any_thread = \ testsys.cpu[i].workload[0].simpoint # No distance specified, just switch else: testsys.cpu[i].max_insts_any_thread = 1 # warmup period if options.warmup_insts: timing_cpus[i].max_insts_any_thread = options.warmup_insts # simulation period if options.maxinsts: o3_cpus[i].max_insts_any_thread = options.maxinsts # attach the checker cpu if selected if options.checker: timing_cpus[i].addCheckerCpu() o3_cpus[i].addCheckerCpu() testsys.timing_cpus = timing_cpus testsys.o3_cpus = o3_cpus switch_cpu_list = [(testsys.cpu[i], timing_cpus[i]) for i in xrange(np)] switch_cpu_list1 = [(timing_cpus[i], o3_cpus[i]) for i in xrange(np)] # set the checkpoint in the cpu before m5.instantiate is called if options.take_checkpoints != None and \ (options.simpoint or options.at_instruction): offset = int(options.take_checkpoints) # Set an instruction break point if options.simpoint: for i in xrange(np): if testsys.cpu[i].workload[0].simpoint == 0: fatal('no simpoint for testsys.cpu[%d].workload[0]', i) checkpoint_inst = int( testsys.cpu[i].workload[0].simpoint) + offset testsys.cpu[i].max_insts_any_thread = checkpoint_inst # used for output below options.take_checkpoints = checkpoint_inst else: options.take_checkpoints = offset # Set all test cpus with the right number of instructions # for the upcoming simulation 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) m5.instantiate(checkpoint_dir) # Initialization is complete. If we're not in control of simulation # (that is, if we're a slave simulator acting as a component in another # 'master' simulator) then we're done here. The other simulator will # call simulate() directly. --initialize-only is used to indicate this. if options.initialize_only: return # Handle the max tick settings now that tick frequency was resolved # during system instantiation # NOTE: the maxtick variable here is in absolute ticks, so it must # include any simulated ticks before a checkpoint explicit_maxticks = 0 maxtick_from_abs = m5.MaxTick maxtick_from_rel = m5.MaxTick maxtick_from_maxtime = m5.MaxTick if options.abs_max_tick: maxtick_from_abs = options.abs_max_tick explicit_maxticks += 1 if options.rel_max_tick: maxtick_from_rel = options.rel_max_tick if options.checkpoint_restore: # NOTE: this may need to be updated if checkpoints ever store # the ticks per simulated second maxtick_from_rel += cpt_starttick if options.at_instruction or options.simpoint: warn("Relative max tick specified with --at-instruction or" \ " --simpoint\n These options don't specify the " \ "checkpoint start tick, so assuming\n you mean " \ "absolute max tick") explicit_maxticks += 1 if options.maxtime: maxtick_from_maxtime = m5.ticks.fromSeconds(options.maxtime) explicit_maxticks += 1 if explicit_maxticks > 1: warn("Specified multiple of --abs-max-tick, --rel-max-tick, --maxtime."\ " Using least") maxtick = min([maxtick_from_abs, maxtick_from_rel, maxtick_from_maxtime]) if options.checkpoint_restore != None and maxtick < cpt_starttick: fatal("Bad maxtick (%d) specified: " \ "Checkpoint starts starts from tick: %d", maxtick, cpt_starttick) if options.standard_switch or cpu_class: if options.standard_switch: print "Switch at instruction count:%s" % \ str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() elif cpu_class and options.fast_forward: print "Switch at instruction count:%s" % \ str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() else: print "Switch at curTick count:%s" % str(10000) exit_event = m5.simulate(10000) print "Switched CPUS @ tick %s" % (m5.curTick()) m5.switchCpus(testsys, switch_cpu_list) if options.standard_switch: print "Switch at instruction count:%d" % \ (testsys.timing_cpus[0].max_insts_any_thread) #warmup instruction count may have already been set if options.warmup_insts: exit_event = m5.simulate() else: exit_event = m5.simulate(options.standard_switch) print "Switching CPUS @ tick %s" % (m5.curTick()) print "Simulation ends instruction count:%d" % \ (testsys.o3_cpus[0].max_insts_any_thread) m5.switchCpus(testsys, switch_cpu_list1) # If we're taking and restoring checkpoints, use checkpoint_dir # 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 or options.take_simpoint_checkpoints) \ and options.checkpoint_restore: if m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.take_checkpoints != None: # Checkpoints being taken via the command line at <when> and at # subsequent periods of <period>. Checkpoint instructions # 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() print "**** REAL SIMULATION ****" # If checkpoints are being taken, then the checkpoint instruction # will occur in the benchmark code it self. if options.repeat_switch and maxtick > options.repeat_switch: exit_event = repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, options.repeat_switch) else: exit_event = benchCheckpoints(options, maxtick, cptdir) print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_event.getCause()) if options.checkpoint_at_end: m5.checkpoint(joinpath(cptdir, "cpt.%d")) if not m5.options.interactive: sys.exit(exit_event.getCode())
def run_test(root, switcher=None, freq=1000, verbose=False): """Test runner for CPU switcheroo tests. The switcheroo test runner is used to switch CPUs in a system that has been prepared for CPU switching. Such systems should have multiple CPUs when they are instantiated, but only one should be switched in. Such configurations can be created using the base_config.BaseFSSwitcheroo class. A CPU switcher object is used to control switching. The default switcher sequentially switches between all CPUs in a system, starting with the CPU that is currently switched in. Unlike most other test runners, this one automatically configures the memory mode of the system based on the first CPU the switcher reports. Keyword Arguments: switcher -- CPU switcher implementation. See Sequential for an example implementation. period -- Switching frequency in Hz. verbose -- Enable output at each switch (suppressed by default). """ if switcher == None: switcher = Sequential(root.system.cpu) current_cpu = switcher.first() system = root.system system.mem_mode = type(current_cpu).memory_mode() # Suppress "Entering event queue" messages since we get tons of them. # Worse yet, they include the timestamp, which makes them highly # variable and unsuitable for comparing as test outputs. if not verbose: _m5.core.setLogLevel(_m5.core.LogLevel.WARN) # instantiate configuration m5.instantiate() # Determine the switching period, this has to be done after # instantiating the system since the time base must be fixed. period = m5.ticks.fromSeconds(1.0 / freq) while True: exit_event = m5.simulate(period) exit_cause = exit_event.getCause() if exit_cause == "simulate() limit reached": next_cpu = switcher.next() if verbose: print("Switching CPUs...") print("Next CPU: %s" % type(next_cpu)) m5.drain() if current_cpu != next_cpu: m5.switchCpus(system, [ (current_cpu, next_cpu) ], verbose=verbose) else: print("Source CPU and destination CPU are the same," " skipping...") current_cpu = next_cpu elif exit_cause == "target called exit()" or \ exit_cause == "m5_exit instruction encountered": sys.exit(0) else: print("Test failed: Unknown exit cause: %s" % exit_cause) sys.exit(1)
def switchCpus(self, old, new): assert (new[0].switchedOut()) m5.switchCpus(self, zip(old, new))
def run(options, root, testsys, cpu_class): if options.checkpoint_dir: cptdir = options.checkpoint_dir elif m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.fast_forward and options.checkpoint_restore != None: fatal("Can't specify both --fast-forward and --checkpoint-restore") if options.standard_switch and not options.caches: fatal("Must specify --caches when using --standard-switch") if options.standard_switch and options.repeat_switch: fatal("Can't specify both --standard-switch and --repeat-switch") if options.repeat_switch and options.take_checkpoints: fatal("Can't specify both --repeat-switch and --take-checkpoints") np = options.num_cpus switch_cpus = None if options.prog_interval: for i in xrange(np): testsys[0].cpu[i].progress_interval = options.prog_interval testsys[1].cpu[i].progress_interval = options.prog_interval if options.maxinsts: for i in xrange(np): testsys[0].cpu[i].max_insts_any_thread = options.maxinsts testsys[1].cpu[i].max_insts_any_thread = options.maxinsts if cpu_class: switch_cpus01 = [ cpu_class(switched_out=True, cpu_id=(i)) for i in xrange(np) ] ncpuswitch = len(switch_cpus01) temp02 = [ cpu_class(switched_out=True, cpu_id=(i + ncpuswitch)) for i in xrange(np) ] switch_cpus = switch_cpus01 + temp02 for i in xrange(np): if options.fast_forward: testsys[0].cpu[i].max_insts_any_thread = int( options.fast_forward) switch_cpus[i].system = testsys[0] switch_cpus[i].workload = testsys[0].cpu[i].workload switch_cpus[i].clk_domain = testsys[0].cpu[i].clk_domain # simulation period if options.maxinsts: switch_cpus[i].max_insts_any_thread = options.maxinsts # Add checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() for i in xrange(np): if options.fast_forward: testsys[1].cpu[i].max_insts_any_thread = int( options.fast_forward) switch_cpus[i + ncpuswitch].system = testsys[1] switch_cpus[i + ncpuswitch].workload = testsys[1].cpu[i].workload switch_cpus[i + ncpuswitch].clk_domain = testsys[1].cpu[i].clk_domain # simulation period if options.maxinsts: switch_cpus[i + ncpuswitch].max_insts_any_thread = options.maxinsts # Add checker cpu if selected if options.checker: switch_cpus[i + ncpuswitch].addCheckerCpu() testsys[0].switch_cpus = switch_cpus01 testsys[1].switch_cpus = temp02 switch_cpu_list = [(testsys[0].cpu[i], switch_cpus[i]) for i in xrange(np)] switch_cpu_list_temp = [(testsys[1].cpu[i], switch_cpus[i + ncpuswitch]) for i in xrange(np)] switch_cpu_list = switch_cpu_list + switch_cpu_list_temp if options.repeat_switch: switch_class = getCPUClass(options.cpu_type)[0] if switch_class.require_caches() and \ not options.caches: print "%s: Must be used with caches" % str(switch_class) sys.exit(1) if not switch_class.support_take_over(): print "%s: CPU switching not supported" % str(switch_class) sys.exit(1) repeat_switch_cpus = [switch_class(switched_out=True, \ cpu_id=(i)) for i in xrange(np*2)] for i in xrange(np): repeat_switch_cpus[i].system = testsys[0] repeat_switch_cpus[i].workload = testsys[0].cpu[i].workload repeat_switch_cpus[i].clk_domain = testsys[0].cpu[i].clk_domain if options.maxinsts: repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts if options.checker: repeat_switch_cpus[i].addCheckerCpu() for i in xrange(np): repeat_switch_cpus[i + ncpuswitch].system = testsys[1] repeat_switch_cpus[ i + ncpuswitch].workload = testsys[1].cpu[i].workload repeat_switch_cpus[ i + ncpuswitch].clk_domain = testsys[1].cpu[i].clk_domain if options.maxinsts: repeat_switch_cpus[ i + ncpuswitch].max_insts_any_thread = options.maxinsts if options.checker: repeat_switch_cpus[i + ncpuswitch].addCheckerCpu() testsys[0].repeat_switch_cpus = [] testsys[1].repeat_switch_cpus = [] for j in xrange(np * 2): if j < np: testsys[0].repeat_switch_cpus.append(repeat_switch_cpus[j]) else: testsys[1].repeat_switch_cpus.append(repeat_switch_cpus[j]) if cpu_class: repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i]) for i in xrange(np * 2)] else: repeat_switch_cpu_list_1 = [ (testsys[0].cpu[i], repeat_switch_cpus[i]) for i in xrange(np) ] repeat_switch_cpu_list_2 = [(testsys[1].cpu[i + ncpuswitch], repeat_switch_cpus[i + ncpuswitch]) for i in xrange(np)] repeat_switch_cpu_list = repeat_switch_cpu_list_1 + repeat_switch_cpu_list_2 if options.standard_switch: switch_cpus = [ TimingSimpleCPU(switched_out=True, cpu_id=(i)) for i in xrange(np * 2) ] switch_cpus_1 = [ DerivO3CPU(switched_out=True, cpu_id=(i)) for i in xrange(np * 2) ] for i in xrange(np * 2): if i < np: switch_cpus[i].system = testsys[0] switch_cpus_1[i].system = testsys[0] switch_cpus[i].workload = testsys[0].cpu[i].workload switch_cpus_1[i].workload = testsys[0].cpu[i].workload switch_cpus[i].clk_domain = testsys[0].cpu[i].clk_domain switch_cpus_1[i].clk_domain = testsys[0].cpu[i].clk_domain else: switch_cpus[i].system = testsys[1] switch_cpus_1[i].system = testsys[1] switch_cpus[i].workload = testsys[1].cpu[i].workload switch_cpus_1[i].workload = testsys[1].cpu[i].workload switch_cpus[i].clk_domain = testsys[1].cpu[i].clk_domain switch_cpus_1[i].clk_domain = testsys[1].cpu[i].clk_domain # if restoring, make atomic cpu simulate only a few instructions if options.checkpoint_restore != None: if i < np: testsys[0].cpu[i].max_insts_any_thread = 1 else: testsys[1].cpu[i].max_insts_any_thread = 1 # Fast forward to specified location if we are not restoring elif options.fast_forward: if i < np: testsys[0].cpu[i].max_insts_any_thread = int( options.fast_forward) else: testsys[1].cpu[i].max_insts_any_thread = int( options.fast_forward) # Fast forward to a simpoint (warning: time consuming) elif options.simpoint: if i < np: if testsys[0].cpu[i].workload[0].simpoint == 0: fatal('simpoint not found') testsys[0].cpu[i].max_insts_any_thread = \ testsys[0].cpu[i].workload[0].simpoint else: if testsys[1].cpu[i].workload[0].simpoint == 0: fatal('simpoint not found') testsys[1].cpu[i].max_insts_any_thread = \ testsys[1].cpu[i].workload[0].simpoint # No distance specified, just switch else: if i < np: testsys[0].cpu[i].max_insts_any_thread = 1 else: testsys[1].cpu[i].max_insts_any_thread = 1 # warmup period if options.warmup_insts: switch_cpus[i].max_insts_any_thread = options.warmup_insts # simulation period if options.maxinsts: switch_cpus_1[i].max_insts_any_thread = options.maxinsts # attach the checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() switch_cpus_1[i].addCheckerCpu() testsys[0].switch_cpus = switch_cpus testsys[1].switch_cpus = switch_cpus testsys[0].switch_cpus_1 = switch_cpus_1 testsys[1].switch_cpus_1 = switch_cpus_1 switch_cpu_list_1 = [(testsys[0].cpu[i], switch_cpus[i]) for i in xrange(np)] switch_cpu_list_2 = [(testsys[1].cpu[i], switch_cpus[i]) for i in xrange(np)] switch_cpu_list = switch_cpu_list_1 + switch_cpu_list_2 switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in switch_cpu_list1] for i in xrange(np * 2): if i < np: switch_cpu_list1_1 = [switch_cpu_list1[i]] else: switch_cpu_list1_2 = [switch_cpu_list1[i]] # set the checkpoint in the cpu before m5.instantiate is called if options.take_checkpoints != None and \ (options.simpoint or options.at_instruction): offset = int(options.take_checkpoints) # Set an instruction break point if options.simpoint: for i in xrange(np * 2): if i < np: if testsys.cpu[i].workload[0].simpoint == 0: fatal('no simpoint for testsys.cpu[%d].workload[0]', i) checkpoint_inst = int( testsys[0].cpu[i].workload[0].simpoint) + offset testsys[0].cpu[i].max_insts_any_thread = checkpoint_inst # used for output below options.take_checkpoints = checkpoint_inst else: if testsys[1].cpu[i].workload[0].simpoint == 0: fatal('no simpoint for testsys.cpu[%d].workload[0]', i) checkpoint_inst = int( testsys[1].cpu[i].workload[0].simpoint) + offset testsys[1].cpu[i].max_insts_any_thread = checkpoint_inst # used for output below options.take_checkpoints = checkpoint_inst else: options.take_checkpoints = offset # Set all test cpus with the right number of instructions # for the upcoming simulation for i in xrange(np * 2): if i < np: testsys[0].cpu[i].max_insts_any_thread = offset else: testsys[1].cpu[i].max_insts_any_thread = offset checkpoint_dir = None checkpoint_dir1 = None if options.checkpoint_restore: cpt_starttick, checkpoint_dir = findCptDir(options, cptdir, testsys[0]) cpt_starttick1, checkpoint_dir1 = findCptDir(options, cptdir, testsys[1]) m5.instantiate(checkpoint_dir) m5.instantiate(checkpoint_dir1) # Handle the max tick settings now that tick frequency was resolved # during system instantiation # NOTE: the maxtick variable here is in absolute ticks, so it must # include any simulated ticks before a checkpoint explicit_maxticks = 0 maxtick_from_abs = m5.MaxTick maxtick_from_rel = m5.MaxTick maxtick_from_maxtime = m5.MaxTick explicit_maxticks1 = 0 maxtick_from_abs1 = m5.MaxTick maxtick_from_rel1 = m5.MaxTick maxtick_from_maxtime1 = m5.MaxTick if options.abs_max_tick: maxtick_from_abs = options.abs_max_tick explicit_maxticks += 1 maxtick_from_abs1 = options.abs_max_tick explicit_maxticks1 += 1 if options.rel_max_tick: maxtick_from_rel = options.rel_max_tick maxtick_from_rel1 = options.rel_max_tick if options.checkpoint_restore: # NOTE: this may need to be updated if checkpoints ever store # the ticks per simulated second maxtick_from_rel += cpt_starttick maxtick_from_rel1 += cpt_starttick1 if options.at_instruction or options.simpoint: warn("Relative max tick specified with --at-instruction or" \ " --simpoint\n These options don't specify the " \ "checkpoint start tick, so assuming\n you mean " \ "absolute max tick") explicit_maxticks += 1 explicit_maxticks1 += 1 if options.maxtime: maxtick_from_maxtime = m5.ticks.fromSeconds(options.maxtime) explicit_maxticks += 1 maxtick_from_maxtime1 = m5.ticks.fromSeconds(options.maxtime) explicit_maxticks1 += 1 if explicit_maxticks > 1: warn("Specified multiple of --abs-max-tick, --rel-max-tick, --maxtime."\ " Using least") if explicit_maxticks1 > 1: warn("Specified multiple of --abs-max-tick, --rel-max-tick, --maxtime."\ " Using least") maxtick = min([maxtick_from_abs, maxtick_from_rel, maxtick_from_maxtime]) maxtick1 = min( [maxtick_from_abs1, maxtick_from_rel1, maxtick_from_maxtime1]) if options.checkpoint_restore != None and maxtick < cpt_starttick: fatal("Bad maxtick (%d) specified: " \ "Checkpoint starts starts from tick: %d", maxtick, cpt_starttick) if options.checkpoint_restore != None and maxtick1 < cpt_starttick1: fatal("Bad maxtick (%d) specified: " \ "Checkpoint starts starts from tick: %d", maxtick1, cpt_starttick1) if options.standard_switch or cpu_class: if options.standard_switch: print "Switch at instruction count:%s" % \ str(testsys[0].cpu[0].max_insts_any_thread) print "Switch at instruction count:%s" % \ str(testsys[1].cpu[0].max_insts_any_thread) exit_event = m5.simulate() elif cpu_class and options.fast_forward: print "Switch at instruction count:%s" % \ str(testsys[0].cpu[0].max_insts_any_thread) print "Switch at instruction count:%s" % \ str(testsys[1].cpu[0].max_insts_any_thread) exit_event = m5.simulate() else: print "Switch at curTick count:%s" % str(10000) exit_event = m5.simulate(10000) print "Switched CPUS @ tick %s" % (m5.curTick()) m5.switchCpus(testsys[0], switch_cpu_list_1) m5.switchCpus(testsys[1], switch_cpu_list_2) if options.standard_switch: print "Switch at instruction count:%d" % \ (testsys[0].switch_cpus[0].max_insts_any_thread) print "Switch at instruction count:%d" % \ (testsys[1].switch_cpus[0].max_insts_any_thread) #warmup instruction count may have already been set if options.warmup_insts: exit_event = m5.simulate() else: exit_event = m5.simulate(options.standard_switch) print "Switching CPUS @ tick %s" % (m5.curTick()) print "Simulation ends instruction count:%d" % \ (testsys[0].switch_cpus_1[0].max_insts_any_thread) print "Simulation ends instruction count:%d" % \ (testsys[1].switch_cpus_1[0].max_insts_any_thread) m5.switchCpus(testsys[0], switch_cpu_list1_1) m5.switchCpus(testsys[1], switch_cpu_list1_2) # If we're taking and restoring checkpoints, use checkpoint_dir # 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 m5.options.outdir: cptdir = m5.options.outdir cptdir1 = m5.options.outdir else: cptdir = getcwd() cptdir1 = getcwd() if options.take_checkpoints != None: # Checkpoints being taken via the command line at <when> and at # subsequent periods of <period>. Checkpoint instructions # received from the benchmark running are ignored and skipped in # favor of command line checkpoint instructions. exit_event = scriptCheckpoints(options, maxtick, cptdir) exit_event1 = scriptCheckpoints(options, maxtick1, cptdir1) else: if options.fast_forward: m5.stats.reset() print "**** REAL SIMULATION ****" # If checkpoints are being taken, then the checkpoint instruction # will occur in the benchmark code it self. if options.repeat_switch and maxtick > options.repeat_switch: exit_event = repeatSwitch(testsys[0], repeat_switch_cpu_list_1, maxtick, options.repeat_switch) else: exit_event = benchCheckpoints(options, maxtick, cptdir) if options.repeat_switch and maxtick1 > options.repeat_switch: exit_event1 = repeatSwitch(testsys[1], repeat_switch_cpu_list_2, maxtick1, options.repeat_switch) else: exit_event = benchCheckpoints(options, maxtick, cptdir) exit_event1 = benchCheckpoints(options, maxtick1, cptdir1) print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_event.getCause()) if options.checkpoint_at_end: m5.checkpoint(joinpath(cptdir, "cpt.%d")) m5.checkpoint(joinpath(cptdir1, "cpt.%d")) if not m5.options.interactive: sys.exit(exit_event.getCode()) sys.exit(exit_event1.getCode())
def run(options, root, testsys, cpu_class): if options.maxtick: maxtick = options.maxtick elif options.maxtime: simtime = m5.ticks.seconds(simtime) print "simulating for: ", simtime maxtick = simtime else: maxtick = m5.MaxTick if options.checkpoint_dir: cptdir = options.checkpoint_dir elif m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.fast_forward and options.checkpoint_restore != None: fatal("Can't specify both --fast-forward and --checkpoint-restore") if options.standard_switch and not options.caches: fatal("Must specify --caches when using --standard-switch") np = options.num_cpus max_checkpoints = options.max_checkpoints switch_cpus = None if options.prog_interval: for i in xrange(np): testsys.cpu[i].progress_interval = options.prog_interval if options.maxinsts: for i in xrange(np): testsys.cpu[i].max_insts_any_thread = options.maxinsts if cpu_class: switch_cpus = [ cpu_class(defer_registration=True, cpu_id=(np + i)) for i in xrange(np) ] for i in xrange(np): if options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) switch_cpus[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[0].clock # simulation period if options.maxinsts: switch_cpus[i].max_insts_any_thread = options.maxinsts # Add checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() testsys.switch_cpus = switch_cpus switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] if options.standard_switch: if not options.caches: # O3 CPU must have a cache to work. print "O3 CPU must be used with caches" sys.exit(1) switch_cpus = [ TimingSimpleCPU(defer_registration=True, cpu_id=(np + i)) for i in xrange(np) ] switch_cpus_1 = [ DerivO3CPU(defer_registration=True, cpu_id=(2 * np + i)) for i in xrange(np) ] for i in xrange(np): switch_cpus[i].system = testsys switch_cpus_1[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus_1[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[0].clock switch_cpus_1[i].clock = testsys.cpu[0].clock # if restoring, make atomic cpu simulate only a few instructions if options.checkpoint_restore != None: testsys.cpu[i].max_insts_any_thread = 1 # Fast forward to specified location if we are not restoring elif options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) # Fast forward to a simpoint (warning: time consuming) elif options.simpoint: if testsys.cpu[i].workload[0].simpoint == 0: fatal('simpoint not found') testsys.cpu[i].max_insts_any_thread = \ testsys.cpu[i].workload[0].simpoint # No distance specified, just switch else: testsys.cpu[i].max_insts_any_thread = 1 # warmup period if options.warmup_insts: switch_cpus[i].max_insts_any_thread = options.warmup_insts # simulation period if options.maxinsts: switch_cpus_1[i].max_insts_any_thread = options.maxinsts # attach the checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() switch_cpus_1[i].addCheckerCpu() testsys.switch_cpus = switch_cpus testsys.switch_cpus_1 = switch_cpus_1 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)] # set the checkpoint in the cpu before m5.instantiate is called if options.take_checkpoints != None and \ (options.simpoint or options.at_instruction): offset = int(options.take_checkpoints) # Set an instruction break point if options.simpoint: for i in xrange(np): if testsys.cpu[i].workload[0].simpoint == 0: fatal('no simpoint for testsys.cpu[%d].workload[0]', i) checkpoint_inst = int( testsys.cpu[i].workload[0].simpoint) + offset testsys.cpu[i].max_insts_any_thread = checkpoint_inst # used for output below options.take_checkpoints = checkpoint_inst else: options.take_checkpoints = offset # Set all test cpus with the right number of instructions # for the upcoming simulation for i in xrange(np): testsys.cpu[i].max_insts_any_thread = offset checkpoint_dir = None if options.checkpoint_restore != None: from os.path import isdir, exists from os import listdir import re if not isdir(cptdir): fatal("checkpoint dir %s does not exist!", cptdir) if options.at_instruction or options.simpoint: inst = options.checkpoint_restore if options.simpoint: # assume workload 0 has the simpoint if testsys.cpu[0].workload[0].simpoint == 0: fatal('Unable to find simpoint') inst += int(testsys.cpu[0].workload[0].simpoint) checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst)) if not exists(checkpoint_dir): fatal("Unable to find checkpoint directory %s", checkpoint_dir) else: dirs = listdir(cptdir) expr = re.compile('cpt\.([0-9]*)') cpts = [] for dir in dirs: match = expr.match(dir) if match: cpts.append(match.group(1)) cpts.sort(lambda a, b: cmp(long(a), long(b))) cpt_num = options.checkpoint_restore if cpt_num > len(cpts): fatal('Checkpoint %d not found', cpt_num) ## Adjust max tick based on our starting tick maxtick = maxtick - int(cpts[cpt_num - 1]) checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1]) m5.instantiate(checkpoint_dir) if options.standard_switch or cpu_class: if options.standard_switch: print "Switch at instruction count:%s" % \ str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() elif cpu_class and options.fast_forward: print "Switch at instruction count:%s" % \ str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() else: print "Switch at curTick count:%s" % str(10000) exit_event = m5.simulate(10000) print "Switched CPUS @ tick %s" % (m5.curTick()) # when you change to Timing (or Atomic), you halt the system # given as argument. When you are finished with the system # changes (including switchCpus), you must resume the system # manually. You DON'T need to resume after just switching # CPUs if you haven't changed anything on the system level. m5.changeToTiming(testsys) m5.switchCpus(switch_cpu_list) m5.resume(testsys) if options.standard_switch: print "Switch at instruction count:%d" % \ (testsys.switch_cpus[0].max_insts_any_thread) #warmup instruction count may have already been set if options.warmup_insts: exit_event = m5.simulate() else: exit_event = m5.simulate(options.warmup) print "Switching CPUS @ tick %s" % (m5.curTick()) print "Simulation ends instruction count:%d" % \ (testsys.switch_cpus_1[0].max_insts_any_thread) m5.drain(testsys) m5.switchCpus(switch_cpu_list1) m5.resume(testsys) num_checkpoints = 0 exit_cause = '' # If we're taking and restoring checkpoints, use checkpoint_dir # 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 m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() # Checkpoints being taken via the command line at <when> and at # subsequent periods of <period>. Checkpoint instructions # received from the benchmark running are ignored and skipped in # favor of command line checkpoint instructions. if options.take_checkpoints != None: if options.at_instruction or options.simpoint: checkpoint_inst = int(options.take_checkpoints) # maintain correct offset if we restored from some instruction if options.checkpoint_restore != None: checkpoint_inst += options.checkpoint_restore print "Creating checkpoint at inst:%d" % (checkpoint_inst) exit_event = m5.simulate() print "exit cause = %s" % (exit_event.getCause()) # skip checkpoint instructions should they exist while exit_event.getCause() == "checkpoint": exit_event = m5.simulate() if exit_event.getCause() == \ "a thread reached the max instruction count": m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % \ (options.bench, checkpoint_inst))) print "Checkpoint written." num_checkpoints += 1 if exit_event.getCause() == "user interrupt received": exit_cause = exit_event.getCause() else: when, period = options.take_checkpoints.split(",", 1) when = int(when) period = int(period) exit_event = m5.simulate(when) while exit_event.getCause() == "checkpoint": exit_event = m5.simulate(when - m5.curTick()) if exit_event.getCause() == "simulate() limit reached": m5.checkpoint(joinpath(cptdir, "cpt.%d")) num_checkpoints += 1 sim_ticks = when exit_cause = "maximum %d checkpoints dropped" % max_checkpoints while num_checkpoints < max_checkpoints and \ exit_event.getCause() == "simulate() limit reached": if (sim_ticks + period) > maxtick: exit_event = m5.simulate(maxtick - sim_ticks) exit_cause = exit_event.getCause() break else: exit_event = m5.simulate(period) sim_ticks += period while exit_event.getCause() == "checkpoint": exit_event = m5.simulate(sim_ticks - m5.curTick()) if exit_event.getCause() == "simulate() limit reached": m5.checkpoint(joinpath(cptdir, "cpt.%d")) num_checkpoints += 1 if exit_event.getCause() != "simulate() limit reached": exit_cause = exit_event.getCause() else: # no checkpoints being taken via this script if options.fast_forward: m5.stats.reset() print "**** REAL SIMULATION ****" exit_event = m5.simulate(maxtick) while exit_event.getCause() == "checkpoint": m5.checkpoint(joinpath(cptdir, "cpt.%d")) num_checkpoints += 1 if num_checkpoints == max_checkpoints: exit_cause = "maximum %d checkpoints dropped" % max_checkpoints break exit_event = m5.simulate(maxtick - m5.curTick()) exit_cause = exit_event.getCause() if exit_cause == '': exit_cause = exit_event.getCause() print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause) if options.checkpoint_at_end: m5.checkpoint(joinpath(cptdir, "cpt.%d"))
if options.checkpoint_num >= len(simpoints): fatal("Invalid checkpoint number %d. Max possible %d", options.checkpoint_num, len(simple_end_points)) point_inst = simpoints[options.checkpoint_num]; cpu.simpoint_start_insts = [ options.simpoint_interval ] ckpt_dir = os.path.join(options.checkpoint_dir, "simpoint.ckpt.inst.%d" % point_inst) m5.instantiate(ckpt_dir) if options.simpoint_mode == "none" or options.simpoint_mode == "checkpoint" or options.simpoint_mode == "generate": exit_event = m5.simulate() exit_cause = exit_event.getCause() elif options.simpoint_mode == "fastfwd": exit_event = m5.simulate() exit_cause = exit_event.getCause() while exit_cause == "simpoint starting point found": m5.switchCpus(system, switch_cpu_list) tmp_cpu_list = [] for old_cpu, new_cpu in switch_cpu_list: tmp_cpu_list.append((new_cpu, old_cpu)) switch_cpu_list = tmp_cpu_list m5.stats.reset() exit_event = m5.simulate() exit_cause = exit_event.getCause() if switch_cpu_list[0][0].type == 'DerivO3CPU': m5.stats.dump() elif options.simpoint_mode == "checkpoint_gen": exit_event = m5.simulate() exit_cause = exit_event.getCause() checkpoint_points = simple_end_points[:]
def run(options, root, testsys, cpu_class): if options.checkpoint_dir: cptdir = options.checkpoint_dir elif m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.fast_forward and options.checkpoint_restore != None: fatal("Can't specify both --fast-forward and --checkpoint-restore") if options.standard_switch and not options.caches: fatal("Must specify --caches when using --standard-switch") if options.standard_switch and options.repeat_switch: fatal("Can't specify both --standard-switch and --repeat-switch") if options.repeat_switch and options.take_checkpoints: fatal("Can't specify both --repeat-switch and --take-checkpoints") np = options.num_cpus switch_cpus = None if options.prog_interval: for i in xrange(np): testsys.cpu[i].progress_interval = options.prog_interval if options.maxinsts: for i in xrange(np): testsys.cpu[i].max_insts_any_thread = options.maxinsts if cpu_class: switch_cpus = [cpu_class(switched_out=True, cpu_id=(i)) for i in xrange(np)] for i in xrange(np): if options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) switch_cpus[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain switch_cpus[i].progress_interval = testsys.cpu[i].progress_interval # simulation period if options.maxinsts: switch_cpus[i].max_insts_any_thread = options.maxinsts # Add checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() testsys.switch_cpus = switch_cpus switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] if options.repeat_switch: switch_class = getCPUClass(options.cpu_type)[0] if switch_class.require_caches() and \ not options.caches: print "%s: Must be used with caches" % str(switch_class) sys.exit(1) if not switch_class.support_take_over(): print "%s: CPU switching not supported" % str(switch_class) sys.exit(1) repeat_switch_cpus = [switch_class(switched_out=True, \ cpu_id=(i)) for i in xrange(np)] for i in xrange(np): repeat_switch_cpus[i].system = testsys repeat_switch_cpus[i].workload = testsys.cpu[i].workload repeat_switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain if options.maxinsts: repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts if options.checker: repeat_switch_cpus[i].addCheckerCpu() testsys.repeat_switch_cpus = repeat_switch_cpus if cpu_class: repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i]) for i in xrange(np)] else: repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i]) for i in xrange(np)] if options.standard_switch: switch_cpus = [TimingSimpleCPU(switched_out=True, cpu_id=(i)) for i in xrange(np)] switch_cpus_1 = [DerivO3CPU(switched_out=True, cpu_id=(i)) for i in xrange(np)] for i in xrange(np): switch_cpus[i].system = testsys switch_cpus_1[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus_1[i].workload = testsys.cpu[i].workload switch_cpus[i].clk_domain = testsys.cpu[i].clk_domain switch_cpus_1[i].clk_domain = testsys.cpu[i].clk_domain # if restoring, make atomic cpu simulate only a few instructions if options.checkpoint_restore != None: testsys.cpu[i].max_insts_any_thread = 1 # Fast forward to specified location if we are not restoring elif options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) # Fast forward to a simpoint (warning: time consuming) elif options.simpoint: if testsys.cpu[i].workload[0].simpoint == 0: fatal('simpoint not found') testsys.cpu[i].max_insts_any_thread = \ testsys.cpu[i].workload[0].simpoint # No distance specified, just switch else: testsys.cpu[i].max_insts_any_thread = 1 # warmup period if options.warmup_insts: switch_cpus[i].max_insts_any_thread = options.warmup_insts # simulation period if options.maxinsts: switch_cpus_1[i].max_insts_any_thread = options.maxinsts # attach the checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() switch_cpus_1[i].addCheckerCpu() testsys.switch_cpus = switch_cpus testsys.switch_cpus_1 = switch_cpus_1 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)] # set the checkpoint in the cpu before m5.instantiate is called if options.take_checkpoints != None and \ (options.simpoint or options.at_instruction): offset = int(options.take_checkpoints) # Set an instruction break point if options.simpoint: for i in xrange(np): if testsys.cpu[i].workload[0].simpoint == 0: fatal('no simpoint for testsys.cpu[%d].workload[0]', i) checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset testsys.cpu[i].max_insts_any_thread = checkpoint_inst # used for output below options.take_checkpoints = checkpoint_inst else: options.take_checkpoints = offset # Set all test cpus with the right number of instructions # for the upcoming simulation 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) m5.instantiate(checkpoint_dir) # Initialization is complete. If we're not in control of simulation # (that is, if we're a slave simulator acting as a component in another # 'master' simulator) then we're done here. The other simulator will # call simulate() directly. --initialize-only is used to indicate this. if options.initialize_only: return # Handle the max tick settings now that tick frequency was resolved # during system instantiation # NOTE: the maxtick variable here is in absolute ticks, so it must # include any simulated ticks before a checkpoint explicit_maxticks = 0 maxtick_from_abs = m5.MaxTick maxtick_from_rel = m5.MaxTick maxtick_from_maxtime = m5.MaxTick if options.abs_max_tick: maxtick_from_abs = options.abs_max_tick explicit_maxticks += 1 if options.rel_max_tick: maxtick_from_rel = options.rel_max_tick if options.checkpoint_restore: # NOTE: this may need to be updated if checkpoints ever store # the ticks per simulated second maxtick_from_rel += cpt_starttick if options.at_instruction or options.simpoint: warn("Relative max tick specified with --at-instruction or" \ " --simpoint\n These options don't specify the " \ "checkpoint start tick, so assuming\n you mean " \ "absolute max tick") explicit_maxticks += 1 if options.maxtime: maxtick_from_maxtime = m5.ticks.fromSeconds(options.maxtime) explicit_maxticks += 1 if explicit_maxticks > 1: warn("Specified multiple of --abs-max-tick, --rel-max-tick, --maxtime."\ " Using least") maxtick = min([maxtick_from_abs, maxtick_from_rel, maxtick_from_maxtime]) if options.checkpoint_restore != None and maxtick < cpt_starttick: fatal("Bad maxtick (%d) specified: " \ "Checkpoint starts starts from tick: %d", maxtick, cpt_starttick) if options.standard_switch or cpu_class: if options.standard_switch: print "Switch at instruction count:%s" % \ str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() elif cpu_class and options.fast_forward: print "Switch at instruction count:%s" % \ str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() else: print "Switch at curTick count:%s" % str(10000) exit_event = m5.simulate(10000) print "Switched CPUS @ tick %s" % (m5.curTick()) m5.switchCpus(testsys, switch_cpu_list) if options.standard_switch: print "Switch at instruction count:%d" % \ (testsys.switch_cpus[0].max_insts_any_thread) #warmup instruction count may have already been set if options.warmup_insts: exit_event = m5.simulate() else: exit_event = m5.simulate(options.standard_switch) print "Switching CPUS @ tick %s" % (m5.curTick()) print "Simulation ends instruction count:%d" % \ (testsys.switch_cpus_1[0].max_insts_any_thread) m5.switchCpus(testsys, switch_cpu_list1) # If we're taking and restoring checkpoints, use checkpoint_dir # 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 or options.take_simpoint_checkpoints) \ and options.checkpoint_restore: if m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.take_checkpoints != None : # Checkpoints being taken via the command line at <when> and at # subsequent periods of <period>. Checkpoint instructions # 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() print "**** REAL SIMULATION ****" # If checkpoints are being taken, then the checkpoint instruction # will occur in the benchmark code it self. if options.repeat_switch and maxtick > options.repeat_switch: exit_event = repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, options.repeat_switch) else: exit_event = benchCheckpoints(options, maxtick, cptdir) print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_event.getCause()) if options.checkpoint_at_end: m5.checkpoint(joinpath(cptdir, "cpt.%d")) if not m5.options.interactive: sys.exit(exit_event.getCode())
def run_test(root, switcher=None, freq=1000, verbose=False): """Test runner for CPU switcheroo tests. The switcheroo test runner is used to switch CPUs in a system that has been prepared for CPU switching. Such systems should have multiple CPUs when they are instantiated, but only one should be switched in. Such configurations can be created using the base_config.BaseFSSwitcheroo class. A CPU switcher object is used to control switching. The default switcher sequentially switches between all CPUs in a system, starting with the CPU that is currently switched in. Unlike most other test runners, this one automatically configures the memory mode of the system based on the first CPU the switcher reports. Keyword Arguments: switcher -- CPU switcher implementation. See Sequential for an example implementation. period -- Switching frequency in Hz. verbose -- Enable output at each switch (suppressed by default). """ if switcher == None: switcher = Sequential(root.system.cpu) current_cpu = switcher.first() system = root.system system.mem_mode = type(current_cpu).memory_mode() # Suppress "Entering event queue" messages since we get tons of them. # Worse yet, they include the timestamp, which makes them highly # variable and unsuitable for comparing as test outputs. if not verbose: _m5.core.setLogLevel(_m5.core.LogLevel.WARN) # instantiate configuration m5.instantiate() # Determine the switching period, this has to be done after # instantiating the system since the time base must be fixed. period = m5.ticks.fromSeconds(1.0 / freq) while True: exit_event = m5.simulate(period) exit_cause = exit_event.getCause() if exit_cause == "simulate() limit reached": next_cpu = switcher.next() if verbose: print "Switching CPUs..." print "Next CPU: %s" % type(next_cpu) m5.drain() if current_cpu != next_cpu: m5.switchCpus(system, [(current_cpu, next_cpu)], verbose=verbose) else: print "Source CPU and destination CPU are the same, skipping..." current_cpu = next_cpu elif exit_cause == "target called exit()" or \ exit_cause == "m5_exit instruction encountered": sys.exit(0) else: print "Test failed: Unknown exit cause: %s" % exit_cause sys.exit(1)
def bigLITTLESwitch(testsys, bigLITTLE_switch_cpu_list, maxtick, switch_freq, num_cpu): print "starting big.LITTLE switch loop" #Define core types and frequencies for each core (Initialized to the big core and max freq.) core_type = ['big_core'] * num_cpu cur_freq = [2100] * num_cpu #Define statistics field for each core and each freq. big_freq_list = [[800, 0], [900, 0], [1000, 0], [1100, 0], [1200, 0], [1300, 0], [1400, 0], [1500, 0], [1600, 0], [1700, 0], [1800, 0], [1900, 0], [2000, 0], [2100, 0]] * num_cpu Llittle_freq_list = [[400, 0], [500, 0], [600, 0], [700, 0], [800, 0], [900, 0], [1000, 0], [1100, 0], [1200, 0], [1300, 0], [1400, 0], [1500, 0]] * num_cpu #Define max. and min. freq for each core type big_min_freq = 800 big_max_freq = 2100 little_min_freq = 400 little_max_freq = 1500 #Define Switching threshold freq_up_thresh = 0.95 freq_down_thresh = 0.85 #For estimating utilization in big core big_past_total_cycles = [0] * num_cpu big_past_idle_cycles = [0] * num_cpu #For estimating utilization in LITTLE core little_past_total_cycles = [0] * num_cpu little_past_idle_cycles = [0] * num_cpu #To get utilization value current_total_cycles = 0 current_idle_cycles = 0 m5.setCpuIndex(bigLITTLE_switch_cpu_list) while True: #Simulate target architecture during 'switch_freq' #print "Running big.LITTLE cluster" exit_event = m5.simulate(switch_freq) exit_cause = exit_event.getCause() #If the simulation is end with other reason, print simulation cycles and exit the simulation loop if exit_cause != "simulate() limit reached": for cpu_idx in range(num_cpu): print "big Core %d DVFS Stat." % (cpu_idx) for idx in range(14): print "%dMHz: %d" % (big_freq_list[idx + 14 * cpu_idx][0], big_freq_list[idx + 14 * cpu_idx][1]) print "LITTLE Core %d DVFS Stat." % (cpu_idx) for idx in range(12): print "%dMHz: %d" % ( Llittle_freq_list[idx + 12 * cpu_idx][0], Llittle_freq_list[idx + 12 * cpu_idx][1]) return exit_event #To access for loop index core_index = 0 for old_cpu, new_cpu in bigLITTLE_switch_cpu_list: #DVFS Handling if core_type[core_index] == 'big_core': #Get busy and idle cycles during past quantum current_total_cycles = m5.getCurBusyCycles(0, core_index) current_idle_cycles = m5.getCurIdleCycles(0, core_index) #Calculate quantum cycles quantum_total_cycles = current_total_cycles - big_past_total_cycles[ core_index] quantum_idle_cycles = current_idle_cycles - big_past_idle_cycles[ core_index] big_past_total_cycles[core_index] = current_total_cycles big_past_idle_cycles[core_index] = current_idle_cycles else: current_total_cycles = m5.getCurBusyCycles(1, core_index) current_idle_cycles = m5.getCurBusyCycles( 1, core_index) - m5.getCurIdleCycles(1, core_index) #Calculate quantum cycles quantum_total_cycles = current_total_cycles - little_past_total_cycles[ core_index] quantum_idle_cycles = current_idle_cycles - little_past_idle_cycles[ core_index] little_past_total_cycles[core_index] = current_total_cycles little_past_idle_cycles[core_index] = current_idle_cycles #print "%lf, %lf" & (old_cpu.idleCycles, old_cpu.tickCycles) #print "Core %d Type: %s, quantum_total_cycles: %lf, quantum_idle_cycles: %lf" % (core_index, core_type[core_index], quantum_total_cycles, quantum_idle_cycles) #Calculate core utilization if quantum_total_cycles != 0: core_utilization = (quantum_total_cycles - quantum_idle_cycles) / quantum_total_cycles #Current Core is big core (change) if core_type[core_index] == 'big_core': #Cycle Statistics for idx in range(14): if big_freq_list[14 * core_index + idx][0] == cur_freq[core_index]: big_freq_list[14 * core_index + idx][1] += quantum_total_cycles #Frequency up-scaling if core_utilization >= freq_up_thresh and cur_freq[ core_index] != big_max_freq: cur_freq[core_index] += 100 #Frequency down-scaling elif core_utilization < freq_down_thresh and cur_freq[ core_index] != big_min_freq: cur_freq[core_index] -= 100 #Core switching elif core_utilization < freq_down_thresh and cur_freq[ core_index] == big_min_freq: #print "Core %d Switch: big --> LITTLE" % (core_index) switching_cpu_list = [] switching_cpu_index = 0 for old_cpu, new_cpu in bigLITTLE_switch_cpu_list: if switching_cpu_index == core_index: switching_cpu_list.append((old_cpu, new_cpu)) m5.switchCpus(testsys, switching_cpu_list) core_type[core_index] = 'LITTLE_core' cur_freq[core_index] = little_max_freq bigLITTLE_switch_cpu_list[core_index] = (new_cpu, old_cpu) switching_cpu_index += 1 #Current Core is LITTLE core (change) if core_type[core_index] == 'LITTLE_core': #Cycle Statistics for idx in range(12): if Llittle_freq_list[12 * core_index + idx][0] == cur_freq[core_index]: Llittle_freq_list[12 * core_index + idx][1] += quantum_total_cycles #Frequency up-scaling if core_utilization >= freq_up_thresh and cur_freq[ core_index] != little_max_freq: cur_freq[core_index] += 100 #Frequency down-scaling elif core_utilization < freq_down_thresh and cur_freq[ core_index] != little_min_freq: cur_freq[core_index] -= 100 #Core switching elif core_utilization >= freq_up_thresh and cur_freq[ core_index] == little_max_freq: #print "Core Switch: LITTLE --> big" switching_cpu_list = [] switching_cpu_index = 0 for old_cpu, new_cpu in bigLITTLE_switch_cpu_list: if switching_cpu_index == core_index: switching_cpu_list.append((old_cpu, new_cpu)) m5.switchCpus(testsys, switching_cpu_list) core_type[core_index] = 'big_core' cur_freq[core_index] = big_min_freq bigLITTLE_switch_cpu_list[core_index] = (new_cpu, old_cpu) switching_cpu_index += 1 #Update for loop index core_index += 1 #Simulate last quantum and exit the simulation loop if (maxtick - m5.curTick()) <= switch_freq: exit_event = m5.simulate(maxtick - m5.curTick()) for cpu_idx in range(num_cpu): print "big Core %d DVFS Stat." % (cpu_idx) for idx in range(14): print "%dMHz: %d" % (big_freq_list[idx + 14 * cpu_idx][0], big_freq_list[idx + 14 * cpu_idx][1]) print "LITTLE Core %d DVFS Stat." % (cpu_idx) for idx in range(12): print "%dMHz: %d" % ( Llittle_freq_list[idx + 12 * cpu_idx][0], Llittle_freq_list[idx + 12 * cpu_idx][1]) return exit_event
def run_system_with_cpu( process, options, output_dir, warmup_instructions=0, ): warmup = True # Override the -d outdir --outdir option to gem5 m5.options.outdir = output_dir m5.core.setOutputDir(m5.options.outdir) m5.stats.reset() max_tick = options.abs_max_tick if options.rel_max_tick: max_tick = options.rel_max_tick elif options.maxtime: max_tick = int(options.maxtime * 1000 * 1000 * 1000 * 1000) eprint("Simulating until tick=%s" % (max_tick)) # DerivO3CPU is the configurable out-of-order CPU model supplied by gem5 the_cpu = DerivO3CPU(cpu_id=0, switched_out=warmup) icache = L1_ICache(size=options.l1i_size, assoc=options.l1i_assoc) dcache = L1_DCache(size=options.l1d_size, assoc=options.l1d_assoc) the_cpu.branchPred = LocalBP() # Parameter values the_cpu.numROBEntries = options.ROB the_cpu.numIQEntries = options.IQ real_cpus = [the_cpu] mem_mode = real_cpus[0].memory_mode() if warmup: the_w_cpu = TimingSimpleCPU(cpu_id=0) the_w_cpu.branchPred = LocalBP() # Parameter values the_w_cpu[0].addPrivateSplitL1Caches(icache, dcache, None, None) the_w_cpu[0].createInterruptController() warmup_cpus = [the_w_cpu] if warmup_instructions: warmup_cpus[0].max_insts_any_thread = warmup_instructions else: warmup_cpus = real_cpus system = System(cpu=warmup_cpus, mem_mode=mem_mode, mem_ranges=[AddrRange(options.mem_size)], cache_line_size=options.cacheline_size) system.multi_thread = False system.voltage_domain = VoltageDomain(voltage=options.sys_voltage) system.clk_domain = SrcClockDomain(clock=options.sys_clock, voltage_domain=system.voltage_domain) system.cpu_voltage_domain = VoltageDomain() system.cpu_clk_domain = SrcClockDomain( clock=options.cpu_clock, voltage_domain=system.cpu_voltage_domain) system.cache_line_size = options.cacheline_size cache_line_size = options.cacheline_size for cpu in system.cpu: cpu.clk_domain = system.cpu_clk_domain cpu.workload = process if options.prog_interval: cpu.progress_interval = options.prog_interval cpu.createThreads() MemClass = Simulation.setMemClass(options) system.membus = SystemXBar() system.system_port = system.membus.slave system.cpu[0].connectAllPorts(system.membus) MemConfig.config_mem(options, system) root = Root(full_system=False, system=system) if warmup: for cpu in real_cpus: cpu.clk_domain = system.cpu_clk_domain cpu.workload = process cpu.system = system cpu.switched_out = True cpu.createThreads() root.switch_cpus = real_cpus m5.options.outdir = output_dir m5.instantiate(None) # None == no checkpoint if warmup: eprint("Running warmup with warmup CPU class ({} instrs.)".format( warmup_instructions)) eprint("Starting simulation") exit_event = m5.simulate(max_tick) eprint("exit_event: {}".format(exit_event)) if warmup: max_tick -= m5.curTick() m5.stats.reset() eprint("Finished warmup; running real simulation") m5.switchCpus(system, list(zip(warmup_cpus, real_cpus))) exit_event = m5.simulate(max_tick) eprint("Done simulation @ tick = %s: %s" % (m5.curTick(), exit_event.getCause())) m5.stats.dump()
def run(options, root, testsys, cpu_class): if options.maxtick: maxtick = options.maxtick elif options.maxtime: simtime = m5.ticks.seconds(simtime) print "simulating for: ", simtime maxtick = simtime else: maxtick = m5.MaxTick if options.checkpoint_dir: cptdir = options.checkpoint_dir elif m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.fast_forward and options.checkpoint_restore != None: fatal("Can't specify both --fast-forward and --checkpoint-restore") if options.standard_switch and not options.caches: fatal("Must specify --caches when using --standard-switch") np = options.num_cpus max_checkpoints = options.max_checkpoints new = None if options.prog_interval: for i in xrange(np): testsys.cpu[i].progress_interval = options.prog_interval if options.maxinsts: for i in xrange(np): testsys.cpu[i].max_insts_any_thread = options.maxinsts if cpu_class: new = [cpu_class(defer_registration=True, cpu_id=(np + i)) for i in xrange(np)] for i in xrange(np): if options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) new[i].system = testsys if not buildEnv["FULL_SYSTEM"]: new[i].workload = testsys.cpu[i].workload new[i].clock = testsys.cpu[0].clock # simulation period if options.maxinsts: new[i].max_insts_any_thread = options.maxinsts testsys.new = new switch_cpu_list = [(testsys.cpu[i], new[i]) for i in xrange(np)] if options.standard_switch: if not options.caches: # O3 CPU must have a cache to work. print "O3 CPU must be used with caches" sys.exit(1) new = [TimingSimpleCPU(defer_registration=True, cpu_id=(np + i)) for i in xrange(np)] new_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2 * np + i)) for i in xrange(np)] for i in xrange(np): new[i].system = testsys new_1[i].system = testsys if not buildEnv["FULL_SYSTEM"]: new[i].workload = testsys.cpu[i].workload new_1[i].workload = testsys.cpu[i].workload new[i].clock = testsys.cpu[0].clock new_1[i].clock = testsys.cpu[0].clock # if restoring, make atomic cpu simulate only a few instructions if options.checkpoint_restore != None: testsys.cpu[i].max_insts_any_thread = 1 # Fast forward to specified location if we are not restoring elif options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) # Fast forward to a simpoint (warning: time consuming) elif options.simpoint: if testsys.cpu[i].workload[0].simpoint == 0: fatal("simpoint not found") testsys.cpu[i].max_insts_any_thread = testsys.cpu[i].workload[0].simpoint # No distance specified, just switch else: testsys.cpu[i].max_insts_any_thread = 1 # warmup period if options.warmup_insts: new[i].max_insts_any_thread = options.warmup_insts # simulation period if options.maxinsts: new_1[i].max_insts_any_thread = options.maxinsts testsys.new = new testsys.new_1 = new_1 switch_cpu_list = [(testsys.cpu[i], new[i]) for i in xrange(np)] switch_cpu_list1 = [(new[i], new_1[i]) for i in xrange(np)] # set the checkpoint in the cpu before m5.instantiate is called if options.take_checkpoints != None and (options.simpoint or options.at_instruction): offset = int(options.take_checkpoints) # Set an instruction break point if options.simpoint: for i in xrange(np): if testsys.cpu[i].workload[0].simpoint == 0: fatal("no simpoint for testsys.cpu[%d].workload[0]", i) checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset testsys.cpu[i].max_insts_any_thread = checkpoint_inst # used for output below options.take_checkpoints = checkpoint_inst else: options.take_checkpoints = offset # Set all test cpus with the right number of instructions # for the upcoming simulation for i in xrange(np): testsys.cpu[i].max_insts_any_thread = offset checkpoint_dir = None if options.checkpoint_restore != None: from os.path import isdir, exists from os import listdir import re if not isdir(cptdir): fatal("checkpoint dir %s does not exist!", cptdir) if options.at_instruction or options.simpoint: inst = options.checkpoint_restore if options.simpoint: # assume workload 0 has the simpoint if testsys.cpu[0].workload[0].simpoint == 0: fatal("Unable to find simpoint") inst += int(testsys.cpu[0].workload[0].simpoint) checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst)) if not exists(checkpoint_dir): fatal("Unable to find checkpoint directory %s", checkpoint_dir) else: dirs = listdir(cptdir) expr = re.compile("cpt\.([0-9]*)") cpts = [] for dir in dirs: match = expr.match(dir) if match: cpts.append(match.group(1)) cpts.sort(lambda a, b: cmp(long(a), long(b))) cpt_num = options.checkpoint_restore if cpt_num > len(cpts): fatal("Checkpoint %d not found", cpt_num) ## Adjust max tick based on our starting tick maxtick = maxtick - int(cpts[cpt_num - 1]) checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1]) m5.instantiate(checkpoint_dir) if options.standard_switch or cpu_class: if options.standard_switch: print "Switch at instruction count:%s" % str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() elif cpu_class and options.fast_forward: print "Switch at instruction count:%s" % str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() else: print "Switch at curTick count:%s" % str(10000) exit_event = m5.simulate(10000) print "Switched CPUS @ tick %s" % (m5.curTick()) # when you change to Timing (or Atomic), you halt the system # given as argument. When you are finished with the system # changes (including switchCpus), you must resume the system # manually. You DON'T need to resume after just switching # CPUs if you haven't changed anything on the system level. m5.changeToTiming(testsys) m5.switchCpus(switch_cpu_list) m5.resume(testsys) if options.standard_switch: print "Switch at instruction count:%d" % (testsys.new[0].max_insts_any_thread) # warmup instruction count may have already been set if options.warmup_insts: exit_event = m5.simulate() else: exit_event = m5.simulate(options.warmup) print "Switching CPUS @ tick %s" % (m5.curTick()) print "Simulation ends instruction count:%d" % (testsys.new_1[0].max_insts_any_thread) m5.drain(testsys) m5.switchCpus(switch_cpu_list1) m5.resume(testsys) num_checkpoints = 0 exit_cause = "" # If we're taking and restoring checkpoints, use checkpoint_dir # 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 m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() # Checkpoints being taken via the command line at <when> and at # subsequent periods of <period>. Checkpoint instructions # received from the benchmark running are ignored and skipped in # favor of command line checkpoint instructions. if options.take_checkpoints != None: if options.at_instruction or options.simpoint: checkpoint_inst = int(options.take_checkpoints) # maintain correct offset if we restored from some instruction if options.checkpoint_restore != None: checkpoint_inst += options.checkpoint_restore print "Creating checkpoint at inst:%d" % (checkpoint_inst) exit_event = m5.simulate() print "exit cause = %s" % (exit_event.getCause()) # skip checkpoint instructions should they exist while exit_event.getCause() == "checkpoint": exit_event = m5.simulate() if exit_event.getCause() == "a thread reached the max instruction count": m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % (options.bench, checkpoint_inst))) print "Checkpoint written." num_checkpoints += 1 if exit_event.getCause() == "user interrupt received": exit_cause = exit_event.getCause() else: when, period = options.take_checkpoints.split(",", 1) when = int(when) period = int(period) exit_event = m5.simulate(when) while exit_event.getCause() == "checkpoint": exit_event = m5.simulate(when - m5.curTick()) if exit_event.getCause() == "simulate() limit reached": m5.checkpoint(joinpath(cptdir, "cpt.%d")) num_checkpoints += 1 sim_ticks = when exit_cause = "maximum %d checkpoints dropped" % max_checkpoints while num_checkpoints < max_checkpoints and exit_event.getCause() == "simulate() limit reached": if (sim_ticks + period) > maxtick: exit_event = m5.simulate(maxtick - sim_ticks) exit_cause = exit_event.getCause() break else: exit_event = m5.simulate(period) sim_ticks += period while exit_event.getCause() == "checkpoint": exit_event = m5.simulate(sim_ticks - m5.curTick()) if exit_event.getCause() == "simulate() limit reached": m5.checkpoint(joinpath(cptdir, "cpt.%d")) num_checkpoints += 1 if exit_event.getCause() != "simulate() limit reached": exit_cause = exit_event.getCause() else: # no checkpoints being taken via this script if options.fast_forward: m5.stats.reset() print "**** REAL SIMULATION ****" exit_event = m5.simulate(maxtick) while exit_event.getCause() == "checkpoint": m5.checkpoint(joinpath(cptdir, "cpt.%d")) num_checkpoints += 1 if num_checkpoints == max_checkpoints: exit_cause = "maximum %d checkpoints dropped" % max_checkpoints break exit_event = m5.simulate(maxtick - m5.curTick()) exit_cause = exit_event.getCause() if exit_cause == "": exit_cause = exit_event.getCause() print "Exiting @ tick %i because %s" % (m5.curTick(), exit_cause) if options.checkpoint_at_end: m5.checkpoint(joinpath(cptdir, "cpt.%d"))
pyterm.close_pyterm(term, inpipe) print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_event.getCause()) if not m5.options.interactive: sys.exit(exit_event.getCode()) sys.exit(0) elif start_count >= len(sorted_points) and options.simpoint_mode =="fastfwd": inpipe.send("/sbin/m5 switchcpus\n") exit_event = m5.simulate() exit_cause = exit_event.getCause() if exit_cause == "switch cpus": print "Done fast-forwarding -- Switching to detailed CPU" m5.switchCpus(test_sys, switch_cpu_list) else: print "exit_cause was %s" % exit_cause sys.exit(1) elif options.simpoint_mode == "simulate" or options.simpoint_mode == "batch": (term, inpipe) = pyterm.pyterm(term_port) print "Waiting for bash shell to start (tick %i)..." % m5.curTick() exit_event = m5.simulate(10000000) #exit_event = m5.simulate(10000000000) exit_cause = exit_event.getCause() print "Wait stopped because %s" % exit_cause print "Switching CPUS at tick %s" % m5.curTick()
def run(options, root, testsys, cpu_class): if options.maxtick: maxtick = options.maxtick elif options.maxtime: simtime = m5.ticks.seconds(simtime) print "simulating for: ", simtime maxtick = simtime else: maxtick = m5.MaxTick if options.checkpoint_dir: cptdir = options.checkpoint_dir elif m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.fast_forward and options.checkpoint_restore != None: fatal("Can't specify both --fast-forward and --checkpoint-restore") if options.standard_switch and not options.caches: fatal("Must specify --caches when using --standard-switch") if options.standard_switch and options.repeat_switch: fatal("Can't specify both --standard-switch and --repeat-switch") if options.repeat_switch and options.take_checkpoints: fatal("Can't specify both --repeat-switch and --take-checkpoints") np = options.num_cpus switch_cpus = None if options.prog_interval: for i in xrange(np): testsys.cpu[i].progress_interval = options.prog_interval if options.maxinsts: for i in xrange(np): testsys.cpu[i].max_insts_any_thread = options.maxinsts if cpu_class: switch_cpus = [cpu_class(switched_out=True, cpu_id=(i)) for i in xrange(np)] for i in xrange(np): if options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) switch_cpus[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[i].clock # simulation period if options.maxinsts: switch_cpus[i].max_insts_any_thread = options.maxinsts # Add checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() testsys.switch_cpus = switch_cpus switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] if options.repeat_switch: switch_class = getCPUClass(options.cpu_type)[0] if switch_class.require_caches() and \ not options.caches: print "%s: Must be used with caches" % str(switch_class) sys.exit(1) if not switch_class.support_take_over(): print "%s: CPU switching not supported" % str(switch_class) sys.exit(1) repeat_switch_cpus = [switch_class(switched_out=True, \ cpu_id=(i)) for i in xrange(np)] for i in xrange(np): repeat_switch_cpus[i].system = testsys repeat_switch_cpus[i].workload = testsys.cpu[i].workload repeat_switch_cpus[i].clock = testsys.cpu[i].clock if options.maxinsts: repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts if options.checker: repeat_switch_cpus[i].addCheckerCpu() testsys.repeat_switch_cpus = repeat_switch_cpus if cpu_class: repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i]) for i in xrange(np)] else: repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i]) for i in xrange(np)] if options.standard_switch: switch_cpus = [TimingSimpleCPU(switched_out=True, cpu_id=(i)) for i in xrange(np)] switch_cpus_1 = [DerivO3CPU(switched_out=True, cpu_id=(i)) for i in xrange(np)] for i in xrange(np): switch_cpus[i].system = testsys switch_cpus_1[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus_1[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[i].clock switch_cpus_1[i].clock = testsys.cpu[i].clock # if restoring, make atomic cpu simulate only a few instructions if options.checkpoint_restore != None: testsys.cpu[i].max_insts_any_thread = 1 # Fast forward to specified location if we are not restoring elif options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) # Fast forward to a simpoint (warning: time consuming) elif options.simpoint: if testsys.cpu[i].workload[0].simpoint == 0: fatal('simpoint not found') testsys.cpu[i].max_insts_any_thread = \ testsys.cpu[i].workload[0].simpoint # No distance specified, just switch else: testsys.cpu[i].max_insts_any_thread = 1 # warmup period if options.warmup_insts: switch_cpus[i].max_insts_any_thread = options.warmup_insts # simulation period if options.maxinsts: switch_cpus_1[i].max_insts_any_thread = options.maxinsts # attach the checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() switch_cpus_1[i].addCheckerCpu() testsys.switch_cpus = switch_cpus testsys.switch_cpus_1 = switch_cpus_1 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)] # set the checkpoint in the cpu before m5.instantiate is called if options.take_checkpoints != None and \ (options.simpoint or options.at_instruction): offset = int(options.take_checkpoints) # Set an instruction break point if options.simpoint: for i in xrange(np): if testsys.cpu[i].workload[0].simpoint == 0: fatal('no simpoint for testsys.cpu[%d].workload[0]', i) checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset testsys.cpu[i].max_insts_any_thread = checkpoint_inst # used for output below options.take_checkpoints = checkpoint_inst else: options.take_checkpoints = offset # Set all test cpus with the right number of instructions # for the upcoming simulation for i in xrange(np): testsys.cpu[i].max_insts_any_thread = offset checkpoint_dir = None if options.checkpoint_restore != None: maxtick, checkpoint_dir = findCptDir(options, maxtick, cptdir, testsys) m5.instantiate(checkpoint_dir) if options.standard_switch or cpu_class: if options.standard_switch: print "Switch at instruction count:%s" % \ str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() elif cpu_class and options.fast_forward: print "Switch at instruction count:%s" % \ str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() else: print "Switch at curTick count:%s" % str(10000) exit_event = m5.simulate(10000) print "Switched CPUS @ tick %s" % (m5.curTick()) m5.switchCpus(testsys, switch_cpu_list) if options.standard_switch: print "Switch at instruction count:%d" % \ (testsys.switch_cpus[0].max_insts_any_thread) #warmup instruction count may have already been set if options.warmup_insts: exit_event = m5.simulate() else: exit_event = m5.simulate(options.standard_switch) print "Switching CPUS @ tick %s" % (m5.curTick()) print "Simulation ends instruction count:%d" % \ (testsys.switch_cpus_1[0].max_insts_any_thread) m5.switchCpus(testsys, switch_cpu_list1) # If we're taking and restoring checkpoints, use checkpoint_dir # 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 m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.take_checkpoints != None : # Checkpoints being taken via the command line at <when> and at # subsequent periods of <period>. Checkpoint instructions # received from the benchmark running are ignored and skipped in # favor of command line checkpoint instructions. exit_event = scriptCheckpoints(options, maxtick, cptdir) else: if options.fast_forward: m5.stats.reset() print "**** REAL SIMULATION ****" # If checkpoints are being taken, then the checkpoint instruction # will occur in the benchmark code it self. if options.repeat_switch and maxtick > options.repeat_switch: exit_event = repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, options.repeat_switch) else: exit_event = benchCheckpoints(options, maxtick, cptdir) print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_event.getCause()) if options.checkpoint_at_end: m5.checkpoint(joinpath(cptdir, "cpt.%d")) if not m5.options.interactive: sys.exit(exit_event.getCode())
def run(options, root, testsys, cpu_class): if options.maxtick: maxtick = options.maxtick elif options.maxtime: simtime = m5.ticks.seconds(simtime) print "simulating for: ", simtime maxtick = simtime else: maxtick = m5.MaxTick if options.checkpoint_dir: cptdir = options.checkpoint_dir elif m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.fast_forward and options.checkpoint_restore != None: fatal("Can't specify both --fast-forward and --checkpoint-restore") if options.standard_switch and not options.caches: fatal("Must specify --caches when using --standard-switch") if options.standard_switch and options.repeat_switch: fatal("Can't specify both --standard-switch and --repeat-switch") if options.repeat_switch and options.take_checkpoints: fatal("Can't specify both --repeat-switch and --take-checkpoints") np = options.num_cpus switch_cpus = None if options.prog_interval: for i in xrange(np): testsys.cpu[i].progress_interval = options.prog_interval if options.maxinsts: for i in xrange(np): testsys.cpu[i].max_insts_any_thread = options.maxinsts if options.pred_type: for i in xrange(np): testsys.cpu[i].predType = options.pred_type if options.global_hist_size: for i in xrange(np): testsys.cpu[i].globalHistoryBits = options.global_hist_size if options.global_pred_size: for i in xrange(np): testsys.cpu[i].globalPredictorSize = options.global_pred_size if options.local_pred_size: for i in xrange(np): testsys.cpu[i].localPredictorSize = options.local_pred_size if cpu_class: switch_cpus = [ cpu_class(defer_registration=True, cpu_id=(i)) for i in xrange(np) ] for i in xrange(np): if options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) switch_cpus[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[i].clock # simulation period if options.maxinsts: switch_cpus[i].max_insts_any_thread = options.maxinsts # Add checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() testsys.switch_cpus = switch_cpus switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] if options.repeat_switch: if options.cpu_type == "arm_detailed": if not options.caches: print "O3 CPU must be used with caches" sys.exit(1) repeat_switch_cpus = [O3_ARM_v7a_3(defer_registration=True, \ cpu_id=(i)) for i in xrange(np)] elif options.cpu_type == "detailed": if not options.caches: print "O3 CPU must be used with caches" sys.exit(1) repeat_switch_cpus = [DerivO3CPU(defer_registration=True, \ cpu_id=(i)) for i in xrange(np)] elif options.cpu_type == "inorder": print "inorder CPU switching not supported" sys.exit(1) elif options.cpu_type == "timing": repeat_switch_cpus = [TimingSimpleCPU(defer_registration=True, \ cpu_id=(i)) for i in xrange(np)] else: repeat_switch_cpus = [AtomicSimpleCPU(defer_registration=True, \ cpu_id=(i)) for i in xrange(np)] for i in xrange(np): repeat_switch_cpus[i].system = testsys repeat_switch_cpus[i].workload = testsys.cpu[i].workload repeat_switch_cpus[i].clock = testsys.cpu[i].clock if options.maxinsts: repeat_switch_cpus[i].max_insts_any_thread = options.maxinsts if options.checker: repeat_switch_cpus[i].addCheckerCpu() testsys.repeat_switch_cpus = repeat_switch_cpus if cpu_class: repeat_switch_cpu_list = [(switch_cpus[i], repeat_switch_cpus[i]) for i in xrange(np)] else: repeat_switch_cpu_list = [(testsys.cpu[i], repeat_switch_cpus[i]) for i in xrange(np)] if options.standard_switch: switch_cpus = [ TimingSimpleCPU(defer_registration=True, cpu_id=(i)) for i in xrange(np) ] switch_cpus_1 = [ DerivO3CPU(defer_registration=True, cpu_id=(i)) for i in xrange(np) ] for i in xrange(np): switch_cpus[i].system = testsys switch_cpus_1[i].system = testsys switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus_1[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[i].clock switch_cpus_1[i].clock = testsys.cpu[i].clock # if restoring, make atomic cpu simulate only a few instructions if options.checkpoint_restore != None: testsys.cpu[i].max_insts_any_thread = 1 # Fast forward to specified location if we are not restoring elif options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) # Fast forward to a simpoint (warning: time consuming) elif options.simpoint: if testsys.cpu[i].workload[0].simpoint == 0: fatal('simpoint not found') testsys.cpu[i].max_insts_any_thread = \ testsys.cpu[i].workload[0].simpoint # No distance specified, just switch else: testsys.cpu[i].max_insts_any_thread = 1 # warmup period if options.warmup_insts: switch_cpus[i].max_insts_any_thread = options.warmup_insts # simulation period if options.maxinsts: switch_cpus_1[i].max_insts_any_thread = options.maxinsts # attach the checker cpu if selected if options.checker: switch_cpus[i].addCheckerCpu() switch_cpus_1[i].addCheckerCpu() testsys.switch_cpus = switch_cpus testsys.switch_cpus_1 = switch_cpus_1 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)] # set the checkpoint in the cpu before m5.instantiate is called if options.take_checkpoints != None and \ (options.simpoint or options.at_instruction): offset = int(options.take_checkpoints) # Set an instruction break point if options.simpoint: for i in xrange(np): if testsys.cpu[i].workload[0].simpoint == 0: fatal('no simpoint for testsys.cpu[%d].workload[0]', i) checkpoint_inst = int( testsys.cpu[i].workload[0].simpoint) + offset testsys.cpu[i].max_insts_any_thread = checkpoint_inst # used for output below options.take_checkpoints = checkpoint_inst else: options.take_checkpoints = offset # Set all test cpus with the right number of instructions # for the upcoming simulation for i in xrange(np): testsys.cpu[i].max_insts_any_thread = offset checkpoint_dir = None if options.checkpoint_restore != None: maxtick, checkpoint_dir = findCptDir(options, maxtick, cptdir, testsys) m5.instantiate(checkpoint_dir) if options.standard_switch or cpu_class: if options.standard_switch: print "Switch at instruction count:%s" % \ str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() elif cpu_class and options.fast_forward: print "Switch at instruction count:%s" % \ str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() else: print "Switch at curTick count:%s" % str(10000) exit_event = m5.simulate(10000) print "Switched CPUS @ tick %s" % (m5.curTick()) # when you change to Timing (or Atomic), you halt the system # given as argument. When you are finished with the system # changes (including switchCpus), you must resume the system # manually. You DON'T need to resume after just switching # CPUs if you haven't changed anything on the system level. m5.doDrain(testsys) m5.changeToTiming(testsys) m5.switchCpus(switch_cpu_list) m5.resume(testsys) if options.standard_switch: print "Switch at instruction count:%d" % \ (testsys.switch_cpus[0].max_insts_any_thread) #warmup instruction count may have already been set if options.warmup_insts: exit_event = m5.simulate() else: exit_event = m5.simulate(options.standard_switch) print "Switching CPUS @ tick %s" % (m5.curTick()) print "Simulation ends instruction count:%d" % \ (testsys.switch_cpus_1[0].max_insts_any_thread) m5.doDrain(testsys) m5.switchCpus(switch_cpu_list1) m5.resume(testsys) # If we're taking and restoring checkpoints, use checkpoint_dir # 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 m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.take_checkpoints != None: # Checkpoints being taken via the command line at <when> and at # subsequent periods of <period>. Checkpoint instructions # received from the benchmark running are ignored and skipped in # favor of command line checkpoint instructions. exit_cause = scriptCheckpoints(options, maxtick, cptdir) else: if options.fast_forward: m5.stats.reset() print "**** REAL SIMULATION ****" # If checkpoints are being taken, then the checkpoint instruction # will occur in the benchmark code it self. if options.repeat_switch and maxtick > options.repeat_switch: exit_cause = repeatSwitch(testsys, repeat_switch_cpu_list, maxtick, options.repeat_switch) else: exit_cause = benchCheckpoints(options, maxtick, cptdir) print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause) if options.checkpoint_at_end: m5.checkpoint(joinpath(cptdir, "cpt.%d"))
checkpoint_dir = None m5.instantiate(checkpoint_dir) # Map workload to this address space host_cpu.workload[0].map(0x10000000, 0x200000000, 4096) if options.fast_forward: print "Switch at instruction count: %d" % \ cpu_list[0].max_insts_any_thread exit_event = m5.simulate(maxtick) if options.fast_forward: if exit_event.getCause() == "a thread reached the max instruction count": m5.switchCpus(system, switch_cpu_list) print "Switched CPUS @ tick %s" % (m5.curTick()) m5.stats.reset() exit_event = m5.simulate(maxtick - m5.curTick()) elif options.fast_forward_pseudo_op: while exit_event.getCause() == "switchcpu": # If we are switching *to* kvm, then the current stats are meaningful # Note that we don't do any warmup by default if type(switch_cpu_list[0][0]) == FutureCpuClass: print "Dumping stats..." m5.stats.dump() m5.switchCpus(system, switch_cpu_list) print "Switched CPUS @ tick %s" % (m5.curTick()) m5.stats.reset() # This lets us switch back and forth without keeping a counter switch_cpu_list = [(x[1], x[0]) for x in switch_cpu_list]
def run(options, root, testsys, cpu_class): # NOTE: this function is called from example from configs/example/ruby_fs.py # like this: "Simulation.run(options, root, system, FutureClass)" # so, "system" is "testsys" here; if options.maxtick: maxtick = options.maxtick elif options.maxtime: simtime = m5.ticks.seconds(simtime) print "simulating for: ", simtime maxtick = simtime else: maxtick = m5.MaxTick if options.checkpoint_dir: cptdir = options.checkpoint_dir elif m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() if options.fast_forward and options.checkpoint_restore != None: fatal("Can't specify both --fast-forward and --checkpoint-restore") if options.standard_switch and not options.caches: fatal("Must specify --caches when using --standard-switch") np = options.num_cpus max_checkpoints = options.max_checkpoints switch_cpus = None if options.prog_interval: for i in xrange(np): testsys.cpu[i].progress_interval = options.prog_interval if options.maxinsts: for i in xrange(np): testsys.cpu[i].max_insts_any_thread = options.maxinsts if cpu_class: switch_cpus = [cpu_class(defer_registration=True, cpu_id=(np+i)) for i in xrange(np)] for i in xrange(np): if options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) switch_cpus[i].system = testsys if not buildEnv['FULL_SYSTEM']: switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[0].clock # simulation period if options.maxinsts: switch_cpus[i].max_insts_any_thread = options.maxinsts testsys.switch_cpus = switch_cpus switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] if options.standard_switch: if not options.caches: # O3 CPU must have a cache to work. print "O3 CPU must be used with caches" sys.exit(1) switch_cpus = [TimingSimpleCPU(defer_registration=True, cpu_id=(np+i)) for i in xrange(np)] switch_cpus_1 = [DerivO3CPU(defer_registration=True, cpu_id=(2*np+i)) for i in xrange(np)] for i in xrange(np): switch_cpus[i].system = testsys switch_cpus_1[i].system = testsys if not buildEnv['FULL_SYSTEM']: switch_cpus[i].workload = testsys.cpu[i].workload switch_cpus_1[i].workload = testsys.cpu[i].workload switch_cpus[i].clock = testsys.cpu[0].clock switch_cpus_1[i].clock = testsys.cpu[0].clock # if restoring, make atomic cpu simulate only a few instructions if options.checkpoint_restore != None: testsys.cpu[i].max_insts_any_thread = 1 # Fast forward to specified location if we are not restoring elif options.fast_forward: testsys.cpu[i].max_insts_any_thread = int(options.fast_forward) # Fast forward to a simpoint (warning: time consuming) elif options.simpoint: if testsys.cpu[i].workload[0].simpoint == 0: fatal('simpoint not found') testsys.cpu[i].max_insts_any_thread = \ testsys.cpu[i].workload[0].simpoint # No distance specified, just switch else: testsys.cpu[i].max_insts_any_thread = 1 # warmup period if options.warmup_insts: switch_cpus[i].max_insts_any_thread = options.warmup_insts # simulation period if options.maxinsts: switch_cpus_1[i].max_insts_any_thread = options.maxinsts testsys.switch_cpus = switch_cpus testsys.switch_cpus_1 = switch_cpus_1 switch_cpu_list = [(testsys.cpu[i], switch_cpus[i]) for i in xrange(np)] switch_cpu_list1 = [(switch_cpus[i], switch_cpus_1[i]) for i in xrange(np)] # set the checkpoint in the cpu before m5.instantiate is called if options.take_checkpoints != None and \ (options.simpoint or options.at_instruction): offset = int(options.take_checkpoints) # Set an instruction break point if options.simpoint: for i in xrange(np): if testsys.cpu[i].workload[0].simpoint == 0: fatal('no simpoint for testsys.cpu[%d].workload[0]', i) checkpoint_inst = int(testsys.cpu[i].workload[0].simpoint) + offset testsys.cpu[i].max_insts_any_thread = checkpoint_inst # used for output below options.take_checkpoints = checkpoint_inst else: options.take_checkpoints = offset # Set all test cpus with the right number of instructions # for the upcoming simulation for i in xrange(np): testsys.cpu[i].max_insts_any_thread = offset checkpoint_dir = None if options.checkpoint_restore != None: from os.path import isdir, exists from os import listdir import re if not isdir(cptdir): fatal("checkpoint dir %s does not exist!", cptdir) if options.at_instruction or options.simpoint: inst = options.checkpoint_restore if options.simpoint: # assume workload 0 has the simpoint if testsys.cpu[0].workload[0].simpoint == 0: fatal('Unable to find simpoint') inst += int(testsys.cpu[0].workload[0].simpoint) checkpoint_dir = joinpath(cptdir, "cpt.%s.%s" % (options.bench, inst)) if not exists(checkpoint_dir): fatal("Unable to find checkpoint directory %s", checkpoint_dir) else: dirs = listdir(cptdir) expr = re.compile('cpt\.([0-9]*)') cpts = [] for dir in dirs: match = expr.match(dir) if match: cpts.append(match.group(1)) cpts.sort(lambda a,b: cmp(long(a), long(b))) cpt_num = options.checkpoint_restore if cpt_num > len(cpts): fatal('Checkpoint %d not found', cpt_num) ## Adjust max tick based on our starting tick maxtick = maxtick - int(cpts[cpt_num - 1]) checkpoint_dir = joinpath(cptdir, "cpt.%s" % cpts[cpt_num - 1]) m5.instantiate(checkpoint_dir) if options.standard_switch or cpu_class: if options.standard_switch: print "Switch at instruction count:%s" % \ str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() elif cpu_class and options.fast_forward: print "Switch at instruction count:%s" % \ str(testsys.cpu[0].max_insts_any_thread) exit_event = m5.simulate() else: print "Switch at curTick count:%s" % str(10000) exit_event = m5.simulate(10000) print "Switched CPUS @ tick %s" % (m5.curTick()) # when you change to Timing (or Atomic), you halt the system # given as argument. When you are finished with the system # changes (including switchCpus), you must resume the system # manually. You DON'T need to resume after just switching # CPUs if you haven't changed anything on the system level. m5.changeToTiming(testsys) m5.switchCpus(switch_cpu_list) m5.resume(testsys) if options.standard_switch: print "Switch at instruction count:%d" % \ (testsys.switch_cpus[0].max_insts_any_thread) #warmup instruction count may have already been set if options.warmup_insts: exit_event = m5.simulate() else: exit_event = m5.simulate(options.warmup) print "Switching CPUS @ tick %s" % (m5.curTick()) print "Simulation ends instruction count:%d" % \ (testsys.switch_cpus_1[0].max_insts_any_thread) m5.drain(testsys) m5.switchCpus(switch_cpu_list1) m5.resume(testsys) num_checkpoints = 0 exit_cause = '' # If we're taking and restoring checkpoints, use checkpoint_dir # 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 m5.options.outdir: cptdir = m5.options.outdir else: cptdir = getcwd() # Checkpoints being taken via the command line at <when> and at # subsequent periods of <period>. Checkpoint instructions # received from the benchmark running are ignored and skipped in # favor of command line checkpoint instructions. if options.take_checkpoints != None : if options.at_instruction or options.simpoint: checkpoint_inst = int(options.take_checkpoints) # maintain correct offset if we restored from some instruction if options.checkpoint_restore != None: checkpoint_inst += options.checkpoint_restore print "Creating checkpoint at inst:%d" % (checkpoint_inst) exit_event = m5.simulate() print "exit cause = %s" % (exit_event.getCause()) # skip checkpoint instructions should they exist while exit_event.getCause() == "checkpoint": exit_event = m5.simulate() if exit_event.getCause() == \ "a thread reached the max instruction count": m5.checkpoint(joinpath(cptdir, "cpt.%s.%d" % \ (options.bench, checkpoint_inst))) print "Checkpoint written." num_checkpoints += 1 if exit_event.getCause() == "user interrupt received": exit_cause = exit_event.getCause(); else: when, period = options.take_checkpoints.split(",", 1) when = int(when) period = int(period) exit_event = m5.simulate(when) while exit_event.getCause() == "checkpoint": exit_event = m5.simulate(when - m5.curTick()) if exit_event.getCause() == "simulate() limit reached": m5.checkpoint(joinpath(cptdir, "cpt.%d")) num_checkpoints += 1 sim_ticks = when exit_cause = "maximum %d checkpoints dropped" % max_checkpoints while num_checkpoints < max_checkpoints and \ exit_event.getCause() == "simulate() limit reached": if (sim_ticks + period) > maxtick: exit_event = m5.simulate(maxtick - sim_ticks) exit_cause = exit_event.getCause() break else: exit_event = m5.simulate(period) sim_ticks += period while exit_event.getCause() == "checkpoint": exit_event = m5.simulate(sim_ticks - m5.curTick()) if exit_event.getCause() == "simulate() limit reached": m5.checkpoint(joinpath(cptdir, "cpt.%d")) num_checkpoints += 1 if exit_event.getCause() != "simulate() limit reached": exit_cause = exit_event.getCause(); else: # no checkpoints being taken via this script if options.fast_forward: m5.stats.reset() print "**** REAL SIMULATION ****" #exit_event = m5.simulate(maxtick) # --Note1: Ruby is created in ruby_fs.py by # "Ruby.create_system(options, system, system.piobus, system._dma_devices)" # which assigned: "stats_filename = options.ruby_stats"; # definition of "create_system" is in configs/ruby/Ruby.py, which # instantiate the ctor of RubySystem: "system.ruby = RubySystem(...)"; #print testsys.ruby._cpu_ruby_ports #print testsys.ruby.network.ni_flit_size #print testsys.ruby.profiler.ruby_system # the ctor of RubySystem is defined in src/mem/ruby/system/RubySystem.py; # which sets some defaults: #print testsys.ruby.stats_filename # i.e., ruby.stats #print testsys.ruby.type #print testsys.ruby.random_seed #print testsys.ruby.clock #print testsys.ruby.block_size_bytes #print testsys.ruby.mem_size #print testsys.ruby.no_mem_vec # () cris: description of changes # --Note2: initially writing into ruby.stats was done with overwriting; # so, for each dump point the file was re-written; to fix that I # changed function "OutputDirectory::create(...)" from src/base/output.cc # which is called by "RubyExitCallback::process()" from src/mem/ruby/system/System.cc # function that is the one called at the end of the gem5 run # as a calback to dump all ruby stats (callback is "registered" in the # ctor of RubySystem::RubySystem() inside the same file...); # --Note3: using doExitCleanup inspired from src/python/m5/simulate.py # (inside which ini and json files are created; you need to rebuild each # time you change that Python file): #m5.internal.core.doExitCleanup( False) #clear callback queue? # --Note4: python/m5/internal/core.py describes "m5.internal.core"; # cris: here I want to dump stats every other delta ticks; # I need these to be able to generate reliability traces; NUM_OF_DUMPS = 100 num_i = 0 delta = maxtick/NUM_OF_DUMPS sim_ticks = m5.curTick() while (m5.curTick() < maxtick): sim_ticks += delta exit_event = m5.simulate(sim_ticks - m5.curTick()) if exit_event.getCause() == "simulate() limit reached": #--Note5: "doExitCleanup()" is described in src/sim/core.cc; # I changed it to be able to call it multiple times; #--Note6: do not dump stats in ruby.stats for last iteration # because it will be repeated once more via the exit callbacks # in src/python/m5/simulate.py... # Note6: next call of doExitCleanup does actually also reset/clear # the stats of ruby system via the RubyExitCallback::process() in # src/mem/ruby/system/System.cc if num_i < (NUM_OF_DUMPS-1): print "Dumping also ruby stats at inst %d to file: ruby.stats" %(num_i) m5.internal.core.doExitCleanup( False) #clear callback queue? print "Dumping gem5 stats at inst %d to file: stats.txt" %(num_i) # --Note7: dump() wites into stats.txt; dump() is defined in # src/python/m5/stats/__init__.py and does its # thing via the functions described in base/stats/text.cc #atexit.register(stats.dump) <--- does not work (from simulate.py) m5.stats.dump() m5.stats.reset() # <--- what does it actually do? num_i += 1 # alex's changes: #while exit_event.getCause() != "m5_exit instruction encountered": # m5.stats.dump() # m5.stats.reset() # exit_event = m5.simulate(maxtick) #while exit_event.getCause() == "checkpoint": # m5.checkpoint(joinpath(cptdir, "cpt.%d")) # num_checkpoints += 1 # if num_checkpoints == max_checkpoints: # exit_cause = "maximum %d checkpoints dropped" % max_checkpoints # break # exit_event = m5.simulate(maxtick - m5.curTick()) # exit_cause = exit_event.getCause() if exit_cause == '': exit_cause = exit_event.getCause() print 'Exiting @ tick %i because %s' % (m5.curTick(), exit_cause) if options.checkpoint_at_end: m5.checkpoint(joinpath(cptdir, "cpt.%d"))
def run_system_with_cpu( process, options, output_dir, warmup_cpu_class=None, warmup_instructions=0, real_cpu_create_function=lambda cpu_id: DerivO3CPU(cpu_id=cpu_id), ): # Override the -d outdir --outdir option to gem5 m5.options.outdir = output_dir m5.core.setOutputDir(m5.options.outdir) m5.stats.reset() max_tick = options.abs_max_tick if options.rel_max_tick: max_tick = options.rel_max_tick elif options.maxtime: max_tick = int(options.maxtime * 1000 * 1000 * 1000 * 1000) eprint("Simulating until tick=%s" % (max_tick)) real_cpus = [real_cpu_create_function(0)] mem_mode = real_cpus[0].memory_mode() if warmup_cpu_class: warmup_cpus = [warmup_cpu_class(cpu_id=0)] warmup_cpus[0].max_insts_any_thread = warmup_instructions else: warmup_cpus = real_cpus system = System(cpu=warmup_cpus, mem_mode=mem_mode, mem_ranges=[AddrRange(options.mem_size)], cache_line_size=options.cacheline_size) system.multi_thread = False system.voltage_domain = VoltageDomain(voltage=options.sys_voltage) system.clk_domain = SrcClockDomain(clock=options.sys_clock, voltage_domain=system.voltage_domain) system.cpu_voltage_domain = VoltageDomain() system.cpu_clk_domain = SrcClockDomain( clock=options.cpu_clock, voltage_domain=system.cpu_voltage_domain) system.cache_line_size = options.cacheline_size if warmup_cpu_class: for cpu in real_cpus: cpu.clk_domain = system.cpu_clk_domain cpu.workload = process cpu.system = system cpu.switched_out = True cpu.createThreads() system.switch_cpus = real_cpus for cpu in system.cpu: cpu.clk_domain = system.cpu_clk_domain cpu.workload = process if options.prog_interval: cpu.progress_interval = options.prog_interval cpu.createThreads() MemClass = Simulation.setMemClass(options) system.membus = SystemXBar() system.system_port = system.membus.slave system.cpu[0].connectAllPorts(system.membus) MemConfig.config_mem(options, system) root = Root(full_system=False, system=system) m5.options.outdir = output_dir m5.instantiate(None) # None == no checkpoint if warmup_cpu_class: eprint("Running warmup with warmup CPU class (%d instrs.)" % (warmup_instructions)) eprint("Starting simulation") exit_event = m5.simulate(max_tick) if warmup_cpu_class: max_tick -= m5.curTick() m5.stats.reset() debug_print("Finished warmup; running real simulation") m5.switchCpus(system, real_cpus) exit_event = m5.simulate(max_tick) eprint("Done simulation @ tick = %s: %s" % (m5.curTick(), exit_event.getCause())) m5.stats.dump()
ctrl.port = system.membus.master if args.dump_period: m5.internal.stats.periodicStatDump(int(args.dump_period * 1e9)) root = m5.objects.Root(full_system=False, system=system) if args.fast_forward: cpu_types[args.cpu_type].numThreads = args.num_threads system.switch_cpus = [ cpu_types[args.cpu_type](switched_out=True, cpu_id=i) for i in xrange(args.num_cpus) ] for i in xrange(args.num_cpus): system.cpu[i].max_insts_any_thread = args.fast_forward system.switch_cpus[i].system = system system.switch_cpus[i].workload = system.cpu[i].workload system.switch_cpus[i].clk_domain = system.cpu[i].clk_domain system.switch_cpus[i].progress_interval = system.cpu[ i].progress_interval system.switch_cpus[i].createThreads() if args.max_instructions: system.switch_cpus[i].max_insts_all_threads = args.max_instructions m5.instantiate(None) if args.fast_forward: exit_event = m5.simulate(args.stop_at_tick) m5.switchCpus(system, [(system.cpu[i], system.switch_cpus[i]) for i in xrange(args.num_cpus)]) exit_event = m5.simulate(args.stop_at_tick - m5.curTick()) print("Exiting at tick %i because %s" % (m5.curTick(), exit_event.getCause()))