SpECTRE Documentation Coverage Report
Current view: top level - Parallel - ParallelComponentHelpers.hpp Coverage Total Hit
Commit: 0d1d717af84a81fb1284a20c4013708fe85cc2f0 Lines: 55.6 % 27 15
Test Date: 2026-10-22 17:29:42
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 2.0-1