psim
is a simulation engine that sits at the bottom of pstack
, as well as
a stand-alone simulator that can run POETS applications without a pstack
deployment. This manual describes the usage of psim
as an independent tool
to run non-distributed simulations. For distributed simulations using pcli
,
see the corresponding manual Using pcli
.
POETS Simulator (PSIM) v0.1
Usage:
psim.py [options] <app.xml>
Options:
-l --level=<n> Specify log messages verbosity [default: 1].
-q --quiet Suppress in-simulation outputs.
-r --result Print simulation result as JSON object.
-t --temp=<dir> Specify simulation file directory [default: /tmp].
-d --debug Print debug information.
After installing pstack
, the tool psim
should be available on the command
line.
psim
has a simple command line interface and can take a POETS XML file as a
single argument. A quick way to try this is to use one of the applications
from the unit test framework, located in the repo's tests
directory. Here's
an example ...
$ psim tests/basic-01.xml
Log [device n0, level 1]: counter = 1
Log [device n1, level 1]: counter = 1
Log [device n2, level 1]: counter = 1
Log [device n3, level 1]: counter = 1
Log [device n0, level 1]: counter = 2
Log [device n1, level 1]: counter = 2
Log [device n2, level 1]: counter = 2
Log [device n3, level 1]: counter = 2
Log [device n0, level 1]: counter = 3
Log [device n1, level 1]: counter = 3
Log [device n2, level 1]: counter = 3
Log [device n3, level 1]: counter = 3
Log [device n0, level 1]: counter = 4
Log [device n1, level 1]: counter = 4
Log [device n2, level 1]: counter = 4
Log [device n3, level 1]: counter = 4
Log [device n0, level 1]: counter = 5
Log [device n1, level 1]: counter = 5
Log [device n2, level 1]: counter = 5
Log [device n3, level 1]: counter = 5
Log [device n0, level 1]: counter = 6
Log [device n1, level 1]: counter = 6
Log [device n2, level 1]: counter = 6
Log [device n3, level 1]: counter = 6
Log [device n0, level 1]: counter = 7
Log [device n1, level 1]: counter = 7
Log [device n2, level 1]: counter = 7
Log [device n3, level 1]: counter = 7
Log [device n0, level 1]: counter = 8
Log [device n1, level 1]: counter = 8
Log [device n2, level 1]: counter = 8
Log [device n3, level 1]: counter = 8
Log [device n0, level 1]: counter = 9
Log [device n1, level 1]: counter = 9
Log [device n2, level 1]: counter = 9
Log [device n3, level 1]: counter = 9
Log [device n0, level 1]: counter = 10
Log [device n1, level 1]: counter = 10
Log [device n2, level 1]: counter = 10
Log [device n3, level 1]: counter = 10
Exit [device n0]: handler_exit(0) called
Metric [Delivered messages]: 40
Metric [Exit code]: 0
State [n0]: state = 0, counter = 10, toggle_buffer_ptr = 0
State [n1]: state = 0, counter = 10, toggle_buffer_ptr = 0
State [n2]: state = 0, counter = 10, toggle_buffer_ptr = 0
State [n3]: state = 0, counter = 10, toggle_buffer_ptr = 0
psim
provides both human and machine-friendly outputs (i.e. porcelain and
plumping).
The output shown above is the human-friendly version and is produced by
default (when no switches are used). It's a print out of log messages
(generated by calls to handler_log
), simulation statistics (called
metrics) and final device states.
The verbosity of log messages can be specified through --level
(this would
not be particularly useful for the simulation above since all log messages
have the same level).
To produce the machine-friendly version, use the switch --result
. This will
dump a simulation result JSON object containing simulation metrics and final
device states. You'll probably want to use --quiet
too, to suppress
human-friendly messages and print the JSON output on its own (useful when
piping output to other tools).
Here's an example ...
$ psim -qr tests/ring-oscillator-01.xml
{"states": {"n0": {"state": 0, "counter": 10, "toggle_buffer_ptr": 0}, "n1": {"state": 0, "counter": 10, "toggle_buffer_ptr": 0}, "n2": {"state": 0, "counter": 10, "toggle_buffer_ptr": 0}, "n3": {"state": 0, "counter": 10, "toggle_buffer_ptr": 0}}, "metrics": {"Exit code": 0, "Delivered messages": 40}}
The output can be piped to a command line JSON processor such as jq to print certain fields of interest ...
$ psim -qr tests/ring-oscillator-01.xml | jq .metrics
{
"Exit code": 0,
"Delivered messages": 40
}
psim
exposes an idiomatic interface to run simulations in Python. Here's an example ...
$ python
Python 2.7.14 (default, Oct 31 2017, 21:12:13)
[GCC 6.4.0] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from psim import psim
>>> psim("../tests/ring-oscillator-01.xml")
{'states': {'n0': {'state': 0, 'counter': 10, 'toggle_buffer_ptr': 0}, 'n1': {'state': 0, 'counter': 10, 'toggle_buffer_ptr': 0}, 'n2': {'state': 0, 'counter': 10, 'toggle_buffer_ptr': 0}, 'n3': {'state': 0, 'counter': 10, 'toggle_buffer_ptr': 0}}, 'metrics': {'Exit code': 0, 'Delivered messages': 40}}
This can be useful to run repeated simulations (e.g. for benchmarking),
especially when used together with the graph and application generation tools
pml
and
gml
that expose similar
Python functions.