SpECTRE Documentation Coverage Report
Current view: top level - Parallel - ParallelComponentHelpers.hpp Hit Total Coverage
Commit: a18e59fda1a195609825c55450f7d61ad20a91a4 Lines: 15 27 55.6 %
Date: 2026-06-11 22:10:41
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 <mutex>
       7             : #include <unordered_map>
       8             : #include <utility>
       9             : 
      10             : #include "DataStructures/TaggedTuple.hpp"
      11             : #include "Parallel/ArrayComponentId.hpp"
      12             : #include "Parallel/Callback.hpp"
      13             : #include "Parallel/Phase.hpp"
      14             : #include "Parallel/PhaseDependentActionList.hpp"
      15             : #include "Parallel/TypeTraits.hpp"
      16             : #include "Utilities/PrettyType.hpp"
      17             : #include "Utilities/TMPL.hpp"
      18             : #include "Utilities/TypeTraits.hpp"
      19             : 
      20             : namespace Parallel {
      21             : namespace detail {
      22             : template <class Action, class = std::void_t<>>
      23             : struct get_inbox_tags_from_action {
      24             :   using type = tmpl::list<>;
      25             : };
      26             : 
      27             : template <class Action>
      28             : struct get_inbox_tags_from_action<Action,
      29             :                                   std::void_t<typename Action::inbox_tags>> {
      30             :   using type = typename Action::inbox_tags;
      31             : };
      32             : }  // namespace detail
      33             : 
      34             : /*!
      35             :  * \ingroup ParallelGroup
      36             :  * \brief Given a list of Actions, get a list of the unique inbox tags
      37             :  */
      38             : template <class ActionsList>
      39           1 : using get_inbox_tags = tmpl::remove_duplicates<tmpl::join<tmpl::transform<
      40             :     ActionsList, detail::get_inbox_tags_from_action<tmpl::_1>>>>;
      41             : 
      42             : namespace detail {
      43             : // ParallelStruct is a metavariables, component, or action struct
      44             : template <class ParallelStruct, class = std::void_t<>>
      45             : struct get_const_global_cache_tags_from_parallel_struct {
      46             :   using type = tmpl::list<>;
      47             : };
      48             : 
      49             : template <class ParallelStruct>
      50             : struct get_const_global_cache_tags_from_parallel_struct<
      51             :     ParallelStruct,
      52             :     std::void_t<typename ParallelStruct::const_global_cache_tags>> {
      53             :   using type = typename ParallelStruct::const_global_cache_tags;
      54             : };
      55             : 
      56             : template <class PhaseDependentActionList>
      57             : struct get_const_global_cache_tags_from_pdal {
      58             :   using type = tmpl::join<tmpl::transform<
      59             :       tmpl::flatten<tmpl::transform<
      60             :           PhaseDependentActionList,
      61             :           get_action_list_from_phase_dep_action_list<tmpl::_1>>>,
      62             :       get_const_global_cache_tags_from_parallel_struct<tmpl::_1>>>;
      63             : };
      64             : 
      65             : template <class Component>
      66             : struct get_const_global_cache_tags_from_component {
      67             :   using type = typename get_const_global_cache_tags_from_pdal<
      68             :       typename Component::phase_dependent_action_list>::type;
      69             : };
      70             : 
      71             : template <class ParallelStruct, class = std::void_t<>>
      72             : struct get_mutable_global_cache_tags_from_parallel_struct {
      73             :   using type = tmpl::list<>;
      74             : };
      75             : 
      76             : template <class ParallelStruct>
      77             : struct get_mutable_global_cache_tags_from_parallel_struct<
      78             :     ParallelStruct,
      79             :     std::void_t<typename ParallelStruct::mutable_global_cache_tags>> {
      80             :   using type = typename ParallelStruct::mutable_global_cache_tags;
      81             : };
      82             : 
      83             : template <class PhaseDependentActionList>
      84             : struct get_mutable_global_cache_tags_from_pdal {
      85             :   using type = tmpl::join<tmpl::transform<
      86             :       tmpl::flatten<tmpl::transform<
      87             :           PhaseDependentActionList,
      88             :           get_action_list_from_phase_dep_action_list<tmpl::_1>>>,
      89             :       get_mutable_global_cache_tags_from_parallel_struct<tmpl::_1>>>;
      90             : };
      91             : 
      92             : template <class Component>
      93             : struct get_mutable_global_cache_tags_from_component {
      94             :   using type = typename get_mutable_global_cache_tags_from_pdal<
      95             :       typename Component::phase_dependent_action_list>::type;
      96             : };
      97             : 
      98             : }  // namespace detail
      99             : 
     100             : /*!
     101             :  * \ingroup ParallelGroup
     102             :  * \brief Given a list of Actions, get a list of the unique tags specified in
     103             :  * the actions' `const_global_cache_tags` aliases.
     104             :  */
     105             : template <class ActionsList>
     106           1 : using get_const_global_cache_tags_from_actions =
     107             :     tmpl::remove_duplicates<tmpl::join<tmpl::transform<
     108             :         ActionsList,
     109             :         detail::get_const_global_cache_tags_from_parallel_struct<tmpl::_1>>>>;
     110             : 
     111             : /*!
     112             :  * \ingroup ParallelGroup
     113             :  * \brief Given a list of Actions, get a list of the unique tags specified in
     114             :  * the actions' `mutable_global_cache_tags` aliases.
     115             :  */
     116             : template <class ActionsList>
     117           1 : using get_mutable_global_cache_tags_from_actions =
     118             :     tmpl::remove_duplicates<tmpl::join<tmpl::transform<
     119             :         ActionsList,
     120             :         detail::get_mutable_global_cache_tags_from_parallel_struct<tmpl::_1>>>>;
     121             : 
     122             : /*!
     123             :  * \ingroup ParallelGroup
     124             :  * \brief Given the metavariables, get a list of the unique tags that will
     125             :  * specify the items in the GlobalCache.
     126             :  */
     127             : template <typename Metavariables>
     128           1 : using get_const_global_cache_tags =
     129             :     tmpl::remove_duplicates<tmpl::flatten<tmpl::list<
     130             :         typename detail::get_const_global_cache_tags_from_parallel_struct<
     131             :             Metavariables>::type,
     132             :         tmpl::transform<
     133             :             typename Metavariables::component_list,
     134             :             detail::get_const_global_cache_tags_from_parallel_struct<tmpl::_1>>,
     135             :         tmpl::transform<
     136             :             typename Metavariables::component_list,
     137             :             detail::get_const_global_cache_tags_from_component<tmpl::_1>>>>>;
     138             : 
     139             : /*!
     140             :  * \ingroup ParallelGroup
     141             :  * \brief Given the metavariables, get a list of the unique tags that will
     142             :  * specify the mutable items in the GlobalCache.
     143             :  */
     144             : template <typename Metavariables>
     145           1 : using get_mutable_global_cache_tags =
     146             :     tmpl::remove_duplicates<tmpl::flatten<tmpl::list<
     147             :         typename detail::get_mutable_global_cache_tags_from_parallel_struct<
     148             :             Metavariables>::type,
     149             :         tmpl::transform<
     150             :             typename Metavariables::component_list,
     151             :             detail::get_mutable_global_cache_tags_from_parallel_struct<
     152             :                 tmpl::_1>>,
     153             :         tmpl::transform<
     154             :             typename Metavariables::component_list,
     155             :             detail::get_mutable_global_cache_tags_from_component<tmpl::_1>>>>>;
     156             : 
     157             : /*!
     158             :  * \ingroup ParallelGroup
     159             :  * \brief Check whether a tag is retrievable from the const portion of
     160             :  * the global cache.
     161             :  */
     162             : template <typename Metavariables, typename Tag>
     163           1 : constexpr bool is_in_const_global_cache =
     164             :     tmpl::size<tmpl::filter<get_const_global_cache_tags<Metavariables>,
     165             :                             std::is_base_of<tmpl::pin<Tag>, tmpl::_1>>>::value >
     166             :     0;
     167             : 
     168             : /*!
     169             :  * \ingroup ParallelGroup
     170             :  * \brief Check whether a tag is retrievable from the mutable portion of
     171             :  * the global cache.
     172             :  */
     173             : template <typename Metavariables, typename Tag>
     174           1 : constexpr bool is_in_mutable_global_cache =
     175             :     tmpl::size<tmpl::filter<get_mutable_global_cache_tags<Metavariables>,
     176             :                             std::is_base_of<tmpl::pin<Tag>, tmpl::_1>>>::value >
     177             :     0;
     178             : 
     179             : /*!
     180             :  * \ingroup ParallelGroup
     181             :  * \brief Check whether a tag is retrievable from the global cache.
     182             :  */
     183             : template <typename Metavariables, typename Tag>
     184           1 : constexpr bool is_in_global_cache =
     185             :     is_in_const_global_cache<Metavariables, Tag> or
     186             :     is_in_mutable_global_cache<Metavariables, Tag>;
     187             : 
     188             : template <typename Tag>
     189           0 : struct MutexTag {
     190           0 :   using type = std::pair<std::mutex, std::mutex>;
     191             : };
     192             : 
     193             : template <typename Tag>
     194           0 : struct MutableCacheTag {
     195           0 :   using tag = Tag;
     196           0 :   using type =
     197             :       std::tuple<typename Tag::type,
     198             :                  std::unordered_map<Parallel::ArrayComponentId,
     199             :                                     std::vector<std::unique_ptr<Callback>>>>;
     200             : };
     201             : 
     202             : template <typename Tag>
     203           0 : struct get_mutable_cache_tag {
     204           0 :   using type = MutableCacheTag<Tag>;
     205             : };
     206             : 
     207             : template <typename Metavariables>
     208           0 : using get_mutable_global_cache_tag_storage =
     209             :     tmpl::transform<get_mutable_global_cache_tags<Metavariables>,
     210             :                     get_mutable_cache_tag<tmpl::_1>>;
     211             : 
     212             : namespace GlobalCache_detail {
     213             : 
     214             : template <typename T>
     215             : struct type_for_get_helper {
     216             :   using type = T;
     217             : };
     218             : 
     219             : template <typename T, typename D>
     220             : struct type_for_get_helper<std::unique_ptr<T, D>> {
     221             :   using type = T;
     222             : };
     223             : 
     224             : // This struct provides a better error message if
     225             : // an unknown tag is requested from the GlobalCache.
     226             : template <typename GlobalCacheTag, typename ListOfPossibleTags>
     227             : struct matching_tag_helper {
     228             :   using found_tags =
     229             :       tmpl::filter<ListOfPossibleTags,
     230             :                    std::is_base_of<tmpl::pin<GlobalCacheTag>, tmpl::_1>>;
     231             :   static_assert(not std::is_same_v<found_tags, tmpl::list<>>,
     232             :                 "Trying to get a nonexistent tag from the GlobalCache. "
     233             :                 "To diagnose the problem, search for "
     234             :                 "'matching_tag_helper' in the error message. "
     235             :                 "The first template parameter of "
     236             :                 "'matching_tag_helper' is the requested tag, and "
     237             :                 "the second template parameter is a tmpl::list of all the "
     238             :                 "tags in the GlobalCache.  One possible bug that may "
     239             :                 "lead to this error message is a missing or misspelled "
     240             :                 "const_global_cache_tags or mutable_global_cache_tags "
     241             :                 "type alias.");
     242             :   static_assert(tmpl::size<found_tags>::value == 1,
     243             :                 "Found more than one matching tag. "
     244             :                 "To diagnose the problem, search for "
     245             :                 "'matching_tag_helper' in the error message. "
     246             :                 "The first template parameter of "
     247             :                 "'matching_tag_helper' is the requested tag, and "
     248             :                 "the second template parameter is a tmpl::list of all the "
     249             :                 "tags in the GlobalCache.");
     250             :   using type = tmpl::front<found_tags>;
     251             : };
     252             : 
     253             : template <class GlobalCacheTag, class Metavariables>
     254             : using get_matching_mutable_tag = typename matching_tag_helper<
     255             :     GlobalCacheTag, get_mutable_global_cache_tags<Metavariables>>::type;
     256             : }  // namespace GlobalCache_detail
     257             : 
     258             : namespace detail {
     259             : template <typename PhaseAction>
     260             : struct get_initialization_actions_list {
     261             :   using type = tmpl::list<>;
     262             : };
     263             : 
     264             : template <typename InitializationActionsList>
     265             : struct get_initialization_actions_list<Parallel::PhaseActions<
     266             :     Parallel::Phase::Initialization, InitializationActionsList>> {
     267             :   using type = InitializationActionsList;
     268             : };
     269             : }  // namespace detail
     270             : 
     271             : /// \ingroup ParallelGroup
     272             : /// \brief Given the phase dependent action list, return the list of
     273             : /// actions in the Initialization phase (or an empty list if the Initialization
     274             : /// phase is absent from the phase dependent action list)
     275             : template <typename PhaseDepActionList>
     276           1 : using get_initialization_actions_list = tmpl::flatten<tmpl::transform<
     277             :     PhaseDepActionList, detail::get_initialization_actions_list<tmpl::_1>>>;
     278             : 
     279             : namespace detail {
     280             : template <typename Action, typename = std::void_t<>>
     281             : struct get_simple_tags_from_options_from_action {
     282             :   using type = tmpl::list<>;
     283             : };
     284             : 
     285             : template <typename Action>
     286             : struct get_simple_tags_from_options_from_action<
     287             :     Action, std::void_t<typename Action::simple_tags_from_options>> {
     288             :   using type = typename Action::simple_tags_from_options;
     289             : };
     290             : }  // namespace detail
     291             : 
     292             : /// \ingroup ParallelGroup
     293             : /// \brief Given a list of initialization actions, returns a list of the
     294             : /// unique simple_tags_from_options for all the actions.
     295             : template <typename InitializationActionsList>
     296           1 : using get_simple_tags_from_options =
     297             :     tmpl::remove_duplicates<tmpl::flatten<tmpl::transform<
     298             :         InitializationActionsList,
     299             :         detail::get_simple_tags_from_options_from_action<tmpl::_1>>>>;
     300             : 
     301             : /// Collect all initialization tags required by the metavariables.
     302             : ///
     303             : /// Initialization tags are the tags in the global cache, the
     304             : /// `simple_tags_from_options` from each component, and the
     305             : /// `array_allocation_tags` from each array component.
     306             : template <typename Metavariables>
     307           1 : struct all_initialization_tags {
     308             :  private:
     309             :   template <typename T>
     310           0 :   using simple_tags_from_options = typename T::simple_tags_from_options;
     311             :   template <typename T>
     312           0 :   using array_allocation_tags = typename T::array_allocation_tags;
     313             : 
     314             :  public:
     315           0 :   using type = tmpl::remove_duplicates<tmpl::append<
     316             :       get_const_global_cache_tags<Metavariables>,
     317             :       get_mutable_global_cache_tags<Metavariables>,
     318             :       tmpl::join<
     319             :           tmpl::transform<typename Metavariables::component_list,
     320             :                           tmpl::bind<simple_tags_from_options, tmpl::_1>>>,
     321             :       tmpl::join<
     322             :           tmpl::transform<tmpl::filter<typename Metavariables::component_list,
     323             :                                        Parallel::is_array<tmpl::_1>>,
     324             :                           tmpl::bind<array_allocation_tags, tmpl::_1>>>>>;
     325             : };
     326             : 
     327             : /// \copydoc all_initialization_tags
     328             : template <typename Metavariables>
     329           1 : using all_initialization_tags_t =
     330             :     typename all_initialization_tags<Metavariables>::type;
     331             : 
     332             : namespace detail {
     333             : template <typename SimpleTag, typename Metavariables,
     334             :           bool PassMetavariables = SimpleTag::pass_metavariables>
     335             : struct get_option_tags_from_simple_tag_impl {
     336             :   using type = typename SimpleTag::option_tags;
     337             : };
     338             : template <typename SimpleTag, typename Metavariables>
     339             : struct get_option_tags_from_simple_tag_impl<SimpleTag, Metavariables, true> {
     340             :   using type = typename SimpleTag::template option_tags<Metavariables>;
     341             : };
     342             : template <typename Metavariables>
     343             : struct get_option_tags_from_simple_tag {
     344             :   template <typename SimpleTag>
     345             :   using f = tmpl::type_from<
     346             :       get_option_tags_from_simple_tag_impl<SimpleTag, Metavariables>>;
     347             : };
     348             : }  // namespace detail
     349             : 
     350             : /// \ingroup ParallelGroup
     351             : /// \brief Given a list of simple tags, returns a list of the
     352             : /// unique option tags required to construct them.
     353             : template <typename SimpleTagsList, typename Metavariables>
     354           1 : using get_option_tags = tmpl::remove_duplicates<tmpl::flatten<tmpl::transform<
     355             :     SimpleTagsList, tmpl::bind<detail::get_option_tags_from_simple_tag<
     356             :                                    Metavariables>::template f,
     357             :                                tmpl::_1>>>>;
     358             : 
     359             : namespace detail {
     360             : template <typename Tag, typename = std::void_t<>>
     361             : struct is_tag_overlayable : std::false_type {};
     362             : 
     363             : template <typename Tag>
     364             : struct is_tag_overlayable<Tag, std::void_t<decltype(Tag::is_overlayable)>>
     365             :     : std::bool_constant<Tag::is_overlayable> {};
     366             : }  // namespace detail
     367             : 
     368             : /// Get the subset of `const_global_cache_tags` that are overlayable.
     369             : ///
     370             : /// Note this is a list of tags in the GlobalCache, but is not a list of option
     371             : /// tags.
     372             : ///
     373             : /// By default, tags are not overlayable, i.e., can not be reparsed to update
     374             : /// a simulation value after a restart from checkpoint. Any tag can "opt in"
     375             : /// and become overlayable by specifying a member variable
     376             : /// `static constexpr bool is_overlayable = true`.
     377             : /// This should be done with caution: changing the value of this tag
     378             : /// must not have any side effects that might invalidate past of current
     379             : /// simulation data. For example, the parameters determining the time stepper
     380             : /// should not be overlayable, because it interacts with the time stepper
     381             : /// history data. But parameters determining the frequency
     382             : /// for (non-dense) reductions to file can be updated on restarts.
     383             : template <typename Metavariables>
     384           1 : using get_overlayable_tag_list =
     385             :     tmpl::filter<get_const_global_cache_tags<Metavariables>,
     386             :                  detail::is_tag_overlayable<tmpl::_1>>;
     387             : 
     388             : /// Get the overlayable option tags.
     389             : ///
     390             : /// These are the option tags that are only used to construct things
     391             : /// in `get_overlayable_tag_list`.
     392             : template <typename Metavariables>
     393           1 : using get_overlayable_option_list = tmpl::list_difference<
     394             :     get_option_tags<get_const_global_cache_tags<Metavariables>, Metavariables>,
     395             :     get_option_tags<
     396             :         tmpl::remove_if<all_initialization_tags_t<Metavariables>,
     397             :                         tmpl::and_<tmpl::lazy::list_contains<
     398             :                                        tmpl::pin<get_const_global_cache_tags<
     399             :                                            Metavariables>>,
     400             :                                        tmpl::_1>,
     401             :                                    detail::is_tag_overlayable<tmpl::_1>>>,
     402             :         Metavariables>>;
     403             : 
     404             : /// \cond
     405             : namespace Algorithms {
     406             : struct Singleton;
     407             : struct Array;
     408             : struct Group;
     409             : struct Nodegroup;
     410             : }  // namespace Algorithms
     411             : 
     412             : template <class ChareType>
     413             : struct get_array_index;
     414             : 
     415             : template <>
     416             : struct get_array_index<Parallel::Algorithms::Singleton> {
     417             :   template <class ParallelComponent>
     418             :   using f = int;
     419             : };
     420             : 
     421             : template <>
     422             : struct get_array_index<Parallel::Algorithms::Array> {
     423             :   template <class ParallelComponent>
     424             :   using f = typename ParallelComponent::array_index;
     425             : };
     426             : 
     427             : template <>
     428             : struct get_array_index<Parallel::Algorithms::Group> {
     429             :   template <class ParallelComponent>
     430             :   using f = int;
     431             : };
     432             : 
     433             : template <>
     434             : struct get_array_index<Parallel::Algorithms::Nodegroup> {
     435             :   template <class ParallelComponent>
     436             :   using f = int;
     437             : };
     438             : 
     439             : template <typename ParallelComponent>
     440             : using proxy_from_parallel_component =
     441             :     typename ParallelComponent::chare_type::template cproxy<
     442             :         ParallelComponent,
     443             :         typename get_array_index<typename ParallelComponent::chare_type>::
     444             :             template f<ParallelComponent>>;
     445             : 
     446             : template <typename ParallelComponent>
     447             : using index_from_parallel_component =
     448             :     typename ParallelComponent::chare_type::template ckindex<
     449             :         ParallelComponent,
     450             :         typename get_array_index<typename ParallelComponent::chare_type>::
     451             :             template f<ParallelComponent>>;
     452             : 
     453             : template <typename ParallelComponent>
     454             : using proxy_element_from_component =
     455             :     typename proxy_from_parallel_component<ParallelComponent>::element_t;
     456             : 
     457             : template <class ParallelComponent, class... Args>
     458             : struct charm_types_with_parameters {
     459             :   using cproxy =
     460             :       typename ParallelComponent::chare_type::template cproxy<ParallelComponent,
     461             :                                                               Args...>;
     462             :   using cbase =
     463             :       typename ParallelComponent::chare_type::template cbase<ParallelComponent,
     464             :                                                              Args...>;
     465             :   using algorithm =
     466             :       typename ParallelComponent::chare_type::template algorithm_type<
     467             :           ParallelComponent, Args...>;
     468             :   using ckindex = typename ParallelComponent::chare_type::template ckindex<
     469             :       ParallelComponent, Args...>;
     470             :   using cproxy_section =
     471             :       typename ParallelComponent::chare_type::template cproxy_section<
     472             :           ParallelComponent, Args...>;
     473             : };
     474             : /// \endcond
     475             : }  // namespace Parallel

Generated by: LCOV version 1.14