From f59d860e5104a4f073c7b108b576b88afec1e5cb Mon Sep 17 00:00:00 2001 From: "Bobby R. Bruce" Date: Mon, 30 Jan 2023 01:29:45 +0000 Subject: [PATCH] stdlib: Add looppoint example scripts Change-Id: If9827af9ba7958af492a6c09cf83e4f6dac9a2eb Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/67493 Tested-by: kokoro Maintainer: Bobby Bruce Reviewed-by: Bobby Bruce --- .../create-looppoint-checkpoints.py | 155 ++++++++++++++++++ .../restore-looppoint-checkpoint.py | 150 +++++++++++++++++ 2 files changed, 305 insertions(+) create mode 100644 configs/example/gem5_library/looppoints/create-looppoint-checkpoints.py create mode 100644 configs/example/gem5_library/looppoints/restore-looppoint-checkpoint.py diff --git a/configs/example/gem5_library/looppoints/create-looppoint-checkpoints.py b/configs/example/gem5_library/looppoints/create-looppoint-checkpoints.py new file mode 100644 index 0000000000..1d8525fe77 --- /dev/null +++ b/configs/example/gem5_library/looppoints/create-looppoint-checkpoints.py @@ -0,0 +1,155 @@ +# Copyright (c) 2023 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 configuration script shows an example of how to take checkpoints for +LoopPoint using the gem5 stdlib. To take checkpoints for LoopPoint simulation +regions, there must be a LoopPoint data file generated by Pin or the gem5 +simulator. With the information in the LoopPoint data file, the stdlib +modules will take checkpoints at the beginning of the simulation regions +(warmup region included if it exists) and record all restore needed information +into a JSON file. The JSON file is needed for later restoring, so please call +`looppoint.output_json_file()` at the end of the simulation. + +This script builds a simple board with the gem5 stdlib with no cache and a +simple memory structure to take checkpoints. Some of the components, such as +cache hierarchy, can be changed when restoring checkpoints. + +Usage +----- +``` +scons build/X86/gem5.opt +./build/X86/gem5.opt \ + configs/example/gem5_library/looppoints/create-looppoint-checkpoint.py +``` +""" + +from gem5.simulate.exit_event import ExitEvent +from gem5.simulate.simulator import Simulator +from gem5.utils.requires import requires +from gem5.components.cachehierarchies.classic.no_cache import NoCache +from gem5.components.boards.simple_board import SimpleBoard +from gem5.components.memory.single_channel import SingleChannelDDR3_1600 +from gem5.components.processors.simple_processor import SimpleProcessor +from gem5.components.processors.cpu_types import CPUTypes +from gem5.isas import ISA +from gem5.resources.resource import obtain_resource +from pathlib import Path +from gem5.simulate.exit_event_generators import ( + looppoint_save_checkpoint_generator, +) +from gem5.utils.looppoint import LoopPointCheckpoint +import argparse + +requires(isa_required=ISA.X86) + +parser = argparse.ArgumentParser( + description="An example looppoint workload file path" +) + +# The lone arguments is a file path to a directory to store the checkpoints. + +parser.add_argument( + "--checkpoint-path", + type=str, + required=False, + default="looppoint_checkpoints_folder", + help="The directory to store the checkpoints.", +) + +args = parser.parse_args() + +# When taking a checkpoint, the cache state is not saved, so the cache +# hierarchy can be changed completely when restoring from a checkpoint. +# By using NoCache() to take checkpoints, it can slightly improve the +# performance when running in atomic mode, and it will not put any restrictions +# on what people can do with the checkpoints. +cache_hierarchy = NoCache() + + +# Using simple memory to take checkpoints might slightly imporve the +# performance in atomic mode. The memory structure can be changed when +# restoring from a checkpoint, but the size of the memory must be equal or +# greater to that taken when creating the checkpoint. +memory = SingleChannelDDR3_1600(size="2GB") + +processor = SimpleProcessor( + cpu_type=CPUTypes.ATOMIC, + isa=ISA.X86, + # LoopPoint can work with multicore workloads + num_cores=9, +) + +looppoint = LoopPointCheckpoint( + # Pass in the LoopPoint data file + looppoint_file=Path( + obtain_resource( + "x86-matrix-multiply-omp-100-8-global-pinpoints" + ).get_local_path() + ), + # True if the LoopPoint data file is a csv generated by Pin. + # False if it is a JSON file generated by the gem5 simulator. + if_csv=True, +) + +board = SimpleBoard( + clk_freq="3GHz", + processor=processor, + memory=memory, + cache_hierarchy=cache_hierarchy, +) + +board.set_se_looppoint_workload( + binary=obtain_resource("x86-matrix-multiply-omp"), + arguments=[100, 8], + # Pass LoopPoint module into the board + looppoint=looppoint, +) + +dir = Path(args.checkpoint_path) +dir.mkdir(exist_ok=True) + +simulator = Simulator( + board=board, + on_exit_event={ + ExitEvent.SIMPOINT_BEGIN: looppoint_save_checkpoint_generator( + checkpoint_dir=dir, + looppoint=looppoint, + # True if the relative PC count pairs should be updated during the + # simulation. Default as True. + update_relatives=True, + # True if the simulation loop should exit after all the PC count + # pairs in the LoopPoint data file have been encountered. Default + # as True. + exit_when_empty=True, + ) + }, +) + +simulator.run() + +# Output the JSON file +looppoint.output_json_file() diff --git a/configs/example/gem5_library/looppoints/restore-looppoint-checkpoint.py b/configs/example/gem5_library/looppoints/restore-looppoint-checkpoint.py new file mode 100644 index 0000000000..28645259d0 --- /dev/null +++ b/configs/example/gem5_library/looppoints/restore-looppoint-checkpoint.py @@ -0,0 +1,150 @@ +# Copyright (c) 2023 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 configuration script shows an example of how to restore a checkpoint that +was taken for a LoopPoint simulation region in the example-restore.py. +All the LoopPoint information should be passed in through the JSON file +generated by the gem5 simulator when all the checkpoints were taken. + +This script builds a more complex board than the board used for taking +checkpoints. + +Usage +----- +``` +./build/X86/gem5.opt \ + configs/example/gem5_library/looppoints/restore-looppoint-checkpoint.py +``` +""" +import argparse + +from gem5.simulate.exit_event import ExitEvent +from gem5.simulate.simulator import Simulator +from gem5.utils.requires import requires +from gem5.components.cachehierarchies.classic.private_l1_private_l2_cache_hierarchy import ( + PrivateL1PrivateL2CacheHierarchy, +) +from gem5.components.boards.simple_board import SimpleBoard +from gem5.components.memory import DualChannelDDR4_2400 +from gem5.components.processors.simple_processor import SimpleProcessor +from gem5.components.processors.cpu_types import CPUTypes +from gem5.isas import ISA +from gem5.resources.resource import obtain_resource +from pathlib import Path +from gem5.utils.looppoint import LoopPointRestore +from m5.stats import reset, dump + +requires(isa_required=ISA.X86) + +parser = argparse.ArgumentParser(description="An restore checkpoint script.") + +parser.add_argument( + "--checkpoint-region", + type=str, + required=False, + choices=( + "1", + "2", + "3", + "5", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + ), + default="1", + help="The checkpoint region to restore from.", +) +args = parser.parse_args() + +# The cache hierarchy can be different from the cache hierarchy used in taking +# the checkpoints +cache_hierarchy = PrivateL1PrivateL2CacheHierarchy( + l1d_size="32kB", + l1i_size="32kB", + l2_size="256kB", +) + +# The memory structure can be different from the memory structure used in +# taking the checkpoints, but the size of the memory must be equal or larger. +memory = DualChannelDDR4_2400(size="2GB") + +processor = SimpleProcessor( + cpu_type=CPUTypes.TIMING, + isa=ISA.X86, + # The number of cores must be equal or greater than that used when taking + # the checkpoint. + num_cores=9, +) + +board = SimpleBoard( + clk_freq="3GHz", + processor=processor, + memory=memory, + cache_hierarchy=cache_hierarchy, +) + +looppoint = LoopPointRestore( + looppoint_file=Path( + obtain_resource( + "x86-matrix-multiply-omp-100-8-looppoint" + ).get_local_path() + ), + region_id=args.checkpoint_region, +) + +board.set_se_looppoint_workload( + binary=obtain_resource("x86-matrix-multiply-omp"), looppoint=looppoint +) + +# This generator will dump the stats and exit the simulation loop when the +# simulation region reaches its end. In the case there is a warmup interval, +# the simulation stats are reset after the warmup is complete. +def reset_and_dump(): + if len(looppoint.get_targets()) > 1: + print("Warmup region ended. Resetting stats.") + reset() + yield False + print("Region ended. Dumping stats.") + dump() + yield True + + +simulator = Simulator( + board=board, + checkpoint_path=obtain_resource( + f"x86-matrix-multiply-omp-100-8-looppoint-checkpoint-region-{args.checkpoint_region}" + ).get_local_path(), + on_exit_event={ExitEvent.SIMPOINT_BEGIN: reset_and_dump()}, +) + +simulator.run()