Model execution
Simulation order
PlantSimEngine.jl
uses the ModelList
to automatically compute a dependency graph between the models and run the simulation in the correct order. When running a simulation with run!
, the models are then executed following this simple set of rules:
- Independent models are run first. A model is independent if it can be run independently from other models, only using initializations (or nothing).
- Then, models that have a dependency on other models are run. The first ones are the ones that depend on an independent model. Then the ones that are children of the second ones, and then their children ... until no children are found anymore. There are two types of children models (i.e. dependencies): hard and soft dependencies:
- Hard dependencies are always run before soft dependencies. A hard dependency is a model that list dependencies in their own method for
dep
. See this example that showsProcess2Model
defining a hard dependency on any model that simulateprocess1
. Inner hard dependency graphs (i.e. consecutive hard-dependency children) are considered as a single soft dependency. - Soft dependencies are then run sequentially. A model has a soft dependency on another model if one or more of its inputs is computed by another model. If a soft dependency has several parent nodes (e.g. two different models compute two inputs of the model), it is run only if all its parent nodes have been run already. In practice, when we visit a node that has one of its parent that did not run already, we stop the visit of this branch. The node will eventually be visited from the branch of the last parent that was run.
- Hard dependencies are always run before soft dependencies. A hard dependency is a model that list dependencies in their own method for
Parallel execution
FLoops
PlantSimEngine.jl
uses the Floops
package to run the simulation in sequential, parallel (multi-threaded) or distributed (multi-process) computations over objects, time-steps and independent processes.
That means that you can provide any compatible executor to the executor
argument of run!
. By default, run!
uses the ThreadedEx
executor, which is a multi-threaded executor. You can also use the SequentialEx
for sequential execution (non-parallel), or DistributedEx
for distributed computations.
Parallel traits
PlantSimEngine.jl
uses Holy traits to define if a model can be run in parallel.
A model is executable in parallel over time-steps if it does not uses or set values from other time-steps, and over objects if it does not uses or set values from other objects.
You can define a model as executable in parallel by defining the traits for time-steps and objects. For example, the ToyLAIModel
model from the examples folder can be run in parallel over time-steps and objects, so it defines the following traits:
PlantSimEngine.TimeStepDependencyTrait(::Type{<:ToyLAIModel}) = PlantSimEngine.IsTimeStepIndependent()
PlantSimEngine.ObjectDependencyTrait(::Type{<:ToyLAIModel}) = PlantSimEngine.IsObjectIndependent()
By default all models are considered not executable in parallel, because it is the safest option to avoid bugs that are difficult to catch, so you only need to define these traits if it is executable in parallel for them.
A model that is defined executable in parallel will not necessarily will. First, the user has to pass a parallel executor
to run!
(e.g. ThreadedEx
). Second, if the model is coupled with another model that is not executable in parallel, PlantSimEngine
will run all models in sequential.
Further executors
You can also take a look at FoldsThreads.jl for extra thread-based executors, FoldsDagger.jl for Transducers.jl-compatible parallel fold implemented using the Dagger.jl framework, and soon FoldsCUDA.jl for GPU computations (see this issue) and FoldsKernelAbstractions.jl. You can also take a look at ParallelMagics.jl to check if automatic parallelization is possible.
Finally, you can take a look into Transducers.jl's documentation for more information, for example if you don't know what is an executor, you can look into this explanation.
Tutorial
You can learn how to run a simulation from the home page, or from the documentation of PlantBiophysics.jl.