Loading [MathJax]/extensions/TeX/AMSmath.js
ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages Concepts
GlobalContext.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2020-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_OBJECTMANAGER_HPP
20#define ESPRESSO_SCRIPT_INTERFACE_OBJECTMANAGER_HPP
21
22/** @file
23 *
24 * Infrastructure to synchronize objects created on the head node
25 * with their corresponding remote copies.
26 *
27 * Implementation in @ref GlobalContext.cpp.
28 */
29
30#include "Context.hpp"
31#include "LocalContext.hpp"
32#include "ObjectHandle.hpp"
34#include "packed_variant.hpp"
35
36#include "core/MpiCallbacks.hpp"
37
38#include <utils/Factory.hpp>
39
40#include <boost/mpi/communicator.hpp>
41#include <boost/serialization/utility.hpp>
42
43#include <cstddef>
44#include <memory>
45#include <stdexcept>
46#include <string>
47#include <unordered_map>
48#include <utility>
49
50namespace ScriptInterface {
51
52/**
53 * @brief Global synchronizing context.
54 *
55 * Objects created in this context are synchronized
56 * between multiple MPI ranks. That is, for each instance
57 * created on the head node, a copy is created on all
58 * other ranks. If the original copy is mutated via
59 * @ref notify_set_parameter(), this change is also applied to all the
60 * copies. Calls to @ref notify_call_method() are also propagated to all
61 * ranks. The lifetime of the copies is tied to the original,
62 * if the original copy is destroyed on the head node,
63 * the remote copies are also destroyed.
64 */
65class GlobalContext : public Context {
66 using ObjectId = std::size_t;
67
68 /* Instances on this node that are managed by the
69 * head node. */
70 std::unordered_map<ObjectId, ObjectRef> m_local_objects;
71
72 std::shared_ptr<LocalContext> m_node_local_context;
73
74 boost::mpi::communicator const &m_comm;
75 bool m_is_head_node;
76
77 ParallelExceptionHandler m_parallel_exception_handler;
78
79 Communication::CallbackHandle<ObjectId, const std::string &,
80 const PackedMap &>
81 cb_make_handle;
82 Communication::CallbackHandle<ObjectId, const std::string &,
83 const PackedVariant &>
84 cb_set_parameter;
85 Communication::CallbackHandle<ObjectId, std::string const &,
86 PackedMap const &>
87 cb_call_method;
89
90public:
91 GlobalContext(std::shared_ptr<Communication::MpiCallbacks> const &callbacks,
92 std::shared_ptr<LocalContext> node_local_context)
93 : m_local_objects(), m_node_local_context(std::move(node_local_context)),
94 m_comm(callbacks->comm()), m_is_head_node(m_comm.rank() == 0),
95 // NOLINTNEXTLINE(bugprone-throw-keyword-missing)
96 m_parallel_exception_handler(m_comm),
97 cb_make_handle(callbacks,
98 [this](ObjectId id, const std::string &name,
100 make_handle(id, name, parameters);
101 }),
102 cb_set_parameter(callbacks,
103 [this](ObjectId id, std::string const &name,
104 PackedVariant const &value) {
105 set_parameter(id, name, value);
106 }),
107 cb_call_method(callbacks,
108 [this](ObjectId id, std::string const &name,
109 PackedMap const &arguments) {
110 call_method(id, name, arguments);
111 }),
112 cb_delete_handle(callbacks,
113 [this](ObjectId id) { delete_handle(id); }) {}
114
115private:
116 /**
117 * @brief Callback for @c cb_make_handle
118 */
119 void make_handle(ObjectId id, const std::string &name,
120 const PackedMap &parameters);
121 /**
122 * @brief Create remote instances
123 *
124 * @param id Internal identifier of the instance
125 * @param name Class name
126 * @param parameters Constructor parameters.
127 */
128 void remote_make_handle(ObjectId id, const std::string &name,
129 const VariantMap &parameters);
130
131private:
132 /**
133 * @brief Callback for @c cb_set_parameter
134 */
135 void set_parameter(ObjectId id, std::string const &name,
136 PackedVariant const &value);
137
138public:
139 void notify_set_parameter(const ObjectHandle *o, std::string const &name,
140 Variant const &value) override;
141
142private:
143 /**
144 * @brief Callback for @c cb_call_method
145 */
146 void call_method(ObjectId id, std::string const &name,
147 PackedMap const &arguments);
148
149public:
150 void notify_call_method(const ObjectHandle *o, std::string const &name,
151 VariantMap const &arguments) override;
152
153private:
154 /**
155 * @brief Callback for @c cb_delete_handle
156 */
157 void delete_handle(ObjectId id) { m_local_objects.erase(id); }
158
159public:
160 /**
161 * @brief Get a new reference counted instance of a script interface
162 * object by name.
163 *
164 * Remote objects are automatically constructed.
165 */
166 std::shared_ptr<ObjectHandle>
167 make_shared(std::string const &name, const VariantMap &parameters) override;
168
169 boost::string_ref name(const ObjectHandle *o) const override;
170
171 bool is_head_node() const override { return m_is_head_node; }
172 void parallel_try_catch(std::function<void()> const &cb) const override {
173 m_parallel_exception_handler.parallel_try_catch<std::exception>(cb);
174 }
175 boost::mpi::communicator const &get_comm() const override { return m_comm; }
176};
177} // namespace ScriptInterface
178
179#endif
ScriptInterface::Context decorates ScriptInterface::ObjectHandle objects with a context: a creation p...
Communication::MpiCallbacks manages MPI communication using a visitor pattern.
Context of an object handle.
Definition Context.hpp:54
Global synchronizing context.
std::shared_ptr< ObjectHandle > make_shared(std::string const &name, const VariantMap &parameters) override
Get a new reference counted instance of a script interface object by name.
void notify_set_parameter(const ObjectHandle *o, std::string const &name, Variant const &value) override
boost::string_ref name(const ObjectHandle *o) const override
boost::mpi::communicator const & get_comm() const override
GlobalContext(std::shared_ptr< Communication::MpiCallbacks > const &callbacks, std::shared_ptr< LocalContext > node_local_context)
bool is_head_node() const override
void parallel_try_catch(std::function< void()> const &cb) const override
void notify_call_method(const ObjectHandle *o, std::string const &name, VariantMap const &arguments) override
Handle exceptions thrown in MPI parallel code.
void parallel_try_catch(std::function< void()> const &callback) const
Handle exceptions in synchronous code.
T get_value(Variant const &v)
Extract value of specific type T from a Variant.
std::unordered_map< std::string, Variant > VariantMap
Definition Variant.hpp:69
boost::make_recursive_variant< None, bool, int, std::size_t, double, std::string, ObjectRef, Utils::Vector3b, Utils::Vector3i, Utils::Vector2d, Utils::Vector3d, Utils::Vector4d, std::vector< int >, std::vector< double >, std::vector< boost::recursive_variant_ >, std::unordered_map< int, boost::recursive_variant_ >, std::unordered_map< std::string, boost::recursive_variant_ > >::type Variant
Possible types for parameters.
Definition Variant.hpp:67
std::vector< std::pair< std::string, PackedVariant > > PackedMap
std::size_t ObjectId
boost::make_recursive_variant< None, bool, int, std::size_t, double, std::string, ObjectId, Utils::Vector3b, Utils::Vector3i, Utils::Vector2d, Utils::Vector3d, Utils::Vector4d, std::vector< int >, std::vector< double >, std::vector< boost::recursive_variant_ >, std::unordered_map< int, boost::recursive_variant_ >, std::unordered_map< std::string, boost::recursive_variant_ > >::type PackedVariant
Packed version of Variant.