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 BaseMDA 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 a BaseMDA.

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 BaseMDA are deactivated, meaning that the execution of the two independent BaseMDA will remain sequential. Yet, a parallel execution of the two BaseMDA 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 BaseMDA.

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.098 seconds)

Gallery generated by Sphinx-Gallery