ConstGlobalCache.hpp
Go to the documentation of this file.
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 /// \file
5 /// Defines class template ConstGlobalCache.
6 
7 #pragma once
8 
9 #include <string>
10 
12 #include "ErrorHandling/Assert.hpp"
13 #include "Parallel/CharmRegistration.hpp"
14 #include "Parallel/ConstGlobalCacheHelper.hpp"
15 #include "Parallel/ParallelComponentHelpers.hpp"
16 #include "Utilities/PrettyType.hpp"
17 #include "Utilities/Requires.hpp"
18 #include "Utilities/TMPL.hpp"
20 
21 #include "Parallel/ConstGlobalCache.decl.h"
22 
23 namespace Parallel {
24 
25 namespace ConstGlobalCache_detail {
26 template <typename T>
27 struct type_for_get_helper {
28  using type = T;
29 };
30 
31 template <typename T, typename D>
32 struct type_for_get_helper<std::unique_ptr<T, D>> {
33  using type = T;
34 };
35 
36 // Note: Returned list does not need to be size 1
37 template <class ConstGlobalCacheTag, class Metavariables>
38 using get_list_of_matching_tags =
39  tmpl::filter<typename ConstGlobalCache<Metavariables>::tag_list,
41 
42 template <class ConstGlobalCacheTag, class Metavariables>
43 using type_for_get = typename type_for_get_helper<
44  typename tmpl::front<ConstGlobalCache_detail::get_list_of_matching_tags<
45  ConstGlobalCacheTag, Metavariables>>::type>::type;
46 
47 template <typename ComponentFromList, typename ComponentToFind>
48 struct get_component_if_mocked_helper
49  : std::is_same<typename ComponentFromList::component_being_mocked,
50  ComponentToFind> {};
51 
52 /// In order to be able to use a mock action testing framework we need to be
53 /// able to get the correct parallel component from the global cache even when
54 /// the correct component is a mock. We do this by having the mocked components
55 /// have a member type alias `component_being_mocked`, and having
56 /// `Parallel::get_component` check if the component to be retrieved is in the
57 /// `metavariables::component_list`. If it is not in the `component_list` then
58 /// we search for a mock component that is mocking the component we are trying
59 /// to retrieve.
60 template <typename ComponentList, typename ParallelComponent>
61 using get_component_if_mocked = tmpl::front<tmpl::type_from<tmpl::conditional_t<
62  tmpl::list_contains_v<ComponentList, ParallelComponent>,
63  tmpl::type_<tmpl::list<ParallelComponent>>,
64  tmpl::lazy::find<ComponentList,
65  get_component_if_mocked_helper<
66  tmpl::_1, tmpl::pin<ParallelComponent>>>>>>;
67 } // namespace ConstGlobalCache_detail
68 
69 /// \ingroup ParallelGroup
70 /// A Charm++ chare that caches constant data once per Charm++ node.
71 ///
72 /// Metavariables must define the following metavariables:
73 /// - const_global_cache_tag_list typelist of tags of constant data
74 /// - component_list typelist of ParallelComponents
75 template <typename Metavariables>
76 class ConstGlobalCache : public CBase_ConstGlobalCache<Metavariables> {
77  using parallel_component_tag_list = tmpl::transform<
78  typename Metavariables::component_list,
79  tmpl::bind<
80  tmpl::type_,
81  tmpl::bind<Parallel::proxy_from_parallel_component, tmpl::_1>>>;
82 
83  public:
84  /// Access to the Metavariables template parameter
86  /// Typelist of the tags of constant data stored in the ConstGlobalCache
87  using tag_list = ConstGlobalCache_detail::make_tag_list<Metavariables>;
88  /// Typelist of the ParallelComponents stored in the ConstGlobalCache
89  using component_list = typename Metavariables::component_list;
90 
91  explicit ConstGlobalCache(
92  tuples::tagged_tuple_from_typelist<tag_list> const_global_cache) noexcept
93  : const_global_cache_(std::move(const_global_cache)) {}
94  explicit ConstGlobalCache(CkMigrateMessage* /*msg*/) {}
95  ~ConstGlobalCache() noexcept override {
98  CkIndex_ConstGlobalCache<Metavariables>>::registrar;
99  }
100  /// \cond
101  ConstGlobalCache(const ConstGlobalCache&) = default;
102  ConstGlobalCache& operator=(const ConstGlobalCache&) = default;
103  ConstGlobalCache(ConstGlobalCache&&) = default;
104  ConstGlobalCache& operator=(ConstGlobalCache&&) = default;
105  /// \endcond
106 
107  /// Entry method to set the ParallelComponents (should only be called once)
108  void set_parallel_components(
109  tuples::tagged_tuple_from_typelist<parallel_component_tag_list>&
110  parallel_components,
111  const CkCallback& callback) noexcept;
112 
113  private:
114  // clang-tidy: false positive, redundant declaration
115  template <typename ConstGlobalCacheTag, typename MV>
116  friend auto get(const ConstGlobalCache<MV>& cache) noexcept // NOLINT
117  -> const ConstGlobalCache_detail::type_for_get<ConstGlobalCacheTag, MV>&;
118 
119  // clang-tidy: false positive, redundant declaration
120  template <typename ParallelComponentTag, typename MV>
121  friend auto get_parallel_component( // NOLINT
122  ConstGlobalCache<MV>& cache) noexcept
123  -> Parallel::proxy_from_parallel_component<
124  ConstGlobalCache_detail::get_component_if_mocked<
125  typename MV::component_list, ParallelComponentTag>>&;
126 
127  // clang-tidy: false positive, redundant declaration
128  template <typename ParallelComponentTag, typename MV>
129  friend auto get_parallel_component( // NOLINT
130  const ConstGlobalCache<MV>& cache) noexcept
131  -> const Parallel::proxy_from_parallel_component<
132  ConstGlobalCache_detail::get_component_if_mocked<
133  typename MV::component_list,
134  ParallelComponentTag>>&; // NOLINT
135 
136  tuples::tagged_tuple_from_typelist<tag_list> const_global_cache_;
137  tuples::tagged_tuple_from_typelist<parallel_component_tag_list>
138  parallel_components_;
139  bool parallel_components_have_been_set_{false};
140 };
141 
142 template <typename Metavariables>
144  tuples::tagged_tuple_from_typelist<parallel_component_tag_list>&
145  parallel_components,
146  const CkCallback& callback) noexcept {
147  ASSERT(!parallel_components_have_been_set_,
148  "Can only set the parallel_components once");
149  parallel_components_ = std::move(parallel_components);
150  parallel_components_have_been_set_ = true;
151  this->contribute(callback);
152 }
153 
154 // @{
155 /// \ingroup ParallelGroup
156 /// \brief Access the Charm++ proxy associated with a ParallelComponent
157 ///
158 /// \requires ParallelComponentTag is a tag in component_list
159 ///
160 /// \returns a Charm++ proxy that can be used to call an entry method on the
161 /// chare(s)
162 template <typename ParallelComponentTag, typename Metavariables>
164  -> Parallel::proxy_from_parallel_component<
165  ConstGlobalCache_detail::get_component_if_mocked<
166  typename Metavariables::component_list, ParallelComponentTag>>& {
167  return tuples::get<tmpl::type_<Parallel::proxy_from_parallel_component<
168  ConstGlobalCache_detail::get_component_if_mocked<
169  typename Metavariables::component_list, ParallelComponentTag>>>>(
170  cache.parallel_components_);
171 }
172 
173 template <typename ParallelComponentTag, typename Metavariables>
175  const ConstGlobalCache<Metavariables>& cache) noexcept
176  -> const Parallel::proxy_from_parallel_component<
177  ConstGlobalCache_detail::get_component_if_mocked<
178  typename Metavariables::component_list, ParallelComponentTag>>& {
179  return tuples::get<tmpl::type_<Parallel::proxy_from_parallel_component<
180  ConstGlobalCache_detail::get_component_if_mocked<
181  typename Metavariables::component_list, ParallelComponentTag>>>>(
182  cache.parallel_components_);
183 }
184 // @}
185 
186 // @{
187 /// \ingroup ParallelGroup
188 /// \brief Access data in the cache
189 ///
190 /// \requires ConstGlobalCacheTag is a tag in tag_list
191 ///
192 /// \returns a constant reference to an object in the cache
193 template <typename ConstGlobalCacheTag, typename Metavariables>
194 auto get(const ConstGlobalCache<Metavariables>& cache) noexcept -> const
195  ConstGlobalCache_detail::type_for_get<ConstGlobalCacheTag, Metavariables>& {
196  // We check if the tag is to be retrieved directly or via a base class
197  using tag = tmpl::front<ConstGlobalCache_detail::get_list_of_matching_tags<
198  ConstGlobalCacheTag, Metavariables>>;
199  static_assert(tmpl::size<ConstGlobalCache_detail::get_list_of_matching_tags<
200  ConstGlobalCacheTag, Metavariables>>::value == 1,
201  "Found more than one tag matching the ConstGlobalCacheTag "
202  "requesting to be retrieved.");
203  return make_overloader(
204  [](std::true_type /*is_unique_ptr*/, auto&& local_cache)
205  -> decltype(
206  *(tuples::get<tag>(local_cache.const_global_cache_).get())) {
207  return *(
208  tuples::get<tag>(local_cache.const_global_cache_)
209  .get());
210  },
211  [](std::false_type /*is_unique_ptr*/, auto&& local_cache)
212  -> decltype(tuples::get<tag>(local_cache.const_global_cache_)) {
213  return tuples::get<tag>(
214  local_cache.const_global_cache_);
216 }
217 
218 namespace Tags {
219 /// \ingroup DataBoxTagsGroup
220 /// \ingroup ParallelGroup
221 /// Tag to retrieve the `Parallel::ConstGlobalCache` from the DataBox.
223 
224 template <class Metavariables>
227  static std::string name() noexcept { return "ConstGlobalCache"; }
228 };
229 
230 /// \ingroup DataBoxTagsGroup
231 /// \ingroup ParallelGroup
232 /// Tag used to retrieve data from the `Parallel::ConstGlobalCache`. This is the
233 /// recommended way for compute tags to retrieve data out of the global cache.
234 template <class CacheTag>
236  static std::string name() noexcept {
237  return "FromConstGlobalCache(" + pretty_type::short_name<CacheTag>() + ")";
238  }
239  template <class Metavariables>
240  static const auto& function(
241  const Parallel::ConstGlobalCache<Metavariables>* const& cache) noexcept {
242  return Parallel::get<CacheTag>(*cache);
243  }
244  using argument_tags = tmpl::list<ConstGlobalCache>;
245 };
246 } // namespace Tags
247 } // namespace Parallel
248 
249 #define CK_TEMPLATES_ONLY
250 #include "Parallel/ConstGlobalCache.def.h"
251 #undef CK_TEMPLATES_ONLY
Defines class tuples::TaggedTuple.
Overloader< Fs... > make_overloader(Fs... fs)
Create Overloader<Fs...>, see Overloader for details.
Definition: Overloader.hpp:109
typename Component::metavariables metavariables
Access to the Metavariables template parameter.
Definition: ConstGlobalCache.hpp:85
constexpr Tag::type & get(Variables< TagList > &v) noexcept
Return Tag::type pointing into the contiguous array.
Definition: Variables.hpp:649
Tag used to retrieve data from the Parallel::ConstGlobalCache. This is the recommended way for comput...
Definition: ConstGlobalCache.hpp:235
void set_parallel_components(tuples::tagged_tuple_from_typelist< parallel_component_tag_list > &parallel_components, const CkCallback &callback) noexcept
Entry method to set the ParallelComponents (should only be called once)
Definition: ConstGlobalCache.hpp:143
Marks a DataBoxTag as being a compute item that executes a function.
Definition: DataBoxTag.hpp:155
Tags for the DataBox inherit from this type.
Definition: DataBoxTag.hpp:65
#define ASSERT(a, m)
Assert that an expression should be true.
Definition: Assert.hpp:49
Contains functions that forward to Charm++ parallel functions.
Definition: Abort.hpp:13
Defines the type alias Requires.
typename typename Component::metavariables ::component_list component_list
Typelist of the ParallelComponents stored in the ConstGlobalCache.
Definition: ConstGlobalCache.hpp:89
Definition: DataBoxTag.hpp:29
A Charm++ chare that caches constant data once per Charm++ node.
Definition: ConstGlobalCache.hpp:76
Check if type T is a template specialization of U
Definition: TypeTraits.hpp:536
Defines macro ASSERT.
Tag to retrieve the Parallel::ConstGlobalCache from the DataBox.
Definition: ConstGlobalCache.hpp:222
Contains a pretty_type library to write types in a "pretty" format.
Derived class for registering chares.
Definition: CharmRegistration.hpp:172
Wraps the template metaprogramming library used (brigand)
auto get_parallel_component(ConstGlobalCache< Metavariables > &cache) noexcept -> Parallel::proxy_from_parallel_component< ConstGlobalCache_detail::get_component_if_mocked< typename Metavariables::component_list, ParallelComponentTag >> &
Access the Charm++ proxy associated with a ParallelComponent.
Definition: ConstGlobalCache.hpp:163
Tags that are base tags, i.e. a simple or compute tag must derive off them for them to be useful...
Definition: DataBoxTag.hpp:83
Definition: ConstGlobalCache.hpp:225
Definition: SolvePoissonProblem.hpp:38
Defines classes SimpleTag, PrefixTag, ComputeTag and several functions for retrieving tag info...
ConstGlobalCache_detail::make_tag_list< typename Component::metavariables > tag_list
Typelist of the tags of constant data stored in the ConstGlobalCache.
Definition: ConstGlobalCache.hpp:87