PhaseControlTags.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <memory>
7 #include <type_traits>
8 #include <unordered_map>
9 #include <utility>
10 #include <vector>
11 
12 #include "Parallel/PhaseControl/PhaseChange.hpp"
13 #include "Parallel/Reduction.hpp"
14 #include "Parallel/Serialize.hpp"
15 #include "ParallelAlgorithms/EventsAndTriggers/Trigger.hpp"
16 #include "Utilities/Registration.hpp"
17 #include "Utilities/TMPL.hpp"
18 #include "Utilities/TaggedTuple.hpp"
19 
20 namespace PhaseControl {
21 
22 /// A type for denoting a piece of data for deciding a phase change.
23 ///
24 /// `Tag` is intended to be a tag (with a type) for indexing a
25 /// `tuples::TaggedTuple`, and `CombineMethod` is intended to be a
26 /// `Parallel::ReductionDatum`-compatible invokable for combining the `type` of
27 /// the `Tag`. The `MainCombineMethod` is provided to give flexibility for a
28 /// different method of combination at the top level of the hierarchy (so, in
29 /// the case of phase control reductions, performed by the main chare to combine
30 /// reductions from different chares)
31 template <typename Tag, typename CombineMethod,
32  typename MainCombineMethod = CombineMethod>
33 struct TagAndCombine : Tag {
34  using tag = Tag;
35  using combine_method = CombineMethod;
36  using main_combine_method = MainCombineMethod;
37 };
38 
39 /// A flexible combine invokable that combines into a `tuples::TaggedTuple` a
40 /// new `tuples::TaggedTuple`, and combines according to type aliases
41 /// `combination_method`s that are required to be defined in each tag.
43  template <typename... Tags>
44  tuples::TaggedTuple<Tags...> operator()(
45  tuples::TaggedTuple<Tags...> current_state,
46  const tuples::TaggedTuple<Tags...>& element) {
47  tmpl::for_each<tmpl::list<Tags...>>(
48  [&current_state, &element](auto tag_v) noexcept {
49  using tag = typename decltype(tag_v)::type;
50  tuples::get<tag>(current_state) = typename tag::combine_method{}(
51  tuples::get<tag>(current_state), tuples::get<tag>(element));
52  });
53  return current_state;
54  }
55 };
56 
57 /// A flexible combine invokable that combines into a `tuples::TaggedTuple` a
58 /// new `tuples::TaggedTuple` with a subset of the original tags, and combines
59 /// according to type aliases `main_combine_method`s that are required to be
60 /// defined in each tag.
61 ///
62 /// \note This is _not_ usable with charm++ reductions; it mutates the current
63 /// state in-place. This is constructed for the use-case where the main chare
64 /// stores a persistent data structure and combines reduction data as it arrives
65 /// from the other chares.
67  template <typename... CurrentTags, typename... CombineTags>
68  static void apply(
70  const tuples::TaggedTuple<CombineTags...>& element) {
71  tmpl::for_each<tmpl::list<CombineTags...>>(
72  [&current_state, &element](auto tag_v) noexcept {
73  using tag = typename decltype(tag_v)::type;
74  tuples::get<tag>(*current_state) =
75  typename tag::main_combine_method{}(
76  tuples::get<tag>(*current_state), tuples::get<tag>(element));
77  });
78  }
79 };
80 
81 /// A `Parallel::ReductionData` with a single `Parallel::ReductionDatum` for a
82 /// given tagged tuple type determined by `TagsPresent`, and performs the
83 /// combine according to `TagsAndCombines`, which must be a `tmpl::list` of
84 /// `PhaseControl::TagAndCombine`s.
85 ///
86 /// Each tag in the `TagsAndCombinesPresent` may either be a `TagsAndCombines`
87 /// or otherise define all three type traits `type`, `combine_method`, and
88 /// `main_combine_method`.
89 template <typename TagsAndCombinesPresent, typename TagsAndCombines>
90 using reduction_data = Parallel::ReductionData<Parallel::ReductionDatum<
91  tuples::tagged_tuple_from_typelist<TagsAndCombinesPresent>,
93 
94 namespace OptionTags {
95 /// Option tag for the collection of triggers that indicate synchronization
96 /// points at which phase changes should be considered, and the associated
97 /// `PhaseChange` objects for making the phase change decisions.
98 ///
99 /// When the phase control is arbitrated on the main chare, the `PhaseChange`
100 /// objects will be queried for their phase request in order of appearance in
101 /// the nested list (i.e. first all of the `PhaseChange`s associated with the
102 /// first trigger, in order, then those associated with the second trigger,
103 /// etc.). The order therefore determines the order of resolution of
104 /// simultaneous requests.
105 ///
106 /// \note The nested collection types for this option tag gives the yaml
107 /// format the slightly unusual form:
108 ///
109 /// ```
110 /// PhaseChangeAndTriggers:
111 /// - - Trigger1
112 /// - - PhaseChange1
113 /// - PhaseChange2
114 /// - - Trigger2
115 /// - - PhaseChange3
116 /// - PhaseChange4
117 /// ```
118 template <typename PhaseChangeRegistrars, typename TriggerRegistrars>
122  static constexpr Options::String help{
123  "A collection of pairs of triggers and collections of phase change "
124  "objects to determine runtime phase control-flow decisions. The order of "
125  "the phase change objects determines the order of the requests processed "
126  "by the Main chare during phase change arbitration."};
127 
128  using type =
131 };
132 } // namespace OptionTags
133 
134 namespace Tags {
135 /// Tag for the collection of triggers that indicate synchronization points at
136 /// which phase changes should be considered, and the associated `PhaseChange`
137 /// objects for making the phase change decisions.
138 template <typename PhaseChangeRegistrars, typename TriggerRegistrars>
142  using type =
145 
146  using option_tags =
147  tmpl::list<OptionTags::PhaseChangeAndTriggers<PhaseChangeRegistrars,
148  TriggerRegistrars>>;
149  static constexpr bool pass_metavariables = false;
150  static type create_from_options(
151  const type& phase_control_and_triggers) noexcept {
152  return deserialize<type>(
153  serialize<type>(phase_control_and_triggers).data());
154  }
155 };
156 } // namespace Tags
157 
158 namespace TagsAndCombines {
159 /// A tag for indicating that a halt was called by a trigger associated with
160 /// `PhaseChange`s.
161 ///
162 /// This is needed to disambiguate different quiescence conditions in the main
163 /// chare. It is automatically included in
164 /// `PhaseControl::get_phase_change_tags`, so shouldn't be explicitly included
165 /// in the `phase_change_tags_and_combines_list` in derived classes of
166 /// `PhaseChange`.
168  using type = bool;
169  using combine_method = funcl::Or<>;
171 };
172 } // namespace TagsAndCombines
173 
174 namespace detail {
175 template <typename PhaseChangeDerived>
176 struct get_phase_change_tags_and_combines {
177  using type = typename PhaseChangeDerived::phase_change_tags_and_combines;
178 };
179 } // namespace detail
180 
181 /// Metafunction for determining the merged collection of tags in
182 /// `phase_change_tags_and_combines_list`s from all `PhaseChange` derived
183 /// classes registered in `PhaseChangeRegistrars`
184 template <typename PhaseChangeRegistrars>
185 using get_phase_change_tags =
186  tmpl::push_back<tmpl::flatten<tmpl::transform<
188  detail::get_phase_change_tags_and_combines<tmpl::_1>>>,
190 } // namespace PhaseControl
PhaseControl
Contains utilities for determining control-flow among phases.
Definition: ExecutePhaseChange.hpp:17
utility
Parallel::ReductionDatum
The data to be reduced, and invokables to be called whenever two reduction messages are combined and ...
Definition: Reduction.hpp:63
PhaseControl::TagsAndCombines::UsePhaseChangeArbitration
A tag for indicating that a halt was called by a trigger associated with PhaseChanges.
Definition: PhaseControlTags.hpp:167
vector
PhaseControl::TaggedTupleCombine
A flexible combine invokable that combines into a tuples::TaggedTuple a new tuples::TaggedTuple,...
Definition: PhaseControlTags.hpp:42
Serialize.hpp
db::SimpleTag
Mark a struct as a simple tag by inheriting from this.
Definition: Tag.hpp:36
PhaseControl::Tags::PhaseChangeAndTriggers
Tag for the collection of triggers that indicate synchronization points at which phase changes should...
Definition: PhaseControlTags.hpp:139
PhaseControl::TaggedTupleMainCombine
A flexible combine invokable that combines into a tuples::TaggedTuple a new tuples::TaggedTuple with ...
Definition: PhaseControlTags.hpp:66
domain::push_back
CoordinateMap< SourceFrame, TargetFrame, Maps..., NewMap > push_back(CoordinateMap< SourceFrame, TargetFrame, Maps... > old_map, NewMap new_map) noexcept
Creates a CoordinateMap by appending the new map to the end of the old maps.
PhaseControl::get_phase_change_tags
tmpl::push_back< tmpl::flatten< tmpl::transform< Registration::registrants< PhaseChangeRegistrars >, detail::get_phase_change_tags_and_combines< tmpl::_1 > >>, TagsAndCombines::UsePhaseChangeArbitration > get_phase_change_tags
Metafunction for determining the merged collection of tags in phase_change_tags_and_combines_lists fr...
Definition: PhaseControlTags.hpp:189
tuples::TaggedTuple
An associative container that is indexed by structs.
Definition: TaggedTuple.hpp:271
Trigger
Definition: Trigger.hpp:34
PhaseControl::TagAndCombine
A type for denoting a piece of data for deciding a phase change.
Definition: PhaseControlTags.hpp:33
PhaseControl::OptionTags::PhaseChangeAndTriggers
Option tag for the collection of triggers that indicate synchronization points at which phase changes...
Definition: PhaseControlTags.hpp:119
memory
PhaseControl::reduction_data
Parallel::ReductionData< Parallel::ReductionDatum< tuples::tagged_tuple_from_typelist< TagsAndCombinesPresent >, TaggedTupleCombine > > reduction_data
A Parallel::ReductionData with a single Parallel::ReductionDatum for a given tagged tuple type determ...
Definition: PhaseControlTags.hpp:92
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
Registration::registrants
tmpl::transform< tmpl::remove_duplicates< RegistrarList >, detail::registrant< tmpl::pin< tmpl::remove_duplicates< RegistrarList > >, tmpl::_1 > > registrants
Transform a list of registrars into the list of associated registrants. This is usually used to defin...
Definition: Registration.hpp:65
funcl::Or
Functional for computing or of two objects.
Definition: Functional.hpp:240
unordered_map
type_traits
TMPL.hpp
gsl::not_null
Require a pointer to not be a nullptr
Definition: ReadSpecThirdOrderPiecewisePolynomial.hpp:13