gem5-dev@gem5.org

The gem5 Developer List

View all threads

[M] Change in gem5/gem5[develop]: configs: Add --pmu-{dump,reset}-stats-on to Arm baremetal.py.

RC
Richard Cooper (Gerrit)
Wed, May 10, 2023 7:44 AM

Richard Cooper has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/69959?usp=email )

Change subject: configs: Add --pmu-{dump,reset}-stats-on to Arm
baremetal.py.
......................................................................

configs: Add --pmu-{dump,reset}-stats-on to Arm baremetal.py.

Add --pmu-dump-stats-on <event> and --pmu-reset-stats-on <event>
options to the Arm baremetal.py config to optionally dump and/or
reset stats on various PMU events.

These options allow the user to specify which PMU events should cause
the dumping or resetting of gem5 stats. The available <event>s are
PMU enable, disable, reset, and interrupt. Both these CLI
options may be specified multiple times to enable more than one event
to cause a stats dump/reset if desired. Stats are dumped before they
are reset.

These options are useful for sampled simulation workloads (e.g.
SimPoints) which are controlled by the PMU.

Change-Id: Ie2ffe11c6aa1f3a57a58425ccec3681c780065c8
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69959
Maintainer: Jason Lowe-Power power.jg@gmail.com
Tested-by: kokoro noreply+kokoro@google.com
Reviewed-by: Jason Lowe-Power power.jg@gmail.com

M configs/example/arm/baremetal.py
M configs/example/arm/devices.py
2 files changed, 87 insertions(+), 5 deletions(-)

Approvals:
kokoro: Regressions pass
Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved

diff --git a/configs/example/arm/baremetal.py
b/configs/example/arm/baremetal.py
index be72ebe..08af3ef 100644
--- a/configs/example/arm/baremetal.py
+++ b/configs/example/arm/baremetal.py
@@ -44,6 +44,7 @@
from m5.util import addToPath
from m5.objects import *
from m5.options import *
+from gem5.simulate.exit_event import ExitEvent
import argparse

m5.util.addToPath("../..")
@@ -72,6 +73,18 @@
),
}

+pmu_control_events = {

  • "enable": ExitEvent.PERF_COUNTER_ENABLE,
  • "disable": ExitEvent.PERF_COUNTER_DISABLE,
  • "reset": ExitEvent.PERF_COUNTER_RESET,
    +}

+pmu_interrupt_events = {

  • "interrupt": ExitEvent.PERF_COUNTER_INTERRUPT,
    +}

+pmu_stats_events = dict(**pmu_control_events, **pmu_interrupt_events)
+

def create_cow_image(name):
"""Helper function to create a Copy-on-Write disk image"""
@@ -158,9 +171,22 @@
system.workload = workload_class(object_file, system)

  if args.with_pmu:
  •    enabled_pmu_events = set(
    
  •        (*args.pmu_dump_stats_on, *args.pmu_reset_stats_on)
    
  •    )
    
  •    exit_sim_on_control = bool(
    
  •        enabled_pmu_events & set(pmu_control_events.keys())
    
  •    )
    
  •    exit_sim_on_interrupt = bool(
    
  •        enabled_pmu_events & set(pmu_interrupt_events.keys())
    
  •    )
        for cluster in system.cpu_cluster:
            interrupt_numbers = [args.pmu_ppi_number] * len(cluster)
    
  •        cluster.addPMUs(interrupt_numbers)
    
  •        cluster.addPMUs(
    
  •            interrupt_numbers,
    
  •            exit_sim_on_control=exit_sim_on_control,
    
  •            exit_sim_on_interrupt=exit_sim_on_interrupt,
    
  •        )
    
    if args.exit_on_uart_eot:
        for uart in system.realview.uart:
    

@@ -174,14 +200,35 @@
if args.checkpoint:
print(f"Checkpoint directory: {cptdir}")

  • pmu_exit_msgs = tuple(evt.value for evt in pmu_stats_events.values())
  • pmu_stats_dump_msgs = tuple(
  •    pmu_stats_events[evt].value for evt in set(args.pmu_dump_stats_on)
    
  • )
  • pmu_stats_reset_msgs = tuple(
  •    pmu_stats_events[evt].value for evt in set(args.pmu_reset_stats_on)
    
  • )
  • while True:
        event = m5.simulate()
        exit_msg = event.getCause()
    
  •    if exit_msg == "checkpoint":
    
  •        print("Dropping checkpoint at tick %d" % m5.curTick())
    
  •    if exit_msg == ExitEvent.CHECKPOINT.value:
    
  •        print(f"Dropping checkpoint at tick {m5.curTick():d}")
            cpt_dir = os.path.join(m5.options.outdir, "cpt.%d" %  
    

m5.curTick())
m5.checkpoint(os.path.join(cpt_dir))
print("Checkpoint done.")

  •    elif exit_msg in pmu_exit_msgs:
    
  •        if exit_msg in pmu_stats_dump_msgs:
    
  •            print(
    
  •                f"Dumping stats at tick {m5.curTick():d}, "
    
  •                f"due to {exit_msg}"
    
  •            )
    
  •            m5.stats.dump()
    
  •        if exit_msg in pmu_stats_reset_msgs:
    
  •            print(
    
  •                f"Resetting stats at tick {m5.curTick():d}, "
    
  •                f"due to {exit_msg}"
    
  •            )
    
  •            m5.stats.reset()
        else:
            print(f"{exit_msg} ({event.getCode()}) @ {m5.curTick()}")
            break
    

@@ -284,6 +331,26 @@
"Must be an integer and a valid PPI number (16 <= int_num <= 31).",
)
parser.add_argument(

  •    "--pmu-dump-stats-on",
    
  •    type=str,
    
  •    default=[],
    
  •    action="append",
    
  •    choices=pmu_stats_events.keys(),
    
  •    help="Specify the PMU events on which to dump the gem5 stats. "
    
  •    "This option may be specified multiple times to enable multiple "
    
  •    "PMU events.",
    
  • )
  • parser.add_argument(
  •    "--pmu-reset-stats-on",
    
  •    type=str,
    
  •    default=[],
    
  •    action="append",
    
  •    choices=pmu_stats_events.keys(),
    
  •    help="Specify the PMU events on which to reset the gem5 stats. "
    
  •    "This option may be specified multiple times to enable multiple "
    
  •    "PMU events.",
    
  • )
  • parser.add_argument(
    "--exit-on-uart-eot",
    action="store_true",
    help="Exit simulation if any of the UARTs receive an EOT. Many "
    diff --git a/configs/example/arm/devices.py b/configs/example/arm/devices.py
    index 02574d2..6c6474c 100644
    --- a/configs/example/arm/devices.py
    +++ b/configs/example/arm/devices.py
    @@ -1,4 +1,4 @@
    -# Copyright (c) 2016-2017, 2019, 2021-2022 Arm Limited
    +# Copyright (c) 2016-2017, 2019, 2021-2023 Arm Limited

All rights reserved.

The license below extends only to copyright in the software and shall

@@ -147,7 +147,13 @@
cpu.connectCachedPorts(self.toL2Bus.cpu_side_ports)
self.toL2Bus.mem_side_ports = self.l2.cpu_side

  • def addPMUs(self, ints, events=[]):
  • def addPMUs(
  •    self,
    
  •    ints,
    
  •    events=[],
    
  •    exit_sim_on_control=False,
    
  •    exit_sim_on_interrupt=False,
    
  • ):
    """
    Instantiates 1 ArmPMU per PE. The method is accepting a list of
    interrupt numbers (ints) used by the PMU and a list of events to
    @@ -159,12 +165,21 @@
    :type ints: List[int]
    :param events: Additional events to be measured by the PMUs
    :type events: List[Union[ProbeEvent, SoftwareIncrement]]
  •    :param exit_sim_on_control: If true, exit the sim loop when the  
    

PMU is

  •        enabled, disabled, or reset.
    
  •    :type exit_on_control: bool
    
  •    :param exit_sim_on_interrupt: If true, exit the sim loop when the  
    

PMU

  •        triggers an interrupt.
    
  •    :type exit_on_control: bool
    
  •     """
        assert len(ints) == len(self.cpus)
        for cpu, pint in zip(self.cpus, ints):
            int_cls = ArmPPI if pint < 32 else ArmSPI
            for isa in cpu.isa:
                isa.pmu = ArmPMU(interrupt=int_cls(num=pint))
    
  •            isa.pmu.exitOnPMUControl = exit_sim_on_control
    
  •            isa.pmu.exitOnPMUInterrupt = exit_sim_on_interrupt
                isa.pmu.addArchEvents(
                    cpu=cpu,
                    itb=cpu.mmu.itb,
    

--
To view, visit
https://gem5-review.googlesource.com/c/public/gem5/+/69959?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings?usp=email

Gerrit-MessageType: merged
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: Ie2ffe11c6aa1f3a57a58425ccec3681c780065c8
Gerrit-Change-Number: 69959
Gerrit-PatchSet: 3
Gerrit-Owner: Richard Cooper richard.cooper@arm.com
Gerrit-Reviewer: Jason Lowe-Power jason@lowepower.com
Gerrit-Reviewer: Jason Lowe-Power power.jg@gmail.com
Gerrit-Reviewer: Richard Cooper richard.cooper@arm.com
Gerrit-Reviewer: kokoro noreply+kokoro@google.com

Richard Cooper has submitted this change. ( https://gem5-review.googlesource.com/c/public/gem5/+/69959?usp=email ) Change subject: configs: Add --pmu-{dump,reset}-stats-on to Arm baremetal.py. ...................................................................... configs: Add --pmu-{dump,reset}-stats-on to Arm baremetal.py. Add `--pmu-dump-stats-on <event>` and `--pmu-reset-stats-on <event>` options to the Arm `baremetal.py` config to optionally dump and/or reset stats on various PMU events. These options allow the user to specify which PMU events should cause the dumping or resetting of gem5 stats. The available `<event>`s are PMU `enable`, `disable`, `reset`, and `interrupt`. Both these CLI options may be specified multiple times to enable more than one event to cause a stats dump/reset if desired. Stats are dumped before they are reset. These options are useful for sampled simulation workloads (e.g. SimPoints) which are controlled by the PMU. Change-Id: Ie2ffe11c6aa1f3a57a58425ccec3681c780065c8 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/69959 Maintainer: Jason Lowe-Power <power.jg@gmail.com> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> --- M configs/example/arm/baremetal.py M configs/example/arm/devices.py 2 files changed, 87 insertions(+), 5 deletions(-) Approvals: kokoro: Regressions pass Jason Lowe-Power: Looks good to me, approved; Looks good to me, approved diff --git a/configs/example/arm/baremetal.py b/configs/example/arm/baremetal.py index be72ebe..08af3ef 100644 --- a/configs/example/arm/baremetal.py +++ b/configs/example/arm/baremetal.py @@ -44,6 +44,7 @@ from m5.util import addToPath from m5.objects import * from m5.options import * +from gem5.simulate.exit_event import ExitEvent import argparse m5.util.addToPath("../..") @@ -72,6 +73,18 @@ ), } +pmu_control_events = { + "enable": ExitEvent.PERF_COUNTER_ENABLE, + "disable": ExitEvent.PERF_COUNTER_DISABLE, + "reset": ExitEvent.PERF_COUNTER_RESET, +} + +pmu_interrupt_events = { + "interrupt": ExitEvent.PERF_COUNTER_INTERRUPT, +} + +pmu_stats_events = dict(**pmu_control_events, **pmu_interrupt_events) + def create_cow_image(name): """Helper function to create a Copy-on-Write disk image""" @@ -158,9 +171,22 @@ system.workload = workload_class(object_file, system) if args.with_pmu: + enabled_pmu_events = set( + (*args.pmu_dump_stats_on, *args.pmu_reset_stats_on) + ) + exit_sim_on_control = bool( + enabled_pmu_events & set(pmu_control_events.keys()) + ) + exit_sim_on_interrupt = bool( + enabled_pmu_events & set(pmu_interrupt_events.keys()) + ) for cluster in system.cpu_cluster: interrupt_numbers = [args.pmu_ppi_number] * len(cluster) - cluster.addPMUs(interrupt_numbers) + cluster.addPMUs( + interrupt_numbers, + exit_sim_on_control=exit_sim_on_control, + exit_sim_on_interrupt=exit_sim_on_interrupt, + ) if args.exit_on_uart_eot: for uart in system.realview.uart: @@ -174,14 +200,35 @@ if args.checkpoint: print(f"Checkpoint directory: {cptdir}") + pmu_exit_msgs = tuple(evt.value for evt in pmu_stats_events.values()) + pmu_stats_dump_msgs = tuple( + pmu_stats_events[evt].value for evt in set(args.pmu_dump_stats_on) + ) + pmu_stats_reset_msgs = tuple( + pmu_stats_events[evt].value for evt in set(args.pmu_reset_stats_on) + ) + while True: event = m5.simulate() exit_msg = event.getCause() - if exit_msg == "checkpoint": - print("Dropping checkpoint at tick %d" % m5.curTick()) + if exit_msg == ExitEvent.CHECKPOINT.value: + print(f"Dropping checkpoint at tick {m5.curTick():d}") cpt_dir = os.path.join(m5.options.outdir, "cpt.%d" % m5.curTick()) m5.checkpoint(os.path.join(cpt_dir)) print("Checkpoint done.") + elif exit_msg in pmu_exit_msgs: + if exit_msg in pmu_stats_dump_msgs: + print( + f"Dumping stats at tick {m5.curTick():d}, " + f"due to {exit_msg}" + ) + m5.stats.dump() + if exit_msg in pmu_stats_reset_msgs: + print( + f"Resetting stats at tick {m5.curTick():d}, " + f"due to {exit_msg}" + ) + m5.stats.reset() else: print(f"{exit_msg} ({event.getCode()}) @ {m5.curTick()}") break @@ -284,6 +331,26 @@ "Must be an integer and a valid PPI number (16 <= int_num <= 31).", ) parser.add_argument( + "--pmu-dump-stats-on", + type=str, + default=[], + action="append", + choices=pmu_stats_events.keys(), + help="Specify the PMU events on which to dump the gem5 stats. " + "This option may be specified multiple times to enable multiple " + "PMU events.", + ) + parser.add_argument( + "--pmu-reset-stats-on", + type=str, + default=[], + action="append", + choices=pmu_stats_events.keys(), + help="Specify the PMU events on which to reset the gem5 stats. " + "This option may be specified multiple times to enable multiple " + "PMU events.", + ) + parser.add_argument( "--exit-on-uart-eot", action="store_true", help="Exit simulation if any of the UARTs receive an EOT. Many " diff --git a/configs/example/arm/devices.py b/configs/example/arm/devices.py index 02574d2..6c6474c 100644 --- a/configs/example/arm/devices.py +++ b/configs/example/arm/devices.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016-2017, 2019, 2021-2022 Arm Limited +# Copyright (c) 2016-2017, 2019, 2021-2023 Arm Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -147,7 +147,13 @@ cpu.connectCachedPorts(self.toL2Bus.cpu_side_ports) self.toL2Bus.mem_side_ports = self.l2.cpu_side - def addPMUs(self, ints, events=[]): + def addPMUs( + self, + ints, + events=[], + exit_sim_on_control=False, + exit_sim_on_interrupt=False, + ): """ Instantiates 1 ArmPMU per PE. The method is accepting a list of interrupt numbers (ints) used by the PMU and a list of events to @@ -159,12 +165,21 @@ :type ints: List[int] :param events: Additional events to be measured by the PMUs :type events: List[Union[ProbeEvent, SoftwareIncrement]] + :param exit_sim_on_control: If true, exit the sim loop when the PMU is + enabled, disabled, or reset. + :type exit_on_control: bool + :param exit_sim_on_interrupt: If true, exit the sim loop when the PMU + triggers an interrupt. + :type exit_on_control: bool + """ assert len(ints) == len(self.cpus) for cpu, pint in zip(self.cpus, ints): int_cls = ArmPPI if pint < 32 else ArmSPI for isa in cpu.isa: isa.pmu = ArmPMU(interrupt=int_cls(num=pint)) + isa.pmu.exitOnPMUControl = exit_sim_on_control + isa.pmu.exitOnPMUInterrupt = exit_sim_on_interrupt isa.pmu.addArchEvents( cpu=cpu, itb=cpu.mmu.itb, -- To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/69959?usp=email To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings?usp=email Gerrit-MessageType: merged Gerrit-Project: public/gem5 Gerrit-Branch: develop Gerrit-Change-Id: Ie2ffe11c6aa1f3a57a58425ccec3681c780065c8 Gerrit-Change-Number: 69959 Gerrit-PatchSet: 3 Gerrit-Owner: Richard Cooper <richard.cooper@arm.com> Gerrit-Reviewer: Jason Lowe-Power <jason@lowepower.com> Gerrit-Reviewer: Jason Lowe-Power <power.jg@gmail.com> Gerrit-Reviewer: Richard Cooper <richard.cooper@arm.com> Gerrit-Reviewer: kokoro <noreply+kokoro@google.com>