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

Process Commands #198

Merged
merged 17 commits into from
Jun 15, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
1 change: 1 addition & 0 deletions .pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ disable=print-statement,
too-many-locals,
too-many-branches,
too-few-public-methods,
too-many-public-methods,
too-many-lines,
no-self-use,
fixme,
Expand Down
37 changes: 37 additions & 0 deletions doc/guides/processes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -562,3 +562,40 @@ The above pseudocode is simplified, and for all but the most simple
processes you will be better off using Vivarium's built-in simulation
capabilities. We hope though that this helps you understand how
processes are simulated and the purpose of the API we defined.

-------------------
Parallel Processing
-------------------

Process Commands
================

When a :term:`process` is run in parallel, we can't interact with it in
the normal Python way. Instead, we can only exchange messages with it
through a pipe. Vivarium structures these exchanges using :term:`process
commands`.

Vivarium provides some built-in commands, which are documented in
:py:meth:`vivarium.core.process.Process.send_command`. Also see that
method's documentation for instructions on how to add support for your
own commands.

Process commands are designed to be used asynchronously, so to retrieve
the result of running a command, you need to call
:py:meth:`vivarium.core.process.Process.get_command_result`. As a
convenience, you can also call
:py:meth:`vivarium.core.process.Process.run_command` to send a command
and get its result as a return value in one function call.

Running Processes in Parallel
=============================

In normal situations though, you shouldn't have to worry about process
commands. Instead, just pass ``'_parallel': True`` in a process's
configuration dictionary, and the Vivarium Engine will handle the
parallelization for you. Just remember that parallelization requires
that processes be serialized and deserialized at the start of the
simulation, and this serialization only preserves the process
parameters. This means that if you instantiate a process and then change
its instance variables, those changes won't be preserved when the
process gets parallelized.
U8NWXD marked this conversation as resolved.
Show resolved Hide resolved
1 change: 1 addition & 0 deletions doc/reference/api/vivarium.core.process.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.. automodule:: vivarium.core.process
:members:
:undoc-members:
:private-members: _handle_parallel_process
:show-inheritance:
10 changes: 10 additions & 0 deletions doc/reference/glossary.rst
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,16 @@ Glossary
subclass either :py:class:`vivarium.core.process.Process`
or another process class.

Process Command
Process command
process command
Process Commands
Process commands
process commands
Instructions that let Vivarium communicate with parallel
processes in a remote-procedure-call-like fashion. See :doc:`the
processes guide </guides/processes>` for details.

Raw Data
Raw data
raw data
Expand Down
11 changes: 6 additions & 5 deletions vivarium/core/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ def get(self) -> Update:
The result of calling the function.
"""
return self.f(
self.defer.get(),
self.defer.get_command_result(),
self.args)


Expand Down Expand Up @@ -215,11 +215,11 @@ def __init__(
self.interval,
self.states)

def get(self) -> Update:
def get_command_result(self) -> Update:
"""Return the computed update.

This method is analogous to the ``.get()`` method in
:py:class:`vivarium.core.process.ParallelProcess` so that
This method is analogous to the ``.get_command_result()`` method
in :py:class:`vivarium.core.process.ParallelProcess` so that
parallel and non-parallel updates can be intermixed in the
simulation engine.
"""
Expand Down Expand Up @@ -711,7 +711,8 @@ def _invoke_process(
self.parallel[path] = ParallelProcess(
process, bool(self.profiler))
# trigger the computation of the parallel process
self.parallel[path].update(interval, states)
self.parallel[path].send_command(
'next_update', (interval, states))
U8NWXD marked this conversation as resolved.
Show resolved Hide resolved

return self.parallel[path]
# if not parallel, perform a normal invocation
Expand Down
Loading