Source code for qopt.parallel

# -*- coding: utf-8 -*-
# =============================================================================
#     qopt
#     Copyright (C) 2020 Julian Teske, Forschungszentrum Juelich
#
#     This program is free software: you can redistribute it and/or modify
#     it under the terms of the GNU General Public License as published by
#     the Free Software Foundation, either version 3 of the License, or
#     (at your option) any later version.
#
#     This program is distributed in the hope that it will be useful,
#     but WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#     GNU General Public License for more details.
#
#     You should have received a copy of the GNU General Public License
#     along with this program. If not, see <http://www.gnu.org/licenses/>.
#
#     Contact email: j.teske@fz-juelich.de
# =============================================================================
"""
This module contains functions for the support of multiprocessing.

The function `run_optimization_parallel` can be used to perform the
optimization for multiple initial conditions in parallel.

Caution! The solver class `SchroedingerSMonteCarlo` offers a functionality for
the parallel execution of the simulation vor various noise samples. These
features are not compatible. The program can only be parallelized once.

Functions
---------
:func:`run_optimization`
    Executes the run_optimization method of an optimizer.

:func:`run_optimization_parallel`
    Parallel execution of the run_optimization Method of the
    Optimizer.

Notes
-----
The implementation was inspired by the optimal control package of QuTiP [1]_
(Quantum Toolbox in Python)

References
----------
.. [1] J. R. Johansson, P. D. Nation, and F. Nori: "QuTiP 2: A Python framework
    for the dynamics of open quantum systems.", Comp. Phys. Comm. 184, 1234
    (2013) [DOI: 10.1016/j.cpc.2012.11.019].

"""

from multiprocessing import Pool
import copy

from qopt.data_container import DataContainer


[docs]def run_optimization(optimizer, initial_pulse): """ Executes the run_optimization method of an optimizer. Parameters ---------- optimizer: Optimizer The Optimizer. initial_pulse: numpy array, shape (num_t, num_ctrl) The initial pulse. Returns ------- result: OptimizationResult The result of the optimization. """ return optimizer.run_optimization(initial_pulse)
[docs]def run_optimization_parallel(optimizer, initial_pulses, processes=None): """ Parallel execution of the run_optimization Method of the Optimizer. Parameters ---------- optimizer: Optimizer The Optimizer. initial_pulses: numpy array, shape (num_init, num_t, num_ctrl) The initial pulse. Where num_init is the number of initial pulses. processes: int, optional If an integer is given, then the propagation is calculated in this number of parallel processes. If 1 then no parallel computing is applied. If None then cpu_count() is called to use all cores available. Defaults to None. Returns ------- data: DataContainer A DataContainer in which the OptimizationResults are saved. """ optimizers = [copy.deepcopy(optimizer) for _ in initial_pulses] with Pool(processes=processes) as pool: results = pool.starmap( run_optimization, zip(optimizers, initial_pulses)) data = DataContainer() for result in results: data.append_optim_result(result) return data