SpECTRE Documentation Coverage Report
Current view: top level - Parallel/PhaseControl - PhaseControlTags.hpp Hit Total Coverage
Commit: 990bc653376fc4a4068db06123ec02659d814816 Lines: 8 28 28.6 %
Date: 2021-05-16 17:17:32
Legend: Lines: hit not hit

          Line data    Source code
       1           0 : // 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           1 : struct TagAndCombine : Tag {
      34           0 :   using tag = Tag;
      35           0 :   using combine_method = CombineMethod;
      36           0 :   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.
      42           1 : struct TaggedTupleCombine {
      43             :   template <typename... Tags>
      44           0 :   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.
      66           1 : struct TaggedTupleMainCombine {
      67             :   template <typename... CurrentTags, typename... CombineTags>
      68           0 :   static void apply(
      69             :       const gsl::not_null<tuples::TaggedTuple<CurrentTags...>*> current_state,
      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           1 : using reduction_data = Parallel::ReductionData<Parallel::ReductionDatum<
      91             :     tuples::tagged_tuple_from_typelist<TagsAndCombinesPresent>,
      92             :     TaggedTupleCombine>>;
      93             : 
      94           0 : 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>
     119           1 : struct PhaseChangeAndTriggers {
     120           0 :   using phase_change_type = PhaseChange<PhaseChangeRegistrars>;
     121           0 :   static constexpr Options::String help{
     122             :       "A collection of pairs of triggers and collections of phase change "
     123             :       "objects to determine runtime phase control-flow decisions. The order of "
     124             :       "the phase change objects determines the order of the requests processed "
     125             :       "by the Main chare during phase change arbitration."};
     126             : 
     127           0 :   using type =
     128             :       std::vector<std::pair<std::unique_ptr<Trigger>,
     129             :                             std::vector<std::unique_ptr<phase_change_type>>>>;
     130             : };
     131             : }  // namespace OptionTags
     132             : 
     133           0 : namespace Tags {
     134             : /// Tag for the collection of triggers that indicate synchronization points at
     135             : /// which phase changes should be considered, and the associated `PhaseChange`
     136             : /// objects for making the phase change decisions.
     137             : template <typename PhaseChangeRegistrars>
     138           1 : struct PhaseChangeAndTriggers : db::SimpleTag {
     139           0 :   using phase_change_type = PhaseChange<PhaseChangeRegistrars>;
     140           0 :   using type =
     141             :       std::vector<std::pair<std::unique_ptr<Trigger>,
     142             :                             std::vector<std::unique_ptr<phase_change_type>>>>;
     143             : 
     144           0 :   using option_tags =
     145             :       tmpl::list<OptionTags::PhaseChangeAndTriggers<PhaseChangeRegistrars>>;
     146           0 :   static constexpr bool pass_metavariables = false;
     147           0 :   static type create_from_options(
     148             :       const type& phase_control_and_triggers) noexcept {
     149             :     return deserialize<type>(
     150             :         serialize<type>(phase_control_and_triggers).data());
     151             :   }
     152             : };
     153             : }  // namespace Tags
     154             : 
     155           0 : namespace TagsAndCombines {
     156             : /// A tag for indicating that a halt was called by a trigger associated with
     157             : /// `PhaseChange`s.
     158             : ///
     159             : /// This is needed to disambiguate different quiescence conditions in the main
     160             : /// chare. It is automatically included in
     161             : /// `PhaseControl::get_phase_change_tags`, so shouldn't be explicitly included
     162             : /// in the `phase_change_tags_and_combines_list` in derived classes of
     163             : /// `PhaseChange`.
     164           1 : struct UsePhaseChangeArbitration {
     165           0 :   using type = bool;
     166           0 :   using combine_method = funcl::Or<>;
     167           0 :   using main_combine_method = combine_method;
     168             : };
     169             : }  // namespace TagsAndCombines
     170             : 
     171             : namespace detail {
     172             : template <typename PhaseChangeDerived>
     173             : struct get_phase_change_tags_and_combines {
     174             :   using type = typename PhaseChangeDerived::phase_change_tags_and_combines;
     175             : };
     176             : }  // namespace detail
     177             : 
     178             : /// Metafunction for determining the merged collection of tags in
     179             : /// `phase_change_tags_and_combines_list`s from all `PhaseChange` derived
     180             : /// classes registered in `PhaseChangeRegistrars`
     181             : template <typename PhaseChangeRegistrars>
     182           1 : using get_phase_change_tags =
     183             :     tmpl::push_back<tmpl::flatten<tmpl::transform<
     184             :                         Registration::registrants<PhaseChangeRegistrars>,
     185             :                         detail::get_phase_change_tags_and_combines<tmpl::_1>>>,
     186             :                     TagsAndCombines::UsePhaseChangeArbitration>;
     187             : }  // namespace PhaseControl

Generated by: LCOV version 1.14