stdlib: Move _connect_things to run as pre_instantiation

Through working with the gem5 stdlib there have been instances where
connecting the memory, processor, and cache hierarchy to the board (via
the AbstractBoard's `_connect_things` function) at the point of the
AbstractBoard's construction is problematic as the memory, processor,
and cache hierarchy may require information to connect correctly that is
only known to the AbstractBoard after construction. In particular this
can occur when a Workload contains information needed to configure
correctly.

To resolve this problem the `_connect_things` function has been moved to
run as a pre-initialization step. That is, run immediately before
`m5.instantiate`. This is done in the Simulator module.

This will break cases where a user utilizes the stdlib AbstractBoard but
does not use the stdlib Simulator module. As such, an Exception is
raised in these cases explaining the fix to the user. This is done via a
hack where the boards' `createCCObject` function (inheritted
from SimObject) is overriden with a check to ensure `_connect_things`
has been run. To fix the `_pre_instantiate` function must be executed
prior to `m5.instantiate` in the Python configuration script. Test and
config scripts in the gem5 repo have been updated accordingly.

Change-Id: Ibaef36eb7433ce104b861b1da80fc600f08f715a
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/65051
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Bobby R. Bruce
2022-10-27 15:16:58 -07:00
committed by Bobby Bruce
parent 75c1df0d06
commit 25d4fb2d91
11 changed files with 83 additions and 4 deletions

View File

@@ -216,6 +216,7 @@ root = Root(full_system=True, system=board)
root.sim_quantum = int(1e9)
board._pre_instantiate()
m5.instantiate()
# We maintain the wall clock time.

View File

@@ -218,6 +218,7 @@ root = Root(full_system=True, system=board)
root.sim_quantum = int(1e9)
board._pre_instantiate()
m5.instantiate()
# We maintain the wall clock time.

View File

@@ -204,6 +204,7 @@ root = Root(full_system=True, system=board)
root.sim_quantum = int(1e9)
board._pre_instantiate()
m5.instantiate()
# We maintain the wall clock time.

View File

@@ -274,6 +274,7 @@ root = Root(full_system=True, system=board)
root.sim_quantum = int(1e9)
board._pre_instantiate()
m5.instantiate()
# We maintain the wall clock time.

View File

@@ -290,6 +290,7 @@ root = Root(full_system=True, system=board)
root.sim_quantum = int(1e9)
board._pre_instantiate()
m5.instantiate()
# We maintain the wall clock time.

View File

@@ -112,8 +112,9 @@ class AbstractBoard:
# Setup board properties unique to the board being constructed.
self._setup_board()
# Connect the memory, processor, and cache hierarchy.
self._connect_things()
# A private variable to record whether `_connect_things` has been
# been called.
self._connect_things_called = False
def get_processor(self) -> "AbstractProcessor":
"""Get the processor connected to the board.
@@ -341,8 +342,15 @@ class AbstractBoard:
* The processor is incorporated after the cache hierarchy due to a bug
noted here: https://gem5.atlassian.net/browse/GEM5-1113. Until this
bug is fixed, this ordering must be maintained.
* Once this function is called `_connect_things_called` *must* be set
to `True`.
"""
if self._connect_things_called:
raise Exception(
"The `_connect_things` function has already been called."
)
# Incorporate the memory into the motherboard.
self.get_memory().incorporate_memory(self)
@@ -353,9 +361,49 @@ class AbstractBoard:
# Incorporate the processor into the motherboard.
self.get_processor().incorporate_processor(self)
self._connect_things_called = True
def _post_instantiate(self):
"""Called to set up anything needed after m5.instantiate"""
self.get_processor()._post_instantiate()
if self.get_cache_hierarchy():
self.get_cache_hierarchy()._post_instantiate()
self.get_memory()._post_instantiate()
def _pre_instantiate(self):
"""To be called immediately before m5.instantiate. This is where
`_connect_things` is executed by default."""
# Connect the memory, processor, and cache hierarchy.
self._connect_things()
def _connect_things_check(self):
"""
Here we check that connect things has been called and throw an
Exception if it has not.
Since v22.1 `_connect_things` function has
been moved from the AbstractBoard constructor to the
`_pre_instantation` function. Users who have used the gem5 stdlib
components (i.e., boards which inherit from AbstractBoard) and the
Simulator module should notice no change. Those who do not use the
Simulator module and instead called `m5.instantiate` directly must
call `AbstractBoard._pre_instantation` prior so `_connect_things` is
called. In order to avoid confusion, this check has been incorporated
and the Exception thrown explains the fix needed to convert old scripts
to function with v22.1.
This function is called in `AbstractSystemBoard.createCCObject` and
ArmBoard.createCCObject`. Both these functions override
`SimObject.createCCObject`. We can not do that here as AbstractBoard
does not inherit form System.
"""
if not self._connect_things_called:
raise Exception(
"""
AbstractBoard's `_connect_things` function has not been called. This is likely
due to not running a board outside of the gem5 Standard Library Simulator
module. If this is the case, this can be resolved by calling
`<AbstractBoard>._pre_instantiate()` prior to `m5.instantiate()`.
"""
)

View File

@@ -27,8 +27,9 @@
from abc import ABCMeta
from .abstract_board import AbstractBoard
from ...utils.override import overrides
from m5.objects import System
from m5.objects import System, SimObject
class AbstractSystemBoard(System, AbstractBoard):
@@ -54,3 +55,12 @@ class AbstractSystemBoard(System, AbstractBoard):
memory=memory,
cache_hierarchy=cache_hierarchy,
)
@overrides(SimObject)
def createCCObject(self):
"""We override this function as it is called in `m5.instantiate`. This
means we can insert a check to ensure the `_connect_things` function
has been run.
"""
super()._connect_things_check()
super().createCCObject()

View File

@@ -44,6 +44,7 @@ from m5.objects import (
ArmDefaultRelease,
VExpress_GEM5_Base,
VExpress_GEM5_Foundation,
SimObject,
)
import os
@@ -388,3 +389,12 @@ class ArmBoard(ArmSystem, AbstractBoard, KernelDiskWorkload):
"rw",
"mem=%s" % self.get_memory().get_size(),
]
@overrides(SimObject)
def createCCObject(self):
"""We override this function as it is called in `m5.instantiate`. This
means we can insert a check to ensure the `_connect_things` function
has been run.
"""
super()._connect_things_check()
super().createCCObject()

View File

@@ -377,6 +377,11 @@ class Simulator:
"""
if not self._instantiated:
# Before anything else we run the AbstractBoard's
# `_pre_instantiate` function.
self._board._pre_instantiate()
root = Root(
full_system=self._full_system
if self._full_system is not None

View File

@@ -211,7 +211,7 @@ root.sim_quantum = int(1e9)
# Disable the gdb ports. Required for forking.
m5.disableAllListeners()
motherboard._pre_instantiate()
m5.instantiate()
# Simulate the inital boot with the starting KVM cpu

View File

@@ -201,6 +201,7 @@ motherboard = TestBoard(
root = Root(full_system=False, system=motherboard)
motherboard._pre_instantiate()
m5.instantiate()
generator.start_traffic()