gem5-resources icon indicating copy to clipboard operation
gem5-resources copied to clipboard

resources: Update npb from 3.3.1 to 3.4.2

Open Harshil2107 opened this issue 9 months ago • 2 comments

Harshil2107 avatar May 07 '24 22:05 Harshil2107

I will push another commit updating the ROIs to the one that Hoa is using. I have kept the code consistent with the original ROI begin and end events.

Harshil2107 avatar May 07 '24 22:05 Harshil2107

I don't know if I like having 70K lines of code change here...

Could you rename NPB3.3.1 to just NPB in one commit and then overwrite it with 3.4.2? That way we have a diff which is "updates to NPB" instead of deleting the old one and adding the new one?

powerjg avatar May 08 '24 00:05 powerjg

The benchmarks are being built. The issue is that when I run the x86 image with gem5 it is not able to catch the workbegin and workend exit events thus not being able to return stats.

The code the build the image is: https://github.com/Harshil2107/gem5-resources-repo/tree/npb-img In the repo Update line 58 in packer file with path to the npb OMP directory.

The test script I used is:

import argparse
import time

import m5
from m5.objects import Root
from m5.stats.gem5stats import get_simstat
from m5.util import warn

from gem5.coherence_protocol import CoherenceProtocol
from gem5.components.boards.x86_board import X86Board
from gem5.components.memory import DualChannelDDR4_2400
from gem5.components.processors.cpu_types import CPUTypes
from gem5.components.processors.simple_switchable_processor import (
    SimpleSwitchableProcessor,
)
from gem5.isas import ISA
from gem5.resources.resource import obtain_resource, DiskImageResource, KernelResource
from gem5.simulate.simulator import (
    ExitEvent,
    Simulator,
)
from gem5.utils.requires import requires

requires(
    isa_required=ISA.X86,
    coherence_protocol_required=CoherenceProtocol.MESI_TWO_LEVEL,
    kvm_required=True,
)

# Following are the list of benchmark programs for npb.

# We are restricting classes of NPB to A, B and C as the other classes (D and
# F) require main memory size of more than 3 GB. The X86Board is currently
# limited to 3 GB of memory. This limitation is explained later in line 136.

# The resource disk has binaries for class D. However, only `ep` benchmark
# works with class D in the current configuration. More information on the
# memory footprint for NPB is available at https://arxiv.org/abs/2010.13216

parser = argparse.ArgumentParser(
    description="An example configuration script to run the npb benchmarks."
)

npb_suite = obtain_resource("npb-benchmark-suite", resource_version="1.0.0")
# The only positional argument accepted is the benchmark name in this script.

parser.add_argument(
    "--ticks",
    type=int,
    help="Optionally put the maximum number of ticks to execute during the "
    "ROI. It accepts an integer value.",
)

args = parser.parse_args()


# Checking for the maximum number of instructions, if provided by the user.

# Setting up all the fixed system parameters here
# Caches: MESI Two Level Cache Hierarchy

from gem5.components.cachehierarchies.ruby.mesi_two_level_cache_hierarchy import (
    MESITwoLevelCacheHierarchy,
)

cache_hierarchy = MESITwoLevelCacheHierarchy(
    l1d_size="32kB",
    l1d_assoc=8,
    l1i_size="32kB",
    l1i_assoc=8,
    l2_size="256kB",
    l2_assoc=16,
    num_l2_banks=2,
)
# Memory: Dual Channel DDR4 2400 DRAM device.
# The X86 board only supports 3 GB of main memory.

memory = DualChannelDDR4_2400(size="3GB")

# Here we setup the processor. This is a special switchable processor in which
# a starting core type and a switch core type must be specified. Once a
# configuration is instantiated a user may call `processor.switch()` to switch
# from the starting core types to the switch core types. In this simulation
# we start with KVM cores to simulate the OS boot, then switch to the Timing
# cores for the command we wish to run after boot.

processor = SimpleSwitchableProcessor(
    starting_core_type=CPUTypes.KVM,
    switch_core_type=CPUTypes.TIMING,
    isa=ISA.X86,
    num_cores=2,
)

# Here we setup the board. The X86Board allows for Full-System X86 simulations

board = X86Board(
    clk_freq="3GHz",
    processor=processor,
    memory=memory,
    cache_hierarchy=cache_hierarchy,
)

# Here we set the FS workload, i.e., npb benchmark program
# After simulation has ended you may inspect
# `m5out/system.pc.com_1.device` to the stdout, if any.

# After the system boots, we execute the benchmark program and wait till the
# ROI `workbegin` annotation is reached (m5_work_begin()). We start collecting
# the number of committed instructions till ROI ends (marked by `workend`).
# We then finish executing the rest of the benchmark.

# Also, we sleep the system for some time so that the output is printed
# properly.
board.set_kernel_disk_workload(
    # kernel=KernelResource("/home/harshilp/gem5-resources-worktrees/gem5-resources-repo/src/x86-ubuntu-gpu-ml/vmlinux-gpu-ml"),
    kernel=obtain_resource("x86-linux-kernel-5.4.0-105-generic"),
    disk_image=DiskImageResource("/home/harshilp/gem5-resources-worktrees/npb-img/src/x86-ubuntu-npb/disk-image/x86-ubuntu-npb"),
    kernel_args=[
            "earlyprintk=ttyS0",
            "console=ttyS0",
            "lpj=7999923",
            "root=/dev/sda2"
        ],
    readfile_contents="/home/gem5/NPB3.4-OMP/bin/bt.A.x; sleep 5; m5 exit;"

)

# 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!")

    m5.stats.reset()

    # We have completed up to this step using KVM cpu. Now we switch to timing
    # cpu for detailed simulation.

    # # 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


# 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`.
def handle_workend():
    print("Dump stats at the end of the ROI!")

    m5.stats.dump()
    yield True

def exit_event_handler():
    print("first exit event")
    yield False
    print("second exit event")
    yield False
    print("third exit event")
    yield False
    print("fourth exit event")
    # yield False
    # print("fifth exit event")
    yield True
simulator = Simulator(
    board=board,
    on_exit_event={
        ExitEvent.WORKBEGIN: handle_workbegin(),
        ExitEvent.WORKEND: handle_workend(),
        ExitEvent.EXIT: exit_event_handler()
    },
)

# We maintain the wall clock time.

globalStart = time.time()

print("Running the simulation")
print("Using KVM cpu")

# We start the simulation.
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.

# 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.

print("Done with the simulation")
print()
print("Performance statistics:")

# manually calculate ROI time if ticks arg is used in case the
# entire ROI wasn't simulated
print("roi_ticks", simulator.get_roi_ticks())
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)
)

It gets the following error:

src/sim/simulate.cc:199: info: Entering event queue @ 43127682706441.  Starting simulation...
third exit event
src/sim/simulate.cc:199: info: Entering event queue @ 69193150173415.  Starting simulation...
fourth exit event
All simulation events were successful.
Done with the simulation

Performance statistics:
roi_ticks []
IndexError: list index out of range

At:
  ../develop/configs/example/gem5_library/x86-npb-benchmarks.py(283): <module>
  src/python/m5/main.py(669): main
src/cpu/kvm/base.cc:591: hack: Pretending totalOps is equivalent to totalInsts()

Harshil2107 avatar May 23 '24 18:05 Harshil2107

There's no post-installation.sh in https://github.com/gem5/gem5-resources/compare/stable...Harshil2107:gem5-resources-repo:npb-img as far as I can tell

powerjg avatar May 23 '24 18:05 powerjg

updated the npb-img repo, It should be there now.

Harshil2107 avatar May 23 '24 18:05 Harshil2107