Note
Go to the end to download the full example code
MDAChain with independent parallel MDAs¶
This example illustrates the possibility to parallelize MDAs in an MDAChain, given that these MDA are independent and can be run in parallel.
from __future__ import annotations
from gemseo import configure_logger
from gemseo import create_discipline
from gemseo.mda.mda_chain import MDAChain
configure_logger()
<RootLogger root (INFO)>
Introduction¶
In an MDAChain
,
there may be an opportunity to parallelize the execution of MDA
that can be executed independently.
As an example,
let us consider the following expressions,
which will be used to instantiate analytic disciplines:
disciplines_expressions = [
{"a": "x"},
{"y1": "x1", "b": "a+1"},
{"x1": "1.-0.3*y1"},
{"y2": "x2", "c": "a+2"},
{"x2": "1.-0.3*y2"},
{"obj1": "x1+x2"},
{"obj2": "b+c"},
{"obj": "obj1+obj2"},
]
We can easily observe in these disciplines,
that the \(x_1\) and \(y_1\) variables are strongly coupled.
It follows that the second and third disciplines are strongly coupled and
constitute an MDA
.
The same statement can be done for the disciplines that provide the output variables \(x_2\) and \(y_2\), and the fourth and fifth disciplines which are also strongly coupled. These two MDAs are independent and only depend on the variable \(a\) given by the first discipline.
Thus,
they can be run in parallel,
hence reducing the overall MDAChain
execution provided that enough
resources are available on the computing node (in our case, at least two CPUs).
By default, the parallel execution of the independent MDA
are deactivated,
meaning that the execution of the two independent MDA
will remain sequential.
Yet, a parallel execution of the two MDA
can be activated using the
mdachain_parallelize_task boolean option.
If activated, the user has also the possibility to provide parallelization options, such as using either threads or processes to perform the parallelization, or the number of processes or threads to use. By default, as more lightweight, threading is used but on some specific case, where for instance race conditions may occur, multiprocessing can be employed.
Example of MDAChain
with parallelization¶
We are here using the disciplines previously defined by their analytical expressions,
and we are going to explicitly ask for a parallelization of the execution of the
two independent MDA
.
disciplines = []
for expr in disciplines_expressions:
disciplines.append(create_discipline("AnalyticDiscipline", expressions=expr))
mdo_parallel_chain_options = {"use_threading": True, "n_processes": 2}
mdachain = MDAChain(
disciplines,
name="mdachain_lower",
mdachain_parallelize_tasks=True,
mdachain_parallel_options=mdo_parallel_chain_options,
)
res = mdachain.execute()
Total running time of the script: (0 minutes 0.112 seconds)