ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
ParallelExceptionHandler.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef ESPRESSO_SCRIPT_INTERFACE_PARALLEL_EXCEPTION_HANDLER_HPP
20#define ESPRESSO_SCRIPT_INTERFACE_PARALLEL_EXCEPTION_HANDLER_HPP
21
23
24#include <boost/mpi/communicator.hpp>
25
26#include <stdexcept>
27#include <string>
28#include <utility>
29
30namespace ScriptInterface {
31/**
32 * Handle exceptions thrown in MPI parallel code.
33 *
34 * Instantiate this class inside the catch block and after the catch block,
35 * like so:
36 * @code{.cpp}
37 * boost::mpi::communicator world;
38 * auto handler = ScriptInterface::ParallelExceptionHandler{world};
39 * std::shared_ptr<MyClass> obj;
40 * context()->parallel_try_catch([&obj]() {
41 * obj = std::make_shared<MyClass>(2., true);
42 * });
43 * @endcode
44 *
45 * Exceptions are handled as follows:
46 * * the main rank throws: re-throw on main rank and throw @ref Exception
47 * on all other ranks
48 * * one or more of the worker nodes throw: collect error messages from
49 * worker nodes and throw them on the main rank as a @c std::runtime_error,
50 * throw @ref Exception on all other ranks
51 *
52 * Throwing a @ref Exception guarantees that the partially initialized script
53 * interface object won't be registered in the @ref GlobalContext dictionary;
54 * this is the only side-effect on worker nodes, since the exception itself
55 * is otherwise silently ignored. On the main rank, the thrown exception is
56 * converted to a Python exception.
57 */
59public:
60 ParallelExceptionHandler(boost::mpi::communicator comm)
61 : m_comm(std::move(comm)) {}
62
63 /**
64 * @brief Handle exceptions in synchronous code.
65 * Error messages queued in the runtime error collector are flushed
66 * to standard error if the code throws on any rank.
67 * @pre Must be called on all ranks.
68 * @pre The @p callback cannot invoke remote functions from the
69 * @ref Communication::MpiCallbacks framework due to blocking
70 * communication (risk of MPI deadlock on worker nodes).
71 * @param[in] callback Callback to execute synchronously on all ranks.
72 */
73 template <typename T>
74 void parallel_try_catch(std::function<void()> const &callback) const {
75 try {
76 callback();
77 } catch (T const &error) {
78 handle_impl(&error);
79 }
80 handle_impl(nullptr);
81 }
82
83private:
84 void handle_impl(std::exception const *error) const;
85 boost::mpi::communicator m_comm;
86};
87} // namespace ScriptInterface
88
89#endif
Handle exceptions thrown in MPI parallel code.
ParallelExceptionHandler(boost::mpi::communicator comm)
void parallel_try_catch(std::function< void()> const &callback) const
Handle exceptions in synchronous code.
This file contains the errorhandling code for severe errors, like a broken bond or illegal parameter ...