Add simulation script
This commit is contained in:
12
configs/pim_config.py
Normal file
12
configs/pim_config.py
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
from dataclasses import dataclass
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class Configuration:
|
||||||
|
name: str
|
||||||
|
workload: Path
|
||||||
|
frequency: str = "3GHz"
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class Statistics:
|
||||||
|
ticks: int
|
||||||
@@ -1,3 +1,8 @@
|
|||||||
|
import m5
|
||||||
|
import json
|
||||||
|
import dataclasses
|
||||||
|
import sys
|
||||||
|
|
||||||
from gem5.isas import ISA
|
from gem5.isas import ISA
|
||||||
from m5.objects import (
|
from m5.objects import (
|
||||||
ArmDefaultRelease,
|
ArmDefaultRelease,
|
||||||
@@ -11,6 +16,10 @@ from gem5.components.boards.arm_baremetal_board import ArmBareMetalBoard
|
|||||||
from gem5.components.memory import DRAMSysHBM2
|
from gem5.components.memory import DRAMSysHBM2
|
||||||
from gem5.components.processors.cpu_types import CPUTypes
|
from gem5.components.processors.cpu_types import CPUTypes
|
||||||
from gem5.components.processors.simple_processor import SimpleProcessor
|
from gem5.components.processors.simple_processor import SimpleProcessor
|
||||||
|
from gem5.simulate.exit_event import ExitEvent
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from pim_config import Configuration, Statistics
|
||||||
|
|
||||||
requires(isa_required=ISA.ARM)
|
requires(isa_required=ISA.ARM)
|
||||||
|
|
||||||
@@ -19,16 +28,19 @@ from gem5.components.cachehierarchies.classic.private_l1_private_l2_cache_hierar
|
|||||||
)
|
)
|
||||||
from gem5.components.cachehierarchies.classic.no_cache import NoCache
|
from gem5.components.cachehierarchies.classic.no_cache import NoCache
|
||||||
|
|
||||||
|
configuration = Configuration(**json.loads(sys.argv[1]))
|
||||||
|
|
||||||
cache_hierarchy = PrivateL1PrivateL2CacheHierarchy(
|
cache_hierarchy = PrivateL1PrivateL2CacheHierarchy(
|
||||||
l1d_size="16kB", l1i_size="16kB", l2_size="256kB"
|
l1d_size="16kB", l1i_size="16kB", l2_size="256kB"
|
||||||
)
|
)
|
||||||
memory = DRAMSysHBM2(recordable=True)
|
|
||||||
|
memory = DRAMSysHBM2(recordable=False)
|
||||||
processor = SimpleProcessor(cpu_type=CPUTypes.O3, num_cores=1, isa=ISA.ARM)
|
processor = SimpleProcessor(cpu_type=CPUTypes.O3, num_cores=1, isa=ISA.ARM)
|
||||||
release = ArmDefaultRelease()
|
release = ArmDefaultRelease()
|
||||||
platform = VExpress_GEM5_Foundation()
|
platform = VExpress_GEM5_Foundation()
|
||||||
|
|
||||||
board = ArmBareMetalBoard(
|
board = ArmBareMetalBoard(
|
||||||
clk_freq="3GHz",
|
clk_freq=configuration.frequency,
|
||||||
processor=processor,
|
processor=processor,
|
||||||
memory=memory,
|
memory=memory,
|
||||||
cache_hierarchy=cache_hierarchy,
|
cache_hierarchy=cache_hierarchy,
|
||||||
@@ -42,16 +54,46 @@ board.cache_line_size = 32
|
|||||||
for core in processor.get_cores():
|
for core in processor.get_cores():
|
||||||
core.core.fetchBufferSize = 32
|
core.core.fetchBufferSize = 32
|
||||||
|
|
||||||
# Address of memory-mapped m5ops
|
|
||||||
board.m5ops_base = 0x10010000
|
|
||||||
|
|
||||||
workload = CustomWorkload(
|
workload = CustomWorkload(
|
||||||
"set_baremetal_workload",
|
"set_baremetal_workload",
|
||||||
{
|
{
|
||||||
"kernel": BinaryResource("kernels/gemv"),
|
"kernel": BinaryResource(configuration.workload),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
board.set_workload(workload)
|
board.set_workload(workload)
|
||||||
|
|
||||||
simulator = Simulator(board=board)
|
|
||||||
|
@dataclass
|
||||||
|
class WorkloadTime:
|
||||||
|
start: int
|
||||||
|
end: int
|
||||||
|
|
||||||
|
|
||||||
|
workload_time = WorkloadTime(0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def exit_event():
|
||||||
|
print(f"Workload begin @{m5.curTick()}")
|
||||||
|
workload_time.start = m5.curTick()
|
||||||
|
m5.stats.reset()
|
||||||
|
yield False
|
||||||
|
|
||||||
|
print(f"Workload end @{m5.curTick()}")
|
||||||
|
workload_time.end = m5.curTick()
|
||||||
|
m5.stats.dump()
|
||||||
|
yield False
|
||||||
|
|
||||||
|
print(f"Exit simulation @{m5.curTick()}...")
|
||||||
|
yield True
|
||||||
|
|
||||||
|
|
||||||
|
simulator = Simulator(
|
||||||
|
board=board, on_exit_event={ExitEvent.EXIT: exit_event()}
|
||||||
|
)
|
||||||
|
|
||||||
simulator.run()
|
simulator.run()
|
||||||
|
|
||||||
|
print(f"Workload took {workload_time.end - workload_time.start}")
|
||||||
|
|
||||||
|
statistics = Statistics(workload_time.end - workload_time.start)
|
||||||
|
print(json.dumps(dataclasses.asdict(statistics)))
|
||||||
76
simulation_script.py
Normal file
76
simulation_script.py
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
import subprocess
|
||||||
|
import csv
|
||||||
|
import copy
|
||||||
|
import dataclasses
|
||||||
|
import json
|
||||||
|
|
||||||
|
from threading import Thread
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Dict
|
||||||
|
from configs.pim_config import Configuration, Statistics
|
||||||
|
|
||||||
|
gem5 = Path("build/ARM/gem5.opt")
|
||||||
|
out_dir_base = Path("pim_out")
|
||||||
|
pim_simulation = Path("configs/pim_simulation.py")
|
||||||
|
|
||||||
|
|
||||||
|
class Gem5Thread(Thread):
|
||||||
|
def __init__(self, configuration: Configuration) -> None:
|
||||||
|
super().__init__()
|
||||||
|
self.configuration = configuration
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
serialized_configuration = json.dumps(
|
||||||
|
dataclasses.asdict(self.configuration)
|
||||||
|
)
|
||||||
|
|
||||||
|
out_dir = out_dir_base / configuration.name
|
||||||
|
|
||||||
|
out = subprocess.run(
|
||||||
|
[
|
||||||
|
gem5,
|
||||||
|
"-d" + out_dir.as_posix(),
|
||||||
|
pim_simulation,
|
||||||
|
serialized_configuration,
|
||||||
|
],
|
||||||
|
capture_output=True,
|
||||||
|
)
|
||||||
|
# print(out.stderr)
|
||||||
|
# print(out.stdout)
|
||||||
|
output = out.stdout.splitlines()[-1]
|
||||||
|
self.statistics = Statistics(**json.loads(output))
|
||||||
|
|
||||||
|
|
||||||
|
workload_directory = Path("kernels")
|
||||||
|
|
||||||
|
workloads = [
|
||||||
|
"classic_vadd",
|
||||||
|
"classic_vmul",
|
||||||
|
"classic_haxpy",
|
||||||
|
"classic_gemv",
|
||||||
|
# "classic_gemv_layers",
|
||||||
|
"vadd",
|
||||||
|
"vmul",
|
||||||
|
"haxpy",
|
||||||
|
"gemv",
|
||||||
|
# "gemv_layers",
|
||||||
|
]
|
||||||
|
|
||||||
|
configurations: list[Configuration] = []
|
||||||
|
|
||||||
|
for frequency in ["3GHz", "100GHz"]:
|
||||||
|
for workload in workloads:
|
||||||
|
configurations.append(
|
||||||
|
Configuration(workload + "_" + frequency, (workload_directory / workload).as_posix(), frequency)
|
||||||
|
)
|
||||||
|
|
||||||
|
threads: list[Gem5Thread] = []
|
||||||
|
|
||||||
|
for configuration in configurations:
|
||||||
|
thread = Gem5Thread(configuration)
|
||||||
|
thread.start()
|
||||||
|
threads.append(thread)
|
||||||
|
|
||||||
|
for thread in threads:
|
||||||
|
thread.join()
|
||||||
|
print(thread.configuration, thread.statistics)
|
||||||
Reference in New Issue
Block a user