Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include "DataStructures/TaggedTuple.hpp"
7 : #include "Parallel/Reduction.hpp"
8 : #include "Utilities/Serialization/Serialize.hpp"
9 : #include "Utilities/TMPL.hpp"
10 :
11 : namespace PhaseControl {
12 :
13 : /// A type for denoting a piece of data for deciding a phase change.
14 : ///
15 : /// `Tag` is intended to be a tag (with a type) for indexing a
16 : /// `tuples::TaggedTuple`, and `CombineMethod` is intended to be a
17 : /// `Parallel::ReductionDatum`-compatible invokable for combining the `type` of
18 : /// the `Tag`. The `MainCombineMethod` is provided to give flexibility for a
19 : /// different method of combination at the top level of the hierarchy (so, in
20 : /// the case of phase control reductions, performed by the main chare to combine
21 : /// reductions from different chares)
22 : template <typename Tag, typename CombineMethod,
23 : typename MainCombineMethod = CombineMethod>
24 1 : struct TagAndCombine : Tag {
25 0 : using tag = Tag;
26 0 : using combine_method = CombineMethod;
27 0 : using main_combine_method = MainCombineMethod;
28 : };
29 :
30 : /// A flexible combine invokable that combines into a `tuples::TaggedTuple` a
31 : /// new `tuples::TaggedTuple`, and combines according to type aliases
32 : /// `combination_method`s that are required to be defined in each tag.
33 1 : struct TaggedTupleCombine {
34 : template <typename... Tags>
35 0 : tuples::TaggedTuple<Tags...> operator()(
36 : tuples::TaggedTuple<Tags...> current_state,
37 : const tuples::TaggedTuple<Tags...>& element) {
38 : tmpl::for_each<tmpl::list<Tags...>>([¤t_state, &element](auto tag_v) {
39 : using tag = typename decltype(tag_v)::type;
40 : tuples::get<tag>(current_state) = typename tag::combine_method{}(
41 : tuples::get<tag>(current_state), tuples::get<tag>(element));
42 : });
43 : return current_state;
44 : }
45 : };
46 :
47 : /// A flexible combine invokable that combines into a `tuples::TaggedTuple` a
48 : /// new `tuples::TaggedTuple` with a subset of the original tags, and combines
49 : /// according to type aliases `main_combine_method`s that are required to be
50 : /// defined in each tag.
51 : ///
52 : /// \note This is _not_ usable with charm++ reductions; it mutates the current
53 : /// state in-place. This is constructed for the use-case where the main chare
54 : /// stores a persistent data structure and combines reduction data as it arrives
55 : /// from the other chares.
56 1 : struct TaggedTupleMainCombine {
57 : template <typename... CurrentTags, typename... CombineTags>
58 0 : static void apply(
59 : const gsl::not_null<tuples::TaggedTuple<CurrentTags...>*> current_state,
60 : const tuples::TaggedTuple<CombineTags...>& element) {
61 : tmpl::for_each<tmpl::list<CombineTags...>>([¤t_state,
62 : &element](auto tag_v) {
63 : using tag = typename decltype(tag_v)::type;
64 : tuples::get<tag>(*current_state) = typename tag::main_combine_method{}(
65 : tuples::get<tag>(*current_state), tuples::get<tag>(element));
66 : });
67 : }
68 : };
69 :
70 : /// A `Parallel::ReductionData` with a single `Parallel::ReductionDatum` for a
71 : /// given tagged tuple type determined by `TagsPresent`, and performs the
72 : /// combine according to `TagsAndCombines`, which must be a `tmpl::list` of
73 : /// `PhaseControl::TagAndCombine`s.
74 : ///
75 : /// Each tag in the `TagsAndCombinesPresent` may either be a `TagsAndCombines`
76 : /// or otherise define all three type traits `type`, `combine_method`, and
77 : /// `main_combine_method`.
78 : template <typename TagsAndCombinesPresent, typename TagsAndCombines>
79 1 : using reduction_data = Parallel::ReductionData<Parallel::ReductionDatum<
80 : tuples::tagged_tuple_from_typelist<TagsAndCombinesPresent>,
81 : TaggedTupleCombine>>;
82 : } // namespace PhaseControl
|