Add documentation on custom tracers

This commit is contained in:
Yentl Van Tendeloo 2018-07-11 17:55:47 +02:00
parent 887179ec9f
commit 107bfdd1f8

View file

@ -157,3 +157,94 @@ Cell
---- ----
The cell tracer is discussed separately, as it has very specific behaviour and is only applicable to a select number of models. The cell tracer is discussed separately, as it has very specific behaviour and is only applicable to a select number of models.
Custom
------
Additionally, it might necessary to define your own custom tracer.
This can be done by defining a class similar to the following template.
For each trace method, an *aDEVS* parameter is passed, being a reference to the atomic DEVS model doing the transition.
On this *aDEVS* object, the following functions and attributes can be accessed:
- *aDEVS.getModelFullName()*: full hierarchical name of the model
- *aDEVS.IPorts*: reference to all input ports
- *aDEVS.OPorts*: reference to all output ports
- *aDEVS.state*: state of model
- *aDEVS.time_last[0]*: Time of next transition
- *aDEVS.time_next[0]*: Time of next transition
- *aDEVS.my_output*: dictionary of output events
- *aDEVS.my_input*: dictionary of input events
- *aDEVS.elapsed*: elapsed time before transition
A custom tracer can be defined as follows::
class TracerCustom(object):
def __init__(self, uid, server, filename):
"""
Both uid and server can be ignored, as these are only required for distributed simulation
filename contains the name of the file in which we should write the trace
"""
pass
def startTracer(self, recover):
"""
Recover is a boolean representing whether or not this is a recovered call (e.g., should the file be overwritten or appended to?)
"""
pass
def stopTracer(self):
"""
Stops the tracer (e.g., flush the file)
"""
pass
def traceInternal(self, aDEVS):
"""
Called for each atomic DEVS model that does an internal transition.
"""
pass
def traceExternal(self, aDEVS):
"""
Called for each atomic DEVS model that does an external transition.
"""
pass
def traceConfluent(self, aDEVS):
"""
Called for each atomic DEVS model that does a confluent transition.
"""
pass
def traceInit(self, aDEVS, t):
"""
Called upon initialization of a model.
The parameter *t* contains the time at which the model commences (likely 0).
"""
pass
def traceUser(self, time, aDEVS, variable, value):
"""
Called upon so called *god events* during debuggin, where a user manually alters the state of an atomic DEVS instance.
"""
pass
For some "example" tracers, have a look at the built-in tracers of PythonPDEVS, which can be found in *src/tracers*.
Note that in optimistic synchronization the destructive parts of this operation should be separated.
This can be done using the *runTraceAtController* function::
runTraceAtController(server, uid, aDEVS, [time, trace_text])
Both the *server* and *uid* are those passed to the constructor of the tracer.
Finally, after the tracer is defined, it needs to be registered for the simulator to use it.
This is done using the following call on the instantiated simulator::
sim.setCustomTracer(self, tracerfile, tracerclass, args):
Where:
- *tracerfile*: the Python class containing the implementation of the tracer, which is dynamically imported.
- *tracerclass*: the name of the class implementing the tracing functionality.
- *args*: the list of arguments that must additionally be passed to the tracer (e.g., filename)