Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

python,stdlib: Improve exit event return #947

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions src/python/gem5/simulate/simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@
from m5.stats import addStatVisitor
from m5.util import warn

from _m5.event import ExitEvent as CPPExitEvent
from _m5.event import GlobalSimLoopExitEvent

from ..components.boards.abstract_board import AbstractBoard
from ..components.processors.switchable_processor import SwitchableProcessor
from .exit_event import ExitEvent
Expand Down Expand Up @@ -689,10 +692,12 @@ def _instantiate(self) -> None:
# any final things.
self._board._post_instantiate()

def run(self, max_ticks: Optional[int] = None) -> None:
def run(self, max_ticks: Optional[int] = None) -> CPPExitEvent:
"""
This function will start or continue the simulator run and handle exit
events accordingly.
events accordingly. If the the exit event is handled by returning to
the Python code (as opposed to re-entering the Simulation loop) the
function will return the GlobalSimLoopExitEvent object.

:param max_ticks: The maximum number of ticks to execute per simulation
run. If this ``max_ticks`` value is met, a ``MAX_TICK``
Expand Down Expand Up @@ -770,9 +775,10 @@ def run(self, max_ticks: Optional[int] = None) -> None:
self._exit_event_count += 1

# If the generator returned True we will return from the Simulator
# run loop. In the case of a function: if it returned True.
# run loop with the ExitEvent. (In the case of a function, instead
# of a generator, : if it also returned True).
if exit_on_completion:
return
return self._last_exit_event

def save_checkpoint(self, checkpoint_dir: Path) -> None:
"""
Expand Down
7 changes: 7 additions & 0 deletions src/python/pybind11/event.cc
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,13 @@ pybind_init_event(py::module_ &m_native)
.def("getCode", &GlobalSimLoopExitEvent::getCode)
;

py::class_<ExitEvent,
std::unique_ptr<ExitEvent, py::nodelete>>(
m, "ExitEvent")
.def("description", &ExitEvent::description)
.def("reenter_simloop", &ExitEvent::reenter_simloop)
;

// Event base class. These should never be returned directly to
// Python since they don't have a well-defined life cycle. Python
// events should be derived from PyEvent instead.
Expand Down
70 changes: 70 additions & 0 deletions src/sim/global_event.hh
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include "base/barrier.hh"
#include "sim/eventq.hh"
#include "sim/simulate.hh"

namespace gem5
{
Expand Down Expand Up @@ -202,6 +203,75 @@ class GlobalEvent : public BaseGlobalEventTemplate<GlobalEvent>
virtual void process() = 0;
};

/**
* `ExitEvent` is the base base for all Exit events. Exit events are events
* which exit the simulation loop. The `ExitEvent` class is the most basic and
* is used to exit the simulation loop immediately, with no further automatic
* action or special data.
*/
class ExitEvent : public GlobalEvent
{
public:

/**
* Used to create an ExitEvent that will exit the simulation loop
* immediately.
*/
ExitEvent(): ExitEvent(curTick()){}

/**
* Used to create an ExitEvent that will exit the simulation loop at
* the specified tick.
*
* @param[in] when The tick at which the simulation should exit.
*/
ExitEvent(Tick when) :
GlobalEvent(when, Sim_Exit_Pri, Flags(Scheduled & IsExitEvent))
{
schedule(when);
}

~ExitEvent() {}

/**
* The process method for the ExitEvent. This method is called when the
* event is processed. It will call the `process_exit` method and then
* check if the simulation loop should be reentered.
*
* The `process_exit` method is a virtual method that can be overridden
* by derived classes to perform additional actions when the simulation.
*
* The `reenter_simloop` method is a virtual method that can be overridden
* by derived classes to determine if the simulation loop should be
* reentered after the event is processed.
*/
void process() final {
this->process_exit();
if (this->reenter_simloop())
{
simulate();
}
}

const char *description() const override {
return "ExitEvent: Exit the simulation with no further action.";
}

void process_exit() {

}


bool reenter_simloop() const
{
/**
* This function is used to determine if after the exit event is
* processed the simulation loop should be reentered.
*/
return false;
}
};

/**
* A special global event that synchronizes all threads and forces
* them to process asynchronously enqueued events. Useful for
Expand Down
14 changes: 14 additions & 0 deletions src/sim/sim_events.hh
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,20 @@ class GlobalSimLoopExitEvent : public GlobalEvent
virtual const char *description() const;
};


class SimpointStartEventEvent : GlobalSimLoopExitEvent
{
public:
SimpointStartEventEvent();
void process() override;
void clean() override {};
~SimpointStartEventEvent (){
DPRINTF(Event,"SimpointStartEventEvent destructed\n");
};
const char *description() const;
};


class LocalSimLoopExitEvent : public Event
{
protected:
Expand Down
8 changes: 7 additions & 1 deletion tests/gem5/stdlib/configs/simulator_exit_event_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,10 @@ def lone_function() -> bool:
ExitEvent.EXIT: exit_event_handler,
},
)
simulator.run()

# The simulator's `run` method returns the exit event object triggered the
# termination of the `run` method. Its state is printed below.
exit_event_obj = simulator.run()

print(f"Exit event object cause: '{exit_event_obj.getCause()}'")
print(f"Exit event code '{exit_event_obj.getCode()}'")
2 changes: 2 additions & 0 deletions tests/gem5/stdlib/simulator/ref/simout.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ About to exit the simulation for the 2 st/nd/rd/th time
Handled exit event.
About to exit the simulation for the 3 st/nd/rd/th time
Handling the final exit event. We'll exit now.
Exit event object cause: 'm5_exit instruction encountered'
Exit event code '0'