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

Gallery generated by Sphinx-Gallery