From 02ed53ff6b19c4539ce0c21a2dc336d2aa3d4b28 Mon Sep 17 00:00:00 2001 From: Hoa Nguyen Date: Tue, 12 Apr 2022 14:57:34 -0700 Subject: [PATCH] stdlib,configs,tests: Examples of saving/restoring checkpoints This change consists of two scripts, - riscv-hello-save-checkpoint.py: runs the first million ticks of the simulation and save a checkpoint. - riscv-hello-load-checkpoint.py: loads the above checkpoint, and runs the rest of the simulation. This change also adds the two scripts as part of quick tests. Change-Id: I7bd97ba953fab52f298cbbcf213f2ea5c185cc38 Signed-off-by: Hoa Nguyen Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/58829 Reviewed-by: Bobby Bruce Tested-by: kokoro Maintainer: Bobby Bruce --- .../riscv-hello-restore-checkpoint.py | 112 ++++++++++++++++++ .../riscv-hello-save-checkpoint.py | 108 +++++++++++++++++ .../test_gem5_library_examples.py | 37 ++++++ 3 files changed, 257 insertions(+) create mode 100644 configs/example/gem5_library/checkpoints/riscv-hello-restore-checkpoint.py create mode 100644 configs/example/gem5_library/checkpoints/riscv-hello-save-checkpoint.py diff --git a/configs/example/gem5_library/checkpoints/riscv-hello-restore-checkpoint.py b/configs/example/gem5_library/checkpoints/riscv-hello-restore-checkpoint.py new file mode 100644 index 0000000000..4b0626790a --- /dev/null +++ b/configs/example/gem5_library/checkpoints/riscv-hello-restore-checkpoint.py @@ -0,0 +1,112 @@ +# Copyright (c) 2022 The Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +""" +This gem5 configuation script creates a simple board sharing the same +structure as the one in +configs/example/gem5_library/checkpoint/riscv-hello-save-checkpoint.py. +This script restores the checkpoint generated by the above script, and +runs the rest of "riscv-hello" binary simulation. +This configuration serves as an example of restoring a checkpoint. + +This is setup is the close to the simplest setup possible using the gem5 +library. It does not contain any kind of caching, IO, or any non-essential +components. + +Usage +----- + +``` +scons build/RISCV/gem5.opt +./build/RISCV/gem5.opt \ + configs/example/gem5_library/checkpoint/riscv-hello-restore-checkpoint.py +``` +""" + +from gem5.isas import ISA +from gem5.utils.requires import requires +from gem5.resources.resource import Resource +from gem5.components.memory import SingleChannelDDR3_1600 +from gem5.components.processors.cpu_types import CPUTypes +from gem5.components.boards.simple_board import SimpleBoard +from gem5.components.cachehierarchies.classic.no_cache import NoCache +from gem5.components.processors.simple_processor import SimpleProcessor +from gem5.simulate.simulator import Simulator + +# This check ensures the gem5 binary is compiled to the RISCV ISA target. +# If not, an exception will be thrown. +requires(isa_required=ISA.RISCV) + +# In this setup we don't have a cache. `NoCache` can be used for such setups. +cache_hierarchy = NoCache() + +# We use a single channel DDR3_1600 memory system +memory = SingleChannelDDR3_1600(size="32MB") + +# We use a simple Timing processor with one core. +processor = SimpleProcessor(cpu_type=CPUTypes.TIMING, isa=ISA.RISCV, + num_cores=1) + +# The gem5 library simble board which can be used to run simple SE-mode +# simulations. +board = SimpleBoard( + clk_freq="3GHz", + processor=processor, + memory=memory, + cache_hierarchy=cache_hierarchy, +) + +# Here we set the workload. In this case we want to run a simple "Hello World!" +# program compiled to the RISCV ISA. The `Resource` class will automatically +# download the binary from the gem5 Resources cloud bucket if it's not already +# present. +board.set_se_binary_workload( + # the workload should be the same as the save-checkpoint script + Resource("riscv-hello") +) + +# Getting the pre-taken checkpoint from gem5-resources. This checkpoint +# was taken from running this gem5 configuration script, +# configs/example/gem5_library/checkpoints/riscv-hello-save-checkpoint.py +checkpoint_resource = Resource("riscv-hello-example-checkpoint") + +# Now we restore the checkpoint by passing the path to the checkpoint to +# the Simulator object. The checkpoint_path could be a string containing +# the path to the checkpoint folder. However, here, we use gem5 resources +# to automatically download the checkpoint folder, and use .get_local_path() +# to obtain the path to that folder. +checkpoint_path = checkpoint_resource.get_local_path() +print("Restore a checkpoint at", checkpoint_path) +simulator = Simulator(board=board, full_system=False, + checkpoint_path=checkpoint_path) +simulator.run() + +print( + "Exiting @ tick {} because {}.".format( + simulator.get_current_tick(), + simulator.get_last_exit_event_cause(), + ) +) diff --git a/configs/example/gem5_library/checkpoints/riscv-hello-save-checkpoint.py b/configs/example/gem5_library/checkpoints/riscv-hello-save-checkpoint.py new file mode 100644 index 0000000000..fd81d45322 --- /dev/null +++ b/configs/example/gem5_library/checkpoints/riscv-hello-save-checkpoint.py @@ -0,0 +1,108 @@ +# Copyright (c) 2022 The Regents of the University of California +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer; +# redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution; +# neither the name of the copyright holders nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +""" +This gem5 configuation script creates a simple board to run the first +10^6 ticks of "riscv-hello" binary simulation and saves a checkpoint. +This configuration serves as an example of taking a checkpoint. + +This is setup is the close to the simplest setup possible using the gem5 +library. It does not contain any kind of caching, IO, or any non-essential +components. + +Usage +----- + +``` +scons build/RISCV/gem5.opt +./build/RISCV/gem5.opt \ + configs/example/gem5_library/checkpoint/riscv-hello-save-checkpoint.py +``` +""" + +from gem5.isas import ISA +from gem5.utils.requires import requires +from gem5.resources.resource import Resource +from gem5.components.memory import SingleChannelDDR3_1600 +from gem5.components.processors.cpu_types import CPUTypes +from gem5.components.boards.simple_board import SimpleBoard +from gem5.components.cachehierarchies.classic.no_cache import NoCache +from gem5.components.processors.simple_processor import SimpleProcessor +from gem5.simulate.simulator import Simulator + +# This check ensures the gem5 binary is compiled to the RISCV ISA target. +# If not, an exception will be thrown. +requires(isa_required=ISA.RISCV) + +# In this setup we don't have a cache. `NoCache` can be used for such setups. +cache_hierarchy = NoCache() + +# We use a single channel DDR3_1600 memory system +memory = SingleChannelDDR3_1600(size="32MB") + +# We use a simple Timing processor with one core. +processor = SimpleProcessor(cpu_type=CPUTypes.TIMING, isa=ISA.RISCV, + num_cores=1) + +# The gem5 library simble board which can be used to run simple SE-mode +# simulations. +board = SimpleBoard( + clk_freq="3GHz", + processor=processor, + memory=memory, + cache_hierarchy=cache_hierarchy, +) + +# Here we set the workload. In this case we want to run a simple "Hello World!" +# program compiled to the RISCV ISA. The `Resource` class will automatically +# download the binary from the gem5 Resources cloud bucket if it's not already +# present. +board.set_se_binary_workload( + # The `Resource` class reads the `resources.json` file from the gem5 + # resources repository: + # https://gem5.googlesource.com/public/gem5-resource. + # Any resource specified in this file will be automatically retrieved. + # At the time of writing, this file is a WIP and does not contain all + # resources. Jira ticket: https://gem5.atlassian.net/browse/GEM5-1096 + Resource("riscv-hello") +) + +# Lastly we run the simulation. +max_ticks = 10**6 +simulator = Simulator(board=board, full_system=False) +simulator.run(max_ticks = max_ticks) + +print( + "Exiting @ tick {} because {}.".format( + simulator.get_current_tick(), + simulator.get_last_exit_event_cause(), + ) +) + +checkpoint_path = "riscv-hello-checkpoint/" +print("Taking a checkpoint at", checkpoint_path) +simulator.save_checkpoint(checkpoint_path) +print("Done taking a checkpoint") diff --git a/tests/gem5/gem5_library_example_tests/test_gem5_library_examples.py b/tests/gem5/gem5_library_example_tests/test_gem5_library_examples.py index 6db082a5d6..805f942e16 100644 --- a/tests/gem5/gem5_library_example_tests/test_gem5_library_examples.py +++ b/tests/gem5/gem5_library_example_tests/test_gem5_library_examples.py @@ -33,6 +33,8 @@ import re import os hello_verifier = verifier.MatchRegex(re.compile(r"Hello world!")) +save_checkpoint_verifier = verifier.MatchRegex( + re.compile(r"Done taking a checkpoint")) gem5_verify_config( name="test-gem5-library-example-arm-hello", @@ -51,6 +53,41 @@ gem5_verify_config( length=constants.quick_tag, ) +gem5_verify_config( + name="test-gem5-library-riscv-hello-save-checkpoint", + fixtures=(), + verifiers=(save_checkpoint_verifier,), + config=joinpath( + config.base_dir, + "configs", + "example", + "gem5_library", + "checkpoints", + "riscv-hello-save-checkpoint.py" + ), + config_args=[], + valid_isas=(constants.riscv_tag,), + valid_hosts=constants.supported_hosts, + length=constants.quick_tag, +) + +gem5_verify_config( + name="test-gem5-library-riscv-hello-restore-checkpoint", + fixtures=(), + verifiers=(hello_verifier,), + config=joinpath( + config.base_dir, + "configs", + "example", + "gem5_library", + "checkpoints", + "riscv-hello-restore-checkpoint.py" + ), + config_args=[], + valid_isas=(constants.riscv_tag,), + valid_hosts=constants.supported_hosts, + length=constants.quick_tag, +) if os.access("/dev/kvm", mode=os.R_OK | os.W_OK): # The x86-ubuntu-run uses KVM cores, this test will therefore only be run