VisitAndReturn.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <optional>
7 #include <pup.h>
8 #include <string>
9 #include <utility>
10 #include <type_traits>
11 
12 #include "Options/Options.hpp"
14 #include "Parallel/GlobalCache.hpp"
15 #include "Parallel/Main.hpp"
16 #include "Parallel/PhaseControl/PhaseChange.hpp"
18 #include "Utilities/Functional.hpp"
19 #include "Utilities/TMPL.hpp"
20 #include "Utilities/TaggedTuple.hpp"
21 
22 /// \cond
23 namespace PhaseControl {
24 template <typename Metavariables, typename Metavariables::Phase TargetPhase,
25  typename PhaseChangeRegistrars>
26 class VisitAndReturn;
27 
28 namespace Registrars {
29 template <typename Metavariables, typename Metavariables::Phase TargetPhase>
30 struct VisitAndReturn {
31  template <typename PhaseChangeRegistrars>
32  using f = ::PhaseControl::VisitAndReturn<Metavariables, TargetPhase,
33  PhaseChangeRegistrars>;
34 };
35 } // namespace Registrars
36 /// \endcond
37 
38 namespace Tags {
39 /// Storage in the phase change decision tuple so that the Main chare can record
40 /// the phase to return to after a temporary phase.
41 ///
42 /// \note This tag is not intended to participate in any of the reduction
43 /// procedures, so will error if the combine method is called.
44 template <auto Phase>
45 struct ReturnPhase {
46  using type = std::optional<decltype(Phase)>;
47 
48  struct combine_method {
49  std::optional<decltype(Phase)> operator()(
50  const std::optional<decltype(Phase)> /*first_phase*/,
51  const std::optional<decltype(Phase)>& /*second_phase*/) noexcept {
52  ERROR(
53  "The return phase should only be altered by the phase change "
54  "arbitration in the Main chare, so no reduction data should be "
55  "provided.");
56  }
57  };
58 
60 };
61 
62 /// Stores whether the phase in question has been requested.
63 ///
64 /// Combinations are performed via `funcl::Or`, as the phase in question should
65 /// be chosen if any component requests the jump.
66 template <auto Phase>
68  using type = bool;
69 
72 };
73 } // namespace Tags
74 
75 /*!
76  * \brief Phase control object for temporarily visiting `TargetPhase`, until the
77  * algorithm halts again, then returning to the original phase.
78  *
79  * The motivation for this type of procedure is e.g. load balancing,
80  * checkpointing, and other maintenance tasks that should be performed
81  * periodically during a lengthy evolution.
82  * Once triggered, this will cause a change to `TargetPhase`, but store the
83  * current phase to resume execution when the tasks in `TargetPhase` are
84  * completed.
85  *
86  * Any parallel component can participate in the associated phase change
87  * reduction data contribution, and if any component requests the temporary
88  * phase, it will execute.
89  *
90  * To determine which specialization of this template is requested from the
91  * input file, the `Metavariables` must define a `phase_name(Phase)` static
92  * member function that returns a string for each phase that will be used in
93  * `VisitAndReturn`s.
94  *
95  * \note If multiple such methods are specified (with different
96  * `TargetPhase`s), then the order of phase jumps depends on their order in the
97  * list.
98  * - If multiple `VisitAndReturn`s trigger simultaneously, then they will visit
99  * in sequence specified by the input file: first going to the first
100  * `TargetPhase` until that phase resolves, then immediately entering the
101  * second `TargetPhase` (without yet returning to the original phase), then
102  * finally returning to the original phase.
103  * - If a `VisitAndReturn` is triggered in a phase that is already a
104  * `TargetPhase` of another `VisitAndReturn`, it will be executed, and
105  * following completion, control will return to the original phase from before
106  * the first `VisitAndReturn`.
107  */
108 template <typename Metavariables, typename Metavariables::Phase TargetPhase,
109  typename PhaseChangeRegistrars = tmpl::list<
110  Registrars::VisitAndReturn<Metavariables, TargetPhase>>>
111 struct VisitAndReturn : public PhaseChange<PhaseChangeRegistrars> {
112  /// \cond
113  VisitAndReturn() = default;
114  explicit VisitAndReturn(CkMigrateMessage* /*unused*/) noexcept {}
115  using PUP::able::register_constructor;
117  /// \endcond
118 
119  static std::string name() noexcept {
120  return "VisitAndReturn(" + Metavariables::phase_name(TargetPhase) +
121  ")";
122  }
123  using options = tmpl::list<>;
124  static constexpr Options::String help{
125  "Temporarily jump to the phase given by `TargetPhase`, returning to the "
126  "previously executing phase when complete."};
127 
128  using argument_tags = tmpl::list<>;
129  using return_tags = tmpl::list<>;
130 
131  using phase_change_tags_and_combines =
132  tmpl::list<Tags::ReturnPhase<TargetPhase>,
134 
135  template <typename LocalMetavariables>
136  using participating_components = typename LocalMetavariables::component_list;
137 
138  template <typename... DecisionTags>
139  void initialize_phase_data_impl(
141  phase_change_decision_data) const noexcept {
142  tuples::get<Tags::ReturnPhase<TargetPhase>>(*phase_change_decision_data) =
143  std::nullopt;
144  tuples::get<Tags::TemporaryPhaseRequested<TargetPhase>>(
145  *phase_change_decision_data) = false;
146  }
147 
148  template <typename ParallelComponent, typename ArrayIndex>
149  void contribute_phase_data_impl(
151  const ArrayIndex& array_index) const noexcept {
152  if constexpr (std::is_same_v<typename ParallelComponent::chare_type,
154  Parallel::contribute_to_phase_change_reduction<ParallelComponent>(
156  cache, array_index);
157  } else {
158  Parallel::contribute_to_phase_change_reduction<ParallelComponent>(
160  cache);
161  }
162  }
163 
164  template <typename... DecisionTags>
165  typename std::optional<
167  arbitrate_phase_change_impl(
169  phase_change_decision_data,
170  const typename Metavariables::Phase current_phase,
171  const Parallel::GlobalCache<Metavariables>& /*cache*/) const noexcept {
172  auto& return_phase = tuples::get<Tags::ReturnPhase<TargetPhase>>(
173  *phase_change_decision_data);
174  if (return_phase.has_value()) {
175  const auto result = return_phase;
176  return_phase.reset();
177  return std::make_pair(result.value(),
178  ArbitrationStrategy::PermitAdditionalJumps);
179  }
180  auto& temporary_phase_requested =
181  tuples::get<Tags::TemporaryPhaseRequested<TargetPhase>>(
182  *phase_change_decision_data);
183  if (temporary_phase_requested) {
184  return_phase = current_phase;
185  temporary_phase_requested = false;
186  return std::make_pair(TargetPhase,
187  ArbitrationStrategy::RunPhaseImmediately);
188  }
189  return std::nullopt;
190  }
191 
192  void pup(PUP::er& /*p*/) noexcept override {}
193 };
194 } // namespace PhaseControl
195 
196 /// \cond
197 template <typename Metavariables, typename Metavariables::Phase TargetPhase,
198  typename PhaseChangeRegistrars>
199 PUP::able::PUP_ID PhaseControl::VisitAndReturn<
200  Metavariables, TargetPhase, PhaseChangeRegistrars>::my_PUP_ID = 0;
201 /// \endcond
PhaseControl
Contains utilities for determining control-flow among phases.
Definition: ExecutePhaseChange.hpp:17
std::string
CharmPupable.hpp
Main.hpp
utility
Tags::ReturnPhase
Storage in the phase change decision tuple so that the Main chare can record the phase to return to a...
Definition: VisitAndReturn.hpp:45
Parallel::GlobalCache
Definition: ElementReceiveInterpPoints.hpp:15
std::pair
GlobalCache.hpp
Options.hpp
Error.hpp
VisitAndReturn
Phase control object for temporarily visiting TargetPhase, until the algorithm halts again,...
Definition: VisitAndReturn.hpp:111
Tags::TemporaryPhaseRequested
Stores whether the phase in question has been requested.
Definition: VisitAndReturn.hpp:67
ERROR
#define ERROR(m)
prints an error message to the standard error stream and aborts the program.
Definition: Error.hpp:37
WRAPPED_PUPable_decl_template
#define WRAPPED_PUPable_decl_template(className)
Mark derived classes as serializable.
Definition: CharmPupable.hpp:22
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:271
ActionTesting::cache
Parallel::GlobalCache< Metavariables > & cache(MockRuntimeSystem< Metavariables > &runner, const ArrayIndex &array_index) noexcept
Returns the GlobalCache of Component with index array_index.
Definition: MockRuntimeSystemFreeFunctions.hpp:380
Parallel::Algorithms::Array
A struct that stores the charm++ types relevant for a particular array component.
Definition: AlgorithmArrayDeclarations.hpp:29
PhaseChange
PhaseChange objects determine the storage types and logic for moving between phases based on runtime ...
Definition: PhaseChange.hpp:140
Options::String
const char *const String
The string used in option structs.
Definition: Options.hpp:32
optional
funcl::Or
Functional for computing or of two objects.
Definition: Functional.hpp:240
type_traits
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecThirdOrderPiecewisePolynomial.hpp:13
Tags::ReturnPhase::combine_method
Definition: VisitAndReturn.hpp:48
string