From 216311560eb63195f312b0dc76998bbff83cb089 Mon Sep 17 00:00:00 2001 From: Mahyar Samani Date: Tue, 21 Sep 2021 13:32:09 -0700 Subject: [PATCH] tests: Adding tests to evaluate memory modules. This change adds a script to validate the statistics reported by gem5. It also overrides has_dma_ports for TestBoard to allow other cache hierarchies such as MESITwoLevel connect to this board. Change-Id: Iae0e61c1763c099cf10924a08b3e4989dc31e220 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/50752 Reviewed-by: Bobby R. Bruce Maintainer: Bobby R. Bruce Tested-by: kokoro --- .../gem5/components/boards/test_board.py | 4 + tests/gem5/configs/simple_traffic_run.py | 103 +++++++++---- .../traffic_gen/test_memory_traffic_gen.py | 141 +++++++++++++++++- 3 files changed, 214 insertions(+), 34 deletions(-) diff --git a/src/python/gem5/components/boards/test_board.py b/src/python/gem5/components/boards/test_board.py index 4bcefb1bb7..2b80f9d127 100644 --- a/src/python/gem5/components/boards/test_board.py +++ b/src/python/gem5/components/boards/test_board.py @@ -128,3 +128,7 @@ class TestBoard(AbstractBoard): # memory. self.mem_ranges = [AddrRange(memory.get_size())] memory.set_memory_range(self.mem_ranges) + + @overrides(AbstractBoard) + def has_dma_ports(self) -> bool: + return False diff --git a/tests/gem5/configs/simple_traffic_run.py b/tests/gem5/configs/simple_traffic_run.py index 2541d90bcc..f5193351bb 100644 --- a/tests/gem5/configs/simple_traffic_run.py +++ b/tests/gem5/configs/simple_traffic_run.py @@ -25,22 +25,55 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ -This script creates a simple traffic generator. The simulator starts with a -linear traffic generator, and ends with a random traffic generator. It is used -for testing purposes. +This scripts is used for checking the correctness of statistics reported +by the gem5 simulator. It can excercise certain components in the memory +subsystem. The reported values could be used to compare against a validated +set of statistics. """ import m5 - -from m5.objects import Root - import argparse import importlib +from os.path import join +from m5.objects import Root +from m5.stats import gem5stats from gem5.components.boards.test_board import TestBoard -from gem5.components.cachehierarchies.classic.no_cache import NoCache -from gem5.components.memory.single_channel import * -from gem5.components.processors.complex_generator import ComplexGenerator +from gem5.components.processors.linear_generator import LinearGenerator +from gem5.components.processors.random_generator import RandomGenerator + + +generator_class_map = { + "LinearGenerator": LinearGenerator, + "RandomGenerator": RandomGenerator, +} + +generator_initializers = dict(rate="20GB/s") + + +def cache_factory(cache_class): + if cache_class == "NoCache": + from gem5.components.cachehierarchies.classic.no_cache import NoCache + + return NoCache() + elif cache_class == "MESITwoLevel": + from gem5.components.cachehierarchies.ruby\ + .mesi_two_level_cache_hierarchy import ( + MESITwoLevelCacheHierarchy, + ) + + return MESITwoLevelCacheHierarchy( + l1i_size="32KiB", + l1i_assoc="8", + l1d_size="32KiB", + l1d_assoc="8", + l2_size="256KiB", + l2_assoc="4", + num_l2_banks=1, + ) + else: + raise ValueError(f"The cache class {cache_class} is not supported.") + parser = argparse.ArgumentParser( description="A traffic generator that can be used to test a gem5 " @@ -48,41 +81,52 @@ parser = argparse.ArgumentParser( ) parser.add_argument( - "module", + "generator_class", type=str, - help="The python module to import.", + help="The class of generator to use.", + choices=["LinearGenerator", "RandomGenerator"], ) parser.add_argument( - "mem_class", + "cache_class", type=str, - help="The memory class to import and instantiate.", + help="The cache class to import and instantiate.", + choices=["NoCache", "MESITwoLevel"], ) parser.add_argument( - "arguments", + "mem_module", + type=str, + help="The python module to import for memory.", +) + +parser.add_argument( + "mem_class", type=str, help="The memory class to import and instantiate." +) + +parser.add_argument( + "mem_args", nargs="*", help="The arguments needed to instantiate the memory class.", ) args = parser.parse_args() -# This setup does not require a cache heirarchy. We therefore use the `NoCache` -# setup. -cache_hierarchy = NoCache() +generator_class = generator_class_map[args.generator_class] +generator = generator_class(**generator_initializers) -memory_class = getattr(importlib.import_module(args.module), args.mem_class) -memory = memory_class(*args.arguments) +cache_hierarchy = cache_factory(args.cache_class) -cmxgen = ComplexGenerator(num_cores=1) -cmxgen.add_linear(rate="100GB/s") -cmxgen.add_random(block_size=32, rate="50MB/s") +memory_class = getattr( + importlib.import_module(args.mem_module), args.mem_class +) +memory = memory_class(*args.mem_args) # We use the Test Board. This is a special board to run traffic generation # tasks motherboard = TestBoard( clk_freq="3GHz", - processor=cmxgen, # We pass the traffic generator as the processor. + processor=generator, # We pass the traffic generator as the processor. memory=memory, cache_hierarchy=cache_hierarchy, ) @@ -93,15 +137,14 @@ root = Root(full_system=False, system=motherboard) m5.instantiate() -cmxgen.start_traffic() +generator.start_traffic() print("Beginning simulation!") exit_event = m5.simulate() print( "Exiting @ tick {} because {}.".format(m5.curTick(), exit_event.getCause()) ) -cmxgen.start_traffic() -print("The Linear taffic has finished. Swiching to random traffic!") -exit_event = m5.simulate() -print( - "Exiting @ tick {} because {}.".format(m5.curTick(), exit_event.getCause()) -) + +stats = gem5stats.get_simstat(root) +json_out = join(m5.options.outdir, "stats.json") +with open(json_out, "w") as json_stats: + stats.dump(json_stats, indent=2) diff --git a/tests/gem5/traffic_gen/test_memory_traffic_gen.py b/tests/gem5/traffic_gen/test_memory_traffic_gen.py index e761fb6ced..ff08f3da20 100644 --- a/tests/gem5/traffic_gen/test_memory_traffic_gen.py +++ b/tests/gem5/traffic_gen/test_memory_traffic_gen.py @@ -34,9 +34,24 @@ TODO: At present all the Single Channel memory components are tested. This from testlib import * -def test_memory(module: str, memory: str, *args) -> None: +def test_memory( + generator: str, cache: str, module: str, memory: str, *args +) -> None: + protocol_map = {"NoCache": None, "MESITwoLevel": "MESI_Two_Level"} + tag_map = { + "NoCache": constants.quick_tag, + "MESITwoLevel": constants.long_tag, + } + gem5_verify_config( - name="test-memory-" + module + "." + memory, + name="test-memory-" + + generator + + "." + + cache + + "." + + module + + "." + + memory, fixtures=(), verifiers=(), config=joinpath( @@ -47,38 +62,156 @@ def test_memory(module: str, memory: str, *args) -> None: "simple_traffic_run.py", ), config_args=[ + generator, + cache, module, memory, ] + list(args), valid_isas=(constants.null_tag,), + protocol=protocol_map[cache], valid_hosts=constants.supported_hosts, - length=constants.quick_tag, + length=tag_map[cache], ) test_memory( + "LinearGenerator", + "NoCache", "gem5.components.memory.single_channel", "SingleChannelDDR3_1600", "512MiB", ) test_memory( + "LinearGenerator", + "NoCache", "gem5.components.memory.single_channel", "SingleChannelDDR3_2133", "512MiB", ) test_memory( + "LinearGenerator", + "NoCache", "gem5.components.memory.single_channel", "SingleChannelDDR4_2400", "512MiB", ) test_memory( + "LinearGenerator", + "NoCache", "gem5.components.memory.single_channel", "SingleChannelLPDDR3_1600", "512MiB", ) test_memory( + "LinearGenerator", + "NoCache", "gem5.components.memory.single_channel", "SingleChannelHBM", - "512MiB" + "512MiB", +) +test_memory( + "RandomGenerator", + "NoCache", + "gem5.components.memory.single_channel", + "SingleChannelDDR3_1600", + "512MiB", +) +test_memory( + "RandomGenerator", + "NoCache", + "gem5.components.memory.single_channel", + "SingleChannelDDR3_2133", + "512MiB", +) +test_memory( + "RandomGenerator", + "NoCache", + "gem5.components.memory.single_channel", + "SingleChannelDDR4_2400", + "512MiB", +) +test_memory( + "RandomGenerator", + "NoCache", + "gem5.components.memory.single_channel", + "SingleChannelLPDDR3_1600", + "512MiB", +) +test_memory( + "RandomGenerator", + "NoCache", + "gem5.components.memory.single_channel", + "SingleChannelHBM", + "512MiB", +) +test_memory( + "LinearGenerator", + "MESITwoLevel", + "gem5.components.memory.single_channel", + "SingleChannelDDR3_1600", + "512MiB", +) +test_memory( + "LinearGenerator", + "MESITwoLevel", + "gem5.components.memory.single_channel", + "SingleChannelDDR3_2133", + "512MiB", +) +test_memory( + "LinearGenerator", + "MESITwoLevel", + "gem5.components.memory.single_channel", + "SingleChannelDDR4_2400", + "512MiB", +) +test_memory( + "LinearGenerator", + "MESITwoLevel", + "gem5.components.memory.single_channel", + "SingleChannelLPDDR3_1600", + "512MiB", +) +test_memory( + "LinearGenerator", + "MESITwoLevel", + "gem5.components.memory.single_channel", + "SingleChannelHBM", + "512MiB", +) +test_memory( + "RandomGenerator", + "MESITwoLevel", + "gem5.components.memory.single_channel", + "SingleChannelDDR3_1600", + "512MiB", +) +test_memory( + "RandomGenerator", + "MESITwoLevel", + "gem5.components.memory.single_channel", + "SingleChannelDDR3_2133", + "512MiB", +) +test_memory( + "RandomGenerator", + "MESITwoLevel", + "gem5.components.memory.single_channel", + "SingleChannelDDR4_2400", + "512MiB", +) +test_memory( + "RandomGenerator", + "MESITwoLevel", + "gem5.components.memory.single_channel", + "SingleChannelLPDDR3_1600", + "512MiB", +) +test_memory( + "RandomGenerator", + "MESITwoLevel", + "gem5.components.memory.single_channel", + "SingleChannelHBM", + "512MiB", )