From 6f3f6c16f3bdd5333eec157cd6db88199deab5fc Mon Sep 17 00:00:00 2001 From: Melissa Jost Date: Tue, 18 Oct 2022 16:04:18 -0700 Subject: [PATCH] stdlib, configs: Updating configs/example/gem5_library This commit updates all of the older tests in this directory to use the Simulator to run instead of m5.simulate() Change-Id: I2a81d5c2f27c89e8c03abb0203ca3e58a6688672 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/64791 Reviewed-by: Bobby Bruce Tested-by: kokoro Maintainer: Bobby Bruce Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66332 --- .../gem5_library/x86-gapbs-benchmarks.py | 101 +++--------- .../gem5_library/x86-npb-benchmarks.py | 145 ++++++------------ .../gem5_library/x86-parsec-benchmarks.py | 110 +++---------- .../x86-spec-cpu2006-benchmarks.py | 117 +++----------- .../x86-spec-cpu2017-benchmarks.py | 109 +++---------- 5 files changed, 144 insertions(+), 438 deletions(-) diff --git a/configs/example/gem5_library/x86-gapbs-benchmarks.py b/configs/example/gem5_library/x86-gapbs-benchmarks.py index bdc0d9427d..638d34b599 100644 --- a/configs/example/gem5_library/x86-gapbs-benchmarks.py +++ b/configs/example/gem5_library/x86-gapbs-benchmarks.py @@ -64,8 +64,8 @@ from gem5.components.processors.cpu_types import CPUTypes from gem5.isas import ISA from gem5.coherence_protocol import CoherenceProtocol from gem5.resources.resource import Resource - -from m5.stats.gem5stats import get_simstat +from gem5.simulate.simulator import Simulator +from gem5.simulate.exit_event import ExitEvent requires( isa_required=ISA.X86, @@ -210,14 +210,26 @@ board.set_kernel_disk_workload( readfile_contents=command, ) -root = Root(full_system=True, system=board) -# sim_quantum must be set when KVM cores are used. +def handle_exit(): + print("Done booting Linux") + print("Resetting stats at the start of ROI!") + m5.stats.reset() + global start_tick + start_tick = m5.curTick() + processor.switch() + yield False # E.g., continue the simulation. + print("Dump stats at the end of the ROI!") + m5.stats.dump() + yield True # Stop the simulation. We're done. -root.sim_quantum = int(1e9) -board._pre_instantiate() -m5.instantiate() +simulator = Simulator( + board=board, + on_exit_event={ + ExitEvent.EXIT: handle_exit(), + }, +) # We maintain the wall clock time. @@ -232,74 +244,8 @@ print("Using KVM cpu") # the first ROI annotation in details. The X86Board currently does not support # `work items started count reached`. -exit_event = m5.simulate() - -# The first exit_event ends with a `workbegin` cause. This means that the -# system started successfully and the execution on the program started. The -# ROI begin is encountered. - -if exit_event.getCause() == "workbegin": - - print("Done booting Linux") - print("Resetting stats at the start of ROI!") - - m5.stats.reset() - start_tick = m5.curTick() - - # We have completed up to this step using KVM cpu. Now we switch to timing - # cpu for detailed simulation. - - processor.switch() -else: - print("Unexpected termination of simulation before ROI was reached!") - print( - "Exiting @ tick {} because {}.".format( - m5.curTick(), exit_event.getCause() - ) - ) - exit(-1) - -# The next exit_event is to simulate the ROI. It should be exited with a cause -# marked by `workend`. This implies that the first annotation is successfully -# completed. - -exit_event = m5.simulate() - -# Reached the end of first ROI. -# We dump the stats here. - -# We exepect that ROI ends with `workend`. Otherwise the simulation ended -# unexpectedly. -if exit_event.getCause() == "workend": - print("Dump stats at the end of the ROI!") - - m5.stats.dump() - end_tick = m5.curTick() -else: - print("Unexpected termination of simulation while ROI was being executed!") - print( - "Exiting @ tick {} because {}.".format( - m5.curTick(), exit_event.getCause() - ) - ) - exit(-1) - -# We get simInsts using get_simstat and output it in the final print statement. - -gem5stats = get_simstat(root) - -# We get the number of committed instructions from the timing cores. We then -# sum and print them at the end. - -roi_insts = float( - gem5stats.to_json()["system"]["processor"]["switch0"]["core"][ - "exec_context.thread_0" - ]["numInsts"]["value"] -) + float( - gem5stats.to_json()["system"]["processor"]["switch1"]["core"][ - "exec_context.thread_0" - ]["numInsts"]["value"] -) +simulator.run() +end_tick = m5.curTick() # Since we simulated the ROI in details, therefore, simulation is over at this # point. @@ -313,8 +259,9 @@ print() print("Performance statistics:") print("Simulated time in ROI: %.2fs" % ((end_tick - start_tick) / 1e12)) -print("Instructions executed in ROI: %d" % ((roi_insts))) -print("Ran a total of", m5.curTick() / 1e12, "simulated seconds") +print( + "Ran a total of", simulator.get_current_tick() / 1e12, "simulated seconds" +) print( "Total wallclock time: %.2fs, %.2f min" % (time.time() - globalStart, (time.time() - globalStart) / 60) diff --git a/configs/example/gem5_library/x86-npb-benchmarks.py b/configs/example/gem5_library/x86-npb-benchmarks.py index 385760c7a7..2cb314303f 100644 --- a/configs/example/gem5_library/x86-npb-benchmarks.py +++ b/configs/example/gem5_library/x86-npb-benchmarks.py @@ -61,6 +61,8 @@ from gem5.components.processors.cpu_types import CPUTypes from gem5.isas import ISA from gem5.coherence_protocol import CoherenceProtocol from gem5.resources.resource import Resource +from gem5.simulate.simulator import Simulator +from gem5.simulate.simulator import ExitEvent from m5.stats.gem5stats import get_simstat from m5.util import warn @@ -209,17 +211,47 @@ board.set_kernel_disk_workload( readfile_contents=command, ) -# We need this for long running processes. -m5.disableAllListeners() +# The first exit_event ends with a `workbegin` cause. This means that the +# system started successfully and the execution on the program started. +def handle_workbegin(): + print("Done booting Linux") + print("Resetting stats at the start of ROI!") -root = Root(full_system=True, system=board) + m5.stats.reset() -# sim_quantum must be set when KVM cores are used. + # We have completed up to this step using KVM cpu. Now we switch to timing + # cpu for detailed simulation. -root.sim_quantum = int(1e9) + # # Next, we need to check if the user passed a value for --ticks. If yes, + # then we limit out execution to this number of ticks during the ROI. + # Otherwise, we simulate until the ROI ends. + processor.switch() + if args.ticks: + # schedule an exit event for this amount of ticks in the future. + # The simulation will then continue. + m5.scheduleTickExitFromCurrent(args.ticks) + yield False -board._pre_instantiate() -m5.instantiate() + +# The next exit_event is to simulate the ROI. It should be exited with a cause +# marked by `workend`. + +# We exepect that ROI ends with `workend` or `simulate() limit reached`. +# Otherwise the simulation ended unexpectedly. +def handle_workend(): + print("Dump stats at the end of the ROI!") + + m5.stats.dump() + yield False + + +simulator = Simulator( + board=board, + on_exit_event={ + ExitEvent.WORKBEGIN: handle_workbegin(), + ExitEvent.WORKEND: handle_workend(), + }, +) # We maintain the wall clock time. @@ -229,96 +261,12 @@ print("Running the simulation") print("Using KVM cpu") # We start the simulation. - -exit_event = m5.simulate() - -# The first exit_event ends with a `workbegin` cause. This means that the -# system started successfully and the execution on the program started. - -if exit_event.getCause() == "workbegin": - - print("Done booting Linux") - print("Resetting stats at the start of ROI!") - - m5.stats.reset() - start_tick = m5.curTick() - - # We have completed up to this step using KVM cpu. Now we switch to timing - # cpu for detailed simulation. - - processor.switch() -else: - # `workbegin` call was never encountered. - - print("Unexpected termination of simulation before ROI was reached!") - print( - "Exiting @ tick {} because {}.".format( - m5.curTick(), exit_event.getCause() - ) - ) - exit(-1) - -# The next exit_event is to simulate the ROI. It should be exited with a cause -# marked by `workend`. - -# Next, we need to check if the user passed a value for --ticks. If yes, -# then we limit out execution to this number of ticks during the ROI. -# Otherwise, we simulate until the ROI ends. -if args.ticks: - exit_event = m5.simulate(args.ticks) -else: - exit_event = m5.simulate() - - -# Reached the end of ROI. -# We dump the stats here. - -# We exepect that ROI ends with `workend` or `simulate() limit reached`. -# Otherwise the simulation ended unexpectedly. -if exit_event.getCause() == "workend": - print("Dump stats at the end of the ROI!") - - m5.stats.dump() - end_tick = m5.curTick() -elif ( - exit_event.getCause() == "simulate() limit reached" - and args.ticks is not None -): - print("Dump stats at the end of {} ticks in the ROI".format(args.ticks)) - - m5.stats.dump() - end_tick = m5.curTick() -else: - print("Unexpected termination of simulation while ROI was being executed!") - print( - "Exiting @ tick {} because {}.".format( - m5.curTick(), exit_event.getCause() - ) - ) - exit(-1) +simulator.run() # We need to note that the benchmark is not executed completely till this # point, but, the ROI has. We collect the essential statistics here before # resuming the simulation again. -# We get simInsts using get_simstat and output it in the final -# print statement. - -gem5stats = get_simstat(root) - -# We get the number of committed instructions from the timing -# cores. We then sum and print them at the end. - -roi_insts = float( - gem5stats.to_json()["system"]["processor"]["switch0"]["core"][ - "exec_context.thread_0" - ]["numInsts"]["value"] -) + float( - gem5stats.to_json()["system"]["processor"]["switch1"]["core"][ - "exec_context.thread_0" - ]["numInsts"]["value"] -) - # Simulation is over at this point. We acknowledge that all the simulation # events were successful. print("All simulation events were successful.") @@ -328,9 +276,16 @@ print("Done with the simulation") print() print("Performance statistics:") -print("Simulated time in ROI: %.2fs" % ((end_tick - start_tick) / 1e12)) -print("Instructions executed in ROI: %d" % ((roi_insts))) -print("Ran a total of", m5.curTick() / 1e12, "simulated seconds") +# manually calculate ROI time if ticks arg is used in case the +# entire ROI wasn't simulated +if args.ticks: + print(f"Simulated time in ROI (to tick): {args.ticks/ 1e12}s") +else: + print(f"Simulated time in ROI: {simulator.get_roi_ticks()[0] / 1e12}s") + +print( + f"Ran a total of {simulator.get_current_tick() / 1e12} simulated seconds" +) print( "Total wallclock time: %.2fs, %.2f min" % (time.time() - globalStart, (time.time() - globalStart) / 60) diff --git a/configs/example/gem5_library/x86-parsec-benchmarks.py b/configs/example/gem5_library/x86-parsec-benchmarks.py index 82183802c7..190c0a0980 100644 --- a/configs/example/gem5_library/x86-parsec-benchmarks.py +++ b/configs/example/gem5_library/x86-parsec-benchmarks.py @@ -60,8 +60,8 @@ from gem5.components.processors.cpu_types import CPUTypes from gem5.isas import ISA from gem5.coherence_protocol import CoherenceProtocol from gem5.resources.resource import Resource - -from m5.stats.gem5stats import get_simstat +from gem5.simulate.simulator import Simulator +from gem5.simulate.exit_event import ExitEvent # We check for the required gem5 build. @@ -195,17 +195,28 @@ board.set_kernel_disk_workload( readfile_contents=command, ) -# We need this for long running processes. -m5.disableAllListeners() +# functions to handle different exit events during the simuation +def handle_workbegin(): + print("Done booting Linux") + print("Resetting stats at the start of ROI!") + m5.stats.reset() + processor.switch() + yield False -root = Root(full_system=True, system=board) -# sim_quantum must be set if KVM cores are used. +def handle_workend(): + print("Dump stats at the end of the ROI!") + m5.stats.dump() + yield True -root.sim_quantum = int(1e9) -board._pre_instantiate() -m5.instantiate() +simulator = Simulator( + board=board, + on_exit_event={ + ExitEvent.WORKBEGIN: handle_workbegin(), + ExitEvent.WORKEND: handle_workend(), + }, +) # We maintain the wall clock time. @@ -214,83 +225,11 @@ globalStart = time.time() print("Running the simulation") print("Using KVM cpu") -start_tick = m5.curTick() -end_tick = m5.curTick() m5.stats.reset() # We start the simulation +simulator.run() -exit_event = m5.simulate() - -# The first exit_event ends with a `workbegin` cause. This means that the -# system booted successfully and the execution on the program started. - -if exit_event.getCause() == "workbegin": - - print("Done booting Linux") - print("Resetting stats at the start of ROI!") - - m5.stats.reset() - start_tick = m5.curTick() - - # We have completed up to this step using KVM cpu. Now we switch to timing - # cpu for detailed simulation. - - processor.switch() -else: - # `workbegin` call was never encountered. - - print("Unexpected termination of simulation before ROI was reached!") - print( - "Exiting @ tick {} because {}.".format( - m5.curTick(), exit_event.getCause() - ) - ) - exit(-1) - -# The next exit_event is to simulate the ROI. It should be exited with a cause -# marked by `workend`. - -exit_event = m5.simulate() - -# Reached the end of ROI. -# We dump the stats here. - -# We exepect that ROI ends with `workend`. Otherwise the simulation ended -# unexpectedly. -if exit_event.getCause() == "workend": - print("Dump stats at the end of the ROI!") - - m5.stats.dump() - end_tick = m5.curTick() -else: - print("Unexpected termination of simulation while ROI was being executed!") - print( - "Exiting @ tick {} because {}.".format( - m5.curTick(), exit_event.getCause() - ) - ) - exit(-1) - -# ROI has ended here, and we get `simInsts` using get_simstat and print it in -# the final print statement. - -gem5stats = get_simstat(root) - -# We get the number of committed instructions from the timing -# cores. We then sum and print them at the end. -roi_insts = float( - gem5stats.to_json()["system"]["processor"]["switch0"]["core"][ - "exec_context.thread_0" - ]["numInsts"]["value"] -) + float( - gem5stats.to_json()["system"]["processor"]["switch1"]["core"][ - "exec_context.thread_0" - ]["numInsts"]["value"] -) - -# Simulation is over at this point. We acknowledge that all the simulation -# events were successful. print("All simulation events were successful.") # We print the final simulation statistics. @@ -299,9 +238,10 @@ print("Done with the simulation") print() print("Performance statistics:") -print("Simulated time in ROI: %.2fs" % ((end_tick - start_tick) / 1e12)) -print("Instructions executed in ROI: %d" % ((roi_insts))) -print("Ran a total of", m5.curTick() / 1e12, "simulated seconds") +print("Simulated time in ROI: " + ((str(simulator.get_roi_ticks()[0])))) +print( + "Ran a total of", simulator.get_current_tick() / 1e12, "simulated seconds" +) print( "Total wallclock time: %.2fs, %.2f min" % (time.time() - globalStart, (time.time() - globalStart) / 60) diff --git a/configs/example/gem5_library/x86-spec-cpu2006-benchmarks.py b/configs/example/gem5_library/x86-spec-cpu2006-benchmarks.py index d656e61145..8f39f49e2e 100644 --- a/configs/example/gem5_library/x86-spec-cpu2006-benchmarks.py +++ b/configs/example/gem5_library/x86-spec-cpu2006-benchmarks.py @@ -66,6 +66,8 @@ from gem5.components.processors.cpu_types import CPUTypes from gem5.isas import ISA from gem5.coherence_protocol import CoherenceProtocol from gem5.resources.resource import Resource, CustomDiskImageResource +from gem5.simulate.simulator import Simulator +from gem5.simulate.exit_event import ExitEvent from m5.stats.gem5stats import get_simstat from m5.util import warn @@ -265,17 +267,23 @@ board.set_kernel_disk_workload( readfile_contents=command, ) -# We need this for long running processes. -m5.disableAllListeners() -root = Root(full_system=True, system=board) +def handle_exit(): + print("Done bootling Linux") + print("Resetting stats at the start of ROI!") + m5.stats.reset() + yield False # E.g., continue the simulation. + print("Dump stats at the end of the ROI!") + m5.stats.dump() + yield True # Stop the simulation. We're done. -# sim_quantum must be set when KVM cores are used. -root.sim_quantum = int(1e9) - -board._pre_instantiate() -m5.instantiate() +simulator = Simulator( + board=board, + on_exit_event={ + ExitEvent.EXIT: handle_exit(), + }, +) # We maintain the wall clock time. @@ -284,92 +292,10 @@ globalStart = time.time() print("Running the simulation") print("Using KVM cpu") -start_tick = m5.curTick() -end_tick = m5.curTick() m5.stats.reset() -exit_event = m5.simulate() - -if exit_event.getCause() == "m5_exit instruction encountered": - # We have completed booting the OS using KVM cpu - # Reached the start of ROI - - print("Done booting Linux") - print("Resetting stats at the start of ROI!") - - m5.stats.reset() - start_tick = m5.curTick() - - # We switch to timing cpu for detailed simulation. - - processor.switch() -else: - # `m5_exit instruction encountered` was never reached - - print("Unexpected termination of simulation before ROI was reached!") - print( - "Exiting @ tick {} because {}.".format( - m5.curTick(), exit_event.getCause() - ) - ) - exit(-1) - -# Simulate the ROI -exit_event = m5.simulate() - -# Reached the end of ROI -gem5stats = get_simstat(root) - -# We get the number of committed instructions from the timing -# cores. We then sum and print them at the end. - -roi_insts = float( - json.loads(gem5stats.dumps())["system"]["processor"]["cores2"]["core"][ - "exec_context.thread_0" - ]["numInsts"]["value"] -) + float( - json.loads(gem5stats.dumps())["system"]["processor"]["cores3"]["core"][ - "exec_context.thread_0" - ]["numInsts"]["value"] -) - -if exit_event.getCause() == "m5_exit instruction encountered": - print("Dump stats at the end of the ROI!") - m5.stats.dump() - end_tick = m5.curTick() - m5.stats.reset() - -else: - # `m5_exit instruction encountered` was never reached - - print("Unexpected termination of simulation while ROI was being executed!") - print( - "Exiting @ tick {} because {}.".format( - m5.curTick(), exit_event.getCause() - ) - ) - exit(-1) - -# We need to copy back the contents of the `speclogs' directory to -# m5.options.outdir - -exit_event = m5.simulate() - -if exit_event.getCause() == "m5_exit instruction encountered": - print("Output logs copied!") - -else: - print("Unexpected termination of simulation while copying speclogs!") - print( - "Exiting @ tick {} because {}.".format( - m5.curTick(), exit_event.getCause() - ) - ) - exit(-1) - -m5.stats.dump() -end_tick = m5.curTick() -m5.stats.reset() +# We start the simulation +simulator.run() # Simulation is over at this point. We acknowledge that all the simulation # events were successful. @@ -378,9 +304,10 @@ print("All simulation events were successful.") print("Performance statistics:") -print("Simulated time: %.2fs" % ((end_tick - start_tick) / 1e12)) -print("Instructions executed: %d" % ((roi_insts))) -print("Ran a total of", m5.curTick() / 1e12, "simulated seconds") +print("Simulated time: " + ((str(simulator.get_roi_ticks()[0])))) +print( + "Ran a total of", simulator.get_current_tick() / 1e12, "simulated seconds" +) print( "Total wallclock time: %.2fs, %.2f min" % (time.time() - globalStart, (time.time() - globalStart) / 60) diff --git a/configs/example/gem5_library/x86-spec-cpu2017-benchmarks.py b/configs/example/gem5_library/x86-spec-cpu2017-benchmarks.py index 2bc948aea1..c4af7f5dd9 100644 --- a/configs/example/gem5_library/x86-spec-cpu2017-benchmarks.py +++ b/configs/example/gem5_library/x86-spec-cpu2017-benchmarks.py @@ -64,6 +64,8 @@ from gem5.components.processors.cpu_types import CPUTypes from gem5.isas import ISA from gem5.coherence_protocol import CoherenceProtocol from gem5.resources.resource import Resource, CustomDiskImageResource +from gem5.simulate.simulator import Simulator +from gem5.simulate.exit_event import ExitEvent from m5.stats.gem5stats import get_simstat from m5.util import warn @@ -281,17 +283,23 @@ board.set_kernel_disk_workload( readfile_contents=command, ) -# We need this for long running processes. -m5.disableAllListeners() -root = Root(full_system=True, system=board) +def handle_exit(): + print("Done bootling Linux") + print("Resetting stats at the start of ROI!") + m5.stats.reset() + yield False # E.g., continue the simulation. + print("Dump stats at the end of the ROI!") + m5.stats.dump() + yield True # Stop the simulation. We're done. -# sim_quantum must be set when KVM cores are used. -root.sim_quantum = int(1e9) - -board._pre_instantiate() -m5.instantiate() +simulator = Simulator( + board=board, + on_exit_event={ + ExitEvent.EXIT: handle_exit(), + }, +) # We maintain the wall clock time. @@ -300,92 +308,21 @@ globalStart = time.time() print("Running the simulation") print("Using KVM cpu") -start_tick = m5.curTick() -end_tick = m5.curTick() m5.stats.reset() -exit_event = m5.simulate() +# We start the simulation +simulator.run() -if exit_event.getCause() == "m5_exit instruction encountered": - # We have completed booting the OS using KVM cpu - # Reached the start of ROI - - print("Done booting Linux") - print("Resetting stats at the start of ROI!") - - m5.stats.reset() - start_tick = m5.curTick() - - # We switch to timing cpu for detailed simulation. - - processor.switch() -else: - print("Unexpected termination of simulation before ROI was reached!") - print( - "Exiting @ tick {} because {}.".format( - m5.curTick(), exit_event.getCause() - ) - ) - exit(-1) - -# Simulate the ROI -exit_event = m5.simulate() - -# Reached the end of ROI -gem5stats = get_simstat(root) - -# We get the number of committed instructions from the timing -# cores. We then sum and print them at the end. - -roi_insts = float( - json.loads(gem5stats.dumps())["system"]["processor"]["cores2"]["core"][ - "exec_context.thread_0" - ]["numInsts"]["value"] -) + float( - json.loads(gem5stats.dumps())["system"]["processor"]["cores3"]["core"][ - "exec_context.thread_0" - ]["numInsts"]["value"] -) - -if exit_event.getCause() == "m5_exit instruction encountered": - print("Dump stats at the end of the ROI!") - m5.stats.dump() - end_tick = m5.curTick() - m5.stats.reset() - -else: - print("Unexpected termination of simulation while ROI was being executed!") - print( - "Exiting @ tick {} because {}.".format( - m5.curTick(), exit_event.getCause() - ) - ) - exit(-1) - -# We need to copy back the contents of the `speclogs' directory to -# m5.options.outdir - -exit_event = m5.simulate() - -if exit_event.getCause() == "m5_exit instruction encountered": - print("Output logs copied!") - -else: - print("Unexpected termination of simulation while copying speclogs!") - print( - "Exiting @ tick {} because {}.".format( - m5.curTick(), exit_event.getCause() - ) - ) - exit(-1) +# We print the final simulation statistics. print("Done with the simulation") print() print("Performance statistics:") -print("Simulated time in ROI: %.2fs" % ((end_tick - start_tick) / 1e12)) -print("Instructions executed in ROI: %d" % ((roi_insts))) -print("Ran a total of", m5.curTick() / 1e12, "simulated seconds") +print("Simulated time in ROI: " + ((str(simulator.get_roi_ticks()[0])))) +print( + "Ran a total of", simulator.get_current_tick() / 1e12, "simulated seconds" +) print( "Total wallclock time: %.2fs, %.2f min" % (time.time() - globalStart, (time.time() - globalStart) / 60)