GlobalCache.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 GlobalCache.
6 
7 #pragma once
8 
9 #include <optional>
10 #include <string>
11 #include <tuple>
12 #include <vector>
13 
14 #include "DataStructures/DataBox/Tag.hpp"
15 #include "ErrorHandling/Assert.hpp"
16 #include "ErrorHandling/Error.hpp"
17 #include "Parallel/CharmRegistration.hpp"
18 #include "Parallel/ParallelComponentHelpers.hpp"
19 #include "Utilities/Gsl.hpp"
20 #include "Utilities/PrettyType.hpp"
21 #include "Utilities/Requires.hpp"
22 #include "Utilities/TMPL.hpp"
23 #include "Utilities/TaggedTuple.hpp"
24 #include "Utilities/TypeTraits/IsA.hpp"
25 
26 #include "Parallel/GlobalCache.decl.h"
27 
28 namespace Parallel {
29 
30 namespace GlobalCache_detail {
31 
32 template <class GlobalCacheTag, class Metavariables>
33 using get_matching_tag = typename matching_tag_helper<
34  GlobalCacheTag,
35  tmpl::append<get_const_global_cache_tags<Metavariables>,
36  get_mutable_global_cache_tags<Metavariables>>>::type;
37 
38 template <class GlobalCacheTag, class Metavariables>
39 using type_for_get = typename type_for_get_helper<
40  typename get_matching_tag<GlobalCacheTag, Metavariables>::type>::type;
41 
42 template <class T, class = std::void_t<>>
43 struct has_component_being_mocked_alias : std::false_type {};
44 
45 template <class T>
46 struct has_component_being_mocked_alias<
47  T, std::void_t<typename T::component_being_mocked>> : std::true_type {};
48 
49 template <class T>
50 constexpr bool has_component_being_mocked_alias_v =
51  has_component_being_mocked_alias<T>::value;
52 
53 template <typename ComponentToFind, typename ComponentFromList>
54 struct get_component_if_mocked_helper {
55  static_assert(
56  has_component_being_mocked_alias_v<ComponentFromList>,
57  "The parallel component was not found, and it looks like it is not being "
58  "mocked. Did you forget to add it to the "
59  "'Metavariables::component_list'? See the first template parameter for "
60  "the component that we are looking for and the second template parameter "
61  "for the component that is being checked for mocking it.");
62  using type = std::is_same<typename ComponentFromList::component_being_mocked,
63  ComponentToFind>;
64 };
65 
66 template <typename... Tags>
67 auto make_mutable_cache_tag_storage(
68  tuples::TaggedTuple<Tags...>&& input) noexcept {
69  return tuples::TaggedTuple<MutableCacheTag<Tags>...>(std::make_tuple(
70  std::move(tuples::get<Tags>(input)), std::vector<CkCallback>{})...);
71 }
72 
73 /// In order to be able to use a mock action testing framework we need to be
74 /// able to get the correct parallel component from the global cache even when
75 /// the correct component is a mock. We do this by having the mocked
76 /// components have a member type alias `component_being_mocked`, and having
77 /// `Parallel::get_component` check if the component to be retrieved is in the
78 /// `metavariables::component_list`. If it is not in the `component_list` then
79 /// we search for a mock component that is mocking the component we are trying
80 /// to retrieve.
81 template <typename ComponentList, typename ParallelComponent>
82 using get_component_if_mocked = tmpl::front<tmpl::type_from<tmpl::conditional_t<
83  tmpl::list_contains_v<ComponentList, ParallelComponent>,
84  tmpl::type_<tmpl::list<ParallelComponent>>,
85  tmpl::lazy::find<ComponentList,
86  tmpl::type_<get_component_if_mocked_helper<
87  tmpl::pin<ParallelComponent>, tmpl::_1>>>>>>;
88 } // namespace GlobalCache_detail
89 
90 /// \ingroup ParallelGroup
91 /// A Charm++ chare that caches mutable data once per Charm++ core.
92 ///
93 /// `MutableGlobalCache` is not intended to be visible to the end user; its
94 /// interface is via the `GlobalCache` member functions
95 /// `mutable_cache_item_is_ready`, `mutate`, and `get`.
96 /// Accordingly, most documentation of `MutableGlobalCache` is provided
97 /// in the relevant `GlobalCache` member functions.
98 template <typename Metavariables>
99 class MutableGlobalCache : public CBase_MutableGlobalCache<Metavariables> {
100  public:
101  explicit MutableGlobalCache(tuples::tagged_tuple_from_typelist<
103  mutable_global_cache) noexcept;
104  explicit MutableGlobalCache(CkMigrateMessage* /*msg*/) {}
105  ~MutableGlobalCache() noexcept override {
108  CkIndex_MutableGlobalCache<Metavariables>>::registrar;
109  }
110  /// \cond
111  MutableGlobalCache(const MutableGlobalCache&) = default;
112  MutableGlobalCache& operator=(const MutableGlobalCache&) = default;
114  MutableGlobalCache& operator=(MutableGlobalCache&&) = default;
115  /// \endcond
116 
117  template <typename GlobalCacheTag>
118  auto get() const noexcept
119  -> const GlobalCache_detail::type_for_get<GlobalCacheTag, Metavariables>&;
120 
121  // Entry method to mutate the object indentified by `GlobalCacheTag`.
122  // Internally calls Function::apply(), where
123  // Function is a struct, and Function::apply is a user-defined
124  // static function that mutates the object. Function::apply() takes
125  // as its first argument a gsl::not_null pointer to the object named
126  // by the GlobalCacheTag, and then the contents of 'args' as
127  // subsequent arguments. Called via `GlobalCache::mutate`.
128  template <typename GlobalCacheTag, typename Function, typename... Args>
129  void mutate(const std::tuple<Args...>& args) noexcept;
130 
131  // Not an entry method, and intended to be called only from
132  // `GlobalCache` via the free function
133  // `Parallel::mutable_cache_item_is_ready`. See the free function
134  // `Parallel::mutable_cache_item_is_ready` for documentation.
135  template <typename GlobalCacheTag, typename Function>
136  bool mutable_cache_item_is_ready(const Function& function) noexcept;
137 
138  private:
139  tuples::tagged_tuple_from_typelist<
140  get_mutable_global_cache_tag_storage<Metavariables>>
141  mutable_global_cache_{};
142 };
143 
144 template <typename Metavariables>
146  tuples::tagged_tuple_from_typelist<
148  mutable_global_cache) noexcept
149  : mutable_global_cache_(GlobalCache_detail::make_mutable_cache_tag_storage(
150  std::move(mutable_global_cache))) {}
151 
152 template <typename Metavariables>
153 template <typename GlobalCacheTag>
154 auto MutableGlobalCache<Metavariables>::get() const noexcept
155  -> const GlobalCache_detail::type_for_get<GlobalCacheTag, Metavariables>& {
156  using tag = MutableCacheTag<
157  GlobalCache_detail::get_matching_tag<GlobalCacheTag, Metavariables>>;
158  if constexpr (tt::is_a_v<std::unique_ptr, typename tag::tag::type>) {
159  return *(std::get<0>(tuples::get<tag>(mutable_global_cache_)));
160  } else {
161  return std::get<0>(tuples::get<tag>(mutable_global_cache_));
162  }
163 }
164 
165 template <typename Metavariables>
166 template <typename GlobalCacheTag, typename Function>
167 bool MutableGlobalCache<Metavariables>::mutable_cache_item_is_ready(
168  const Function& function) noexcept {
169  using tag = MutableCacheTag<GlobalCache_detail::get_matching_mutable_tag<
170  GlobalCacheTag, Metavariables>>;
171  std::optional<CkCallback> optional_callback{};
172  if constexpr (tt::is_a_v<std::unique_ptr, typename tag::tag::type>) {
173  optional_callback =
174  function(*(std::get<0>(tuples::get<tag>(mutable_global_cache_))));
175  } else {
176  optional_callback =
177  function(std::get<0>(tuples::get<tag>(mutable_global_cache_)));
178  }
179  if (optional_callback) {
180  std::get<1>(tuples::get<tag>(mutable_global_cache_))
181  .push_back(std::move(*optional_callback));
182  if (std::get<1>(tuples::get<tag>(mutable_global_cache_)).size() > 20000) {
183  ERROR("The number of callbacks in MutableGlobalCache for tag "
184  << pretty_type::short_name<GlobalCacheTag>()
185  << " has gotten too large, and may be growing without bound");
186  }
187  return false;
188  } else {
189  // The user-defined `function` didn't specify a callback, which
190  // means that the item is ready.
191  return true;
192  }
193 }
194 
195 template <typename Metavariables>
196 template <typename GlobalCacheTag, typename Function, typename... Args>
197 void MutableGlobalCache<Metavariables>::mutate(
198  const std::tuple<Args...>& args) noexcept {
200  Metavariables, GlobalCacheTag, Function, Args...>::registrar;
201  using tag = MutableCacheTag<GlobalCache_detail::get_matching_mutable_tag<
202  GlobalCacheTag, Metavariables>>;
203 
204  // Do the mutate.
205  std::apply(
206  [this](const auto&... local_args) noexcept {
207  Function::apply(make_not_null(&std::get<0>(
208  tuples::get<tag>(mutable_global_cache_))),
209  local_args...);
210  },
211  args);
212 
213  // Call the callbacks and clear the list of callbacks.
214  for (auto& callback : std::get<1>(tuples::get<tag>(mutable_global_cache_))) {
215  callback.send(nullptr);
216  }
217  std::get<1>(tuples::get<tag>(mutable_global_cache_)).clear();
218  std::get<1>(tuples::get<tag>(mutable_global_cache_)).shrink_to_fit();
219 }
220 
221 /// \ingroup ParallelGroup
222 /// A Charm++ chare that caches constant data once per Charm++ node or
223 /// non-constant data once per Charm++ core.
224 ///
225 /// `Metavariables` must define the following metavariables:
226 /// - `component_list` typelist of ParallelComponents
227 /// - `const_global_cache_tags` (possibly empty) typelist of tags of
228 /// constant data
229 /// - `mutable_global_cache_tags` (possibly empty) typelist of tags of
230 /// non-constant data
231 ///
232 /// The tag lists for the const items added to the GlobalCache is created by
233 /// combining the following tag lists:
234 /// - `Metavariables::const_global_cache_tags` which should contain only those
235 /// tags that cannot be added from the other tag lists below.
236 /// - `Component::const_global_cache_tags` for each `Component` in
237 /// `Metavariables::component_list` which should contain the tags needed by
238 /// any simple actions called on the Component, as well as tags need by the
239 /// `allocate_array` function of an array component. The type alias may be
240 /// omitted for an empty list.
241 /// - `Action::const_global_cache_tags` for each `Action` in the
242 /// `phase_dependent_action_list` of each `Component` of
243 /// `Metavariables::component_list` which should contain the tags needed by
244 /// that Action. The type alias may be omitted for an empty list.
245 ///
246 /// The tag lists for the non-const items added to the GlobalCache is created
247 /// by combining exactly the same tag lists as for the const items, except with
248 /// `const_global_cache_tags` replaced by `mutable_global_cache_tags`.
249 ///
250 /// The tags in the `const_global_cache_tags` and
251 /// `mutable_global_cache_tags` type lists are db::SimpleTag%s that
252 /// have a `using option_tags` type alias and a static function
253 /// `create_from_options` that are used to create the constant data
254 /// from input file options.
255 ///
256 /// References to const items in the GlobalCache are also added to the
257 /// db::DataBox of each `Component` in the
258 /// `Metavariables::component_list` with the same tag with which they
259 /// were inserted into the GlobalCache. References to non-const items
260 /// in the GlobalCache are not added to the db::DataBox.
261 template <typename Metavariables>
262 class GlobalCache : public CBase_GlobalCache<Metavariables> {
263  using parallel_component_tag_list = tmpl::transform<
264  typename Metavariables::component_list,
265  tmpl::bind<
266  tmpl::type_,
267  tmpl::bind<Parallel::proxy_from_parallel_component, tmpl::_1>>>;
268 
269  public:
270  /// Access to the Metavariables template parameter
271  using metavariables = Metavariables;
272  /// Typelist of the ParallelComponents stored in the GlobalCache
273  using component_list = typename Metavariables::component_list;
274 
275  /// Constructor used only by the ActionTesting framework and other
276  /// non-charm++ tests that don't know about proxies.
277  GlobalCache(tuples::tagged_tuple_from_typelist<
279  const_global_cache,
280  MutableGlobalCache<Metavariables>* mutable_global_cache) noexcept;
281 
282  /// Constructor used by Main and anything else that is charm++ aware.
283  GlobalCache(tuples::tagged_tuple_from_typelist<
285  const_global_cache,
286  CProxy_MutableGlobalCache<Metavariables>
287  mutable_global_cache_proxy) noexcept;
288 
289  explicit GlobalCache(CkMigrateMessage* /*msg*/) {}
290  ~GlobalCache() noexcept override {
293  CkIndex_GlobalCache<Metavariables>>::registrar;
294  }
295  /// \cond
296  GlobalCache(const GlobalCache&) = default;
297  GlobalCache& operator=(const GlobalCache&) = default;
298  GlobalCache(GlobalCache&&) = default;
299  GlobalCache& operator=(GlobalCache&&) = default;
300  /// \endcond
301 
302  /// Entry method to set the ParallelComponents (should only be called once)
304  tuples::tagged_tuple_from_typelist<parallel_component_tag_list>&&
305  parallel_components,
306  const CkCallback& callback) noexcept;
307 
308  /// Returns whether the object referred to by `GlobalCacheTag`
309  /// (which must be a mutable cache tag) is ready to be accessed by a
310  /// `get` call.
311  ///
312  /// `function` is a user-defined invokable that:
313  /// - takes one argument: a const reference to the object referred to by the
314  /// `GlobalCacheTag`.
315  /// - if the data is ready, returns a default constructed
316  /// `std::optional<CkCallBack>`
317  /// - if the data is not ready, returns a `std::optional<CkCallBack>`,
318  /// where the `CkCallback` will re-invoke the current action on the
319  /// current parallel component.
320  template <typename GlobalCacheTag, typename Function>
321  bool mutable_cache_item_is_ready(const Function& function) noexcept;
322 
323  /// Mutates the non-const object identified by GlobalCacheTag.
324  /// \requires `GlobalCacheTag` is a tag in `mutable_global_cache_tags`
325  /// defined by the Metavariables and in Actions.
326  ///
327  /// Internally calls `Function::apply()`, where `Function` is a
328  /// user-defined struct and `Function::apply()` is a user-defined
329  /// static function that mutates the object. `Function::apply()`
330  /// takes as its first argument a `gsl::not_null` pointer to the
331  /// object named by the GlobalCacheTag, and takes the contents of
332  /// `args` as subsequent arguments.
333  template <typename GlobalCacheTag, typename Function, typename... Args>
334  void mutate(const std::tuple<Args...>& args) noexcept;
335 
336  private:
337  // clang-tidy: false positive, redundant declaration
338  template <typename GlobalCacheTag, typename MV>
339  friend auto get(const GlobalCache<MV>& cache) noexcept // NOLINT
340  -> const GlobalCache_detail::type_for_get<GlobalCacheTag, MV>&;
341 
342  // clang-tidy: false positive, redundant declaration
343  template <typename ParallelComponentTag, typename MV>
344  friend auto get_parallel_component( // NOLINT
345  GlobalCache<MV>& cache) noexcept
346  -> Parallel::proxy_from_parallel_component<
347  GlobalCache_detail::get_component_if_mocked<
348  typename MV::component_list, ParallelComponentTag>>&;
349 
350  // clang-tidy: false positive, redundant declaration
351  template <typename ParallelComponentTag, typename MV>
352  friend auto get_parallel_component( // NOLINT
353  const GlobalCache<MV>& cache) noexcept
354  -> const Parallel::proxy_from_parallel_component<
355  GlobalCache_detail::get_component_if_mocked<
356  typename MV::component_list,
357  ParallelComponentTag>>&; // NOLINT
358 
359  tuples::tagged_tuple_from_typelist<get_const_global_cache_tags<Metavariables>>
360  const_global_cache_{};
361  tuples::tagged_tuple_from_typelist<parallel_component_tag_list>
362  parallel_components_{};
363  // We store both a pointer and a proxy to the MutableGlobalCache.
364  // There is both a pointer and a proxy because we want to use
365  // MutableGlobalCache in production (where it must be charm-aware)
366  // and for simple testing (which we want to do in a non-charm-aware
367  // context for simplicity). If the charm-aware constructor is
368  // used, then the pointer is set to nullptr and the proxy is set.
369  // If the non-charm-aware constructor is used, the the pointer is
370  // set and the proxy is ignored. The member functions that need the
371  // MutableGlobalCache should use the pointer if it is not nullptr,
372  // otherwise use the proxy.
373  MutableGlobalCache<Metavariables>* mutable_global_cache_{nullptr};
374  CProxy_MutableGlobalCache<Metavariables> mutable_global_cache_proxy_{};
375  bool parallel_components_have_been_set_{false};
376 };
377 
378 template <typename Metavariables>
380  tuples::tagged_tuple_from_typelist<
382  const_global_cache,
383  MutableGlobalCache<Metavariables>* mutable_global_cache) noexcept
384  : const_global_cache_(std::move(const_global_cache)),
385  mutable_global_cache_(mutable_global_cache) {
386  ASSERT(mutable_global_cache_ != nullptr,
387  "GlobalCache: Do not construct with a nullptr!");
388 }
389 
390 template <typename Metavariables>
392  tuples::tagged_tuple_from_typelist<
394  const_global_cache,
395  CProxy_MutableGlobalCache<Metavariables>
396  mutable_global_cache_proxy) noexcept
397  : const_global_cache_(std::move(const_global_cache)),
398  mutable_global_cache_(nullptr),
399  mutable_global_cache_proxy_(std::move(mutable_global_cache_proxy)) {}
400 
401 template <typename Metavariables>
403  tuples::tagged_tuple_from_typelist<parallel_component_tag_list>&&
404  parallel_components,
405  const CkCallback& callback) noexcept {
406  ASSERT(!parallel_components_have_been_set_,
407  "Can only set the parallel_components once");
408  parallel_components_ = std::move(parallel_components);
409  parallel_components_have_been_set_ = true;
410  this->contribute(callback);
411 }
412 
413 template <typename Metavariables>
414 template <typename GlobalCacheTag, typename Function>
416  const Function& function) noexcept {
417  if (mutable_global_cache_ == nullptr) {
418  return mutable_global_cache_proxy_.ckLocalBranch()
419  ->template mutable_cache_item_is_ready<GlobalCacheTag>(function);
420  } else {
421  return mutable_global_cache_
422  ->template mutable_cache_item_is_ready<GlobalCacheTag>(function);
423  }
424 }
425 
426 template <typename Metavariables>
427 template <typename GlobalCacheTag, typename Function, typename... Args>
429  const std::tuple<Args...>& args) noexcept {
431  Metavariables, GlobalCacheTag, Function, Args...>::registrar;
432  if (mutable_global_cache_ == nullptr) {
433  // charm-aware version: Mutate the variable on all PEs on this node.
434  for (auto pe = CkNodeFirst(CkMyNode());
435  pe < CkNodeFirst(CkMyNode()) + CkNodeSize(CkMyNode()); ++pe) {
436  mutable_global_cache_proxy_[pe].template mutate<GlobalCacheTag, Function>(
437  args);
438  }
439  } else {
440  // version that bypasses proxies. Just call the function.
441  mutable_global_cache_->template mutate<GlobalCacheTag, Function>(args);
442  }
443 }
444 
445 // @{
446 /// \ingroup ParallelGroup
447 /// \brief Access the Charm++ proxy associated with a ParallelComponent
448 ///
449 /// \requires ParallelComponentTag is a tag in component_list
450 ///
451 /// \returns a Charm++ proxy that can be used to call an entry method on the
452 /// chare(s)
453 template <typename ParallelComponentTag, typename Metavariables>
455  -> Parallel::proxy_from_parallel_component<
456  GlobalCache_detail::get_component_if_mocked<
457  typename Metavariables::component_list, ParallelComponentTag>>& {
458  return tuples::get<tmpl::type_<Parallel::proxy_from_parallel_component<
459  GlobalCache_detail::get_component_if_mocked<
460  typename Metavariables::component_list, ParallelComponentTag>>>>(
461  cache.parallel_components_);
462 }
463 
464 template <typename ParallelComponentTag, typename Metavariables>
465 auto get_parallel_component(const GlobalCache<Metavariables>& cache) noexcept
466  -> const Parallel::proxy_from_parallel_component<
467  GlobalCache_detail::get_component_if_mocked<
468  typename Metavariables::component_list, ParallelComponentTag>>& {
469  return tuples::get<tmpl::type_<Parallel::proxy_from_parallel_component<
470  GlobalCache_detail::get_component_if_mocked<
471  typename Metavariables::component_list, ParallelComponentTag>>>>(
472  cache.parallel_components_);
473 }
474 // @}
475 
476 // @{
477 /// \ingroup ParallelGroup
478 /// \brief Access data in the cache
479 ///
480 /// \requires GlobalCacheTag is a tag in the `mutable_global_cache_tags`
481 /// or `const_global_cache_tags` defined by the Metavariables and in Actions.
482 ///
483 /// \returns a constant reference to an object in the cache
484 template <typename GlobalCacheTag, typename Metavariables>
485 auto get(const GlobalCache<Metavariables>& cache) noexcept
486  -> const GlobalCache_detail::type_for_get<GlobalCacheTag, Metavariables>& {
487  // We check if the tag is to be retrieved directly or via a base class
488  using tag =
489  GlobalCache_detail::get_matching_tag<GlobalCacheTag, Metavariables>;
490  using tag_is_not_in_const_tags = std::is_same<
491  tmpl::filter<get_const_global_cache_tags<Metavariables>,
493  tmpl::list<>>;
494  if constexpr (tag_is_not_in_const_tags::value) {
495  // Tag is not in the const tags, so use MutableGlobalCache
496  if (cache.mutable_global_cache_ == nullptr) {
497  const auto& local_mutable_cache =
498  *cache.mutable_global_cache_proxy_.ckLocalBranch();
499  return local_mutable_cache.template get<GlobalCacheTag>();
500  } else {
501  return cache.mutable_global_cache_->template get<GlobalCacheTag>();
502  }
503  } else {
504  // Tag is in the const tags, so use const_global_cache_
505  if constexpr (tt::is_a_v<std::unique_ptr, typename tag::type>) {
506  return *(tuples::get<tag>(cache.const_global_cache_));
507  } else {
508  return tuples::get<tag>(cache.const_global_cache_);
509  }
510  }
511 }
512 
513 /// \ingroup ParallelGroup
514 /// \brief Returns whether the object identified by `GlobalCacheTag`
515 /// is ready to be accessed by `get`.
516 ///
517 /// \requires `GlobalCacheTag` is a tag in `mutable_global_cache_tags`
518 /// defined by the Metavariables and in Actions.
519 ///
520 /// \requires `function` is a user-defined invokable that takes one argument:
521 /// a const reference to the object referred to by the
522 /// `GlobalCacheTag`. `function` returns a
523 /// `std::optional<CkCallBack>` that determines the readiness. To
524 /// indicate that the item is ready, the `std::optional` returned
525 /// by `function` must be invalid; in this case
526 /// `mutable_cache_item_is_ready` returns true. To indicate that the
527 /// item is not ready, the `std::optional` returned by `function`
528 /// must be valid; in this case, `mutable_cache_item_is_ready`
529 /// appends the `std::optional`'s wrapped `CkCallback` to an
530 /// internal list of callbacks to be called on `mutate`, and then
531 /// returns false.
532 template <typename GlobalCacheTag, typename Function, typename Metavariables>
534  const Function& function) noexcept {
535  return cache.template mutable_cache_item_is_ready<GlobalCacheTag>(function);
536 }
537 
538 /// \ingroup ParallelGroup
539 /// \brief Mutates non-const data in the cache, by calling `Function::apply()`
540 ///
541 /// \requires `GlobalCacheTag` is a tag in the `mutable_global_cache_tags`
542 /// defined by the Metavariables and in Actions.
543 /// \requires `Function` is a struct with a static void `apply()`
544 /// function that mutates the object. `Function::apply()` takes as its
545 /// first argument a `gsl::not_null` pointer to the object named by
546 /// the `GlobalCacheTag`, and takes `args` as
547 /// subsequent arguments.
548 ///
549 /// This is the version that takes a GlobalCache<Metavariables>. Used only
550 /// for tests.
551 template <typename GlobalCacheTag, typename Function, typename Metavariables,
552  typename... Args>
553 void mutate(GlobalCache<Metavariables>& cache, Args&&... args) noexcept {
554  cache.template mutate<GlobalCacheTag, Function>(
555  std::make_tuple<Args...>(std::forward<Args>(args)...));
556 }
557 
558 /// \ingroup ParallelGroup
559 ///
560 /// \brief Mutates non-const data in the cache, by calling `Function::apply()`
561 ///
562 /// \requires `GlobalCacheTag` is a tag in tag_list.
563 /// \requires `Function` is a struct with a static void `apply()`
564 /// function that mutates the object. `Function::apply()` takes as its
565 /// first argument a `gsl::not_null` pointer to the object named by
566 /// the `GlobalCacheTag`, and takes `args` as
567 /// subsequent arguments.
568 ///
569 /// This is the version that takes a charm++ proxy to the GlobalCache.
570 template <typename GlobalCacheTag, typename Function, typename Metavariables,
571  typename... Args>
572 void mutate(CProxy_GlobalCache<Metavariables>& cache_proxy,
573  Args&&... args) noexcept {
574  cache_proxy.template mutate<GlobalCacheTag, Function>(
575  std::make_tuple<Args...>(std::forward<Args>(args)...));
576 }
577 
578 namespace Tags {
579 /// \ingroup DataBoxTagsGroup
580 /// \ingroup ParallelGroup
581 /// Tag to retrieve the `Parallel::GlobalCache` from the DataBox.
583 
584 template <class Metavariables>
587  static std::string name() noexcept { return "GlobalCache"; }
588 };
589 
590 /// \ingroup DataBoxTagsGroup
591 /// \ingroup ParallelGroup
592 /// Tag used to retrieve data from the `Parallel::GlobalCache`. This is the
593 /// recommended way for compute tags to retrieve data out of the global cache.
594 template <class CacheTag>
595 struct FromGlobalCache : CacheTag, db::ComputeTag {
596  static std::string name() noexcept {
597  return "FromGlobalCache(" + pretty_type::short_name<CacheTag>() + ")";
598  }
599  template <class Metavariables>
600  static const GlobalCache_detail::type_for_get<CacheTag, Metavariables>&
601  function(const Parallel::GlobalCache<Metavariables>* const& cache) {
602  return Parallel::get<CacheTag>(*cache);
603  }
604  using argument_tags = tmpl::list<GlobalCache>;
605 };
606 } // namespace Tags
607 } // namespace Parallel
608 
609 #define CK_TEMPLATES_ONLY
610 #include "Parallel/GlobalCache.def.h"
611 #undef CK_TEMPLATES_ONLY
std::is_same
db::ComputeTag
Mark a struct as a compute tag by inheriting from this.
Definition: Tag.hpp:157
std::false_type
std::string
Parallel::GlobalCache< typename Component::metavariables >::metavariables
typename Component::metavariables metavariables
Access to the Metavariables template parameter.
Definition: GlobalCache.hpp:271
get
constexpr Tag::type & get(Variables< TagList > &v) noexcept
Return Tag::type pointing into the contiguous array.
Definition: Variables.hpp:638
Parallel::GlobalCache
Definition: ElementReceiveInterpPoints.hpp:15
Parallel::get_parallel_component
auto get_parallel_component(GlobalCache< Metavariables > &cache) noexcept -> Parallel::proxy_from_parallel_component< GlobalCache_detail::get_component_if_mocked< typename Metavariables::component_list, ParallelComponentTag >> &
Access the Charm++ proxy associated with a ParallelComponent.
Definition: GlobalCache.hpp:454
vector
Error.hpp
std::size
T size(T... args)
PrettyType.hpp
Parallel::GlobalCache::GlobalCache
GlobalCache(tuples::tagged_tuple_from_typelist< get_const_global_cache_tags< Metavariables >> const_global_cache, MutableGlobalCache< Metavariables > *mutable_global_cache) noexcept
Constructor used only by the ActionTesting framework and other non-charm++ tests that don't know abou...
Definition: GlobalCache.hpp:379
Parallel::Tags::FromGlobalCache
Definition: GlobalCache.hpp:595
Parallel::charmxx::RegisterGlobalCacheMutate
Derived class for registering GlobalCache::mutate.
Definition: CharmRegistration.hpp:549
tuple
Parallel::mutable_cache_item_is_ready
bool mutable_cache_item_is_ready(GlobalCache< Metavariables > &cache, const Function &function) noexcept
Returns whether the object identified by GlobalCacheTag is ready to be accessed by get.
Definition: GlobalCache.hpp:533
db::SimpleTag
Mark a struct as a simple tag by inheriting from this.
Definition: Tag.hpp:36
Parallel::GlobalCache::set_parallel_components
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: GlobalCache.hpp:402
Parallel::charmxx::RegisterMutableGlobalCacheMutate
Derived class for registering MutableGlobalCache::mutate.
Definition: CharmRegistration.hpp:507
Parallel::MutableGlobalCache
Definition: GlobalCache.hpp:99
ERROR
#define ERROR(m)
prints an error message to the standard error stream and aborts the program.
Definition: Error.hpp:36
Parallel::GlobalCache::mutable_cache_item_is_ready
bool mutable_cache_item_is_ready(const Function &function) noexcept
Returns whether the object referred to by GlobalCacheTag (which must be a mutable cache tag) is ready...
Definition: GlobalCache.hpp:415
Assert.hpp
tuples::TaggedTuple< Tags... >
Parallel::Tags::GlobalCacheImpl
Definition: GlobalCache.hpp:585
Parallel::mutate
void mutate(GlobalCache< Metavariables > &cache, Args &&... args) noexcept
Mutates non-const data in the cache, by calling Function::apply()
Definition: GlobalCache.hpp:553
db::BaseTag
Mark a (usually) empty struct as a base tag by inheriting from this.
Definition: Tag.hpp:69
Parallel::Tags::GlobalCache
Definition: GlobalCache.hpp:582
ASSERT
#define ASSERT(a, m)
Assert that an expression should be true.
Definition: Assert.hpp:51
Parallel::get_const_global_cache_tags
tmpl::remove_duplicates< tmpl::flatten< tmpl::list< typename detail::get_const_global_cache_tags_from_parallel_struct< Metavariables >::type, tmpl::transform< typename Metavariables::component_list, detail::get_const_global_cache_tags_from_parallel_struct< tmpl::_1 > >, tmpl::transform< typename Metavariables::component_list, detail::get_const_global_cache_tags_from_pdal< tmpl::_1 > >> >> get_const_global_cache_tags
Given the metavariables, get a list of the unique tags that will specify the items in the GlobalCache...
Definition: ParallelComponentHelpers.hpp:116
Gsl.hpp
Parallel::GlobalCache::mutate
void mutate(const std::tuple< Args... > &args) noexcept
Mutates the non-const object identified by GlobalCacheTag.
Definition: GlobalCache.hpp:428
Parallel::GlobalCache< typename Component::metavariables >::component_list
typename typename Component::metavariables ::component_list component_list
Typelist of the ParallelComponents stored in the GlobalCache.
Definition: GlobalCache.hpp:273
Requires.hpp
Parallel::get_mutable_global_cache_tags
tmpl::remove_duplicates< tmpl::flatten< tmpl::list< typename detail::get_mutable_global_cache_tags_from_parallel_struct< Metavariables >::type, tmpl::transform< typename Metavariables::component_list, detail::get_mutable_global_cache_tags_from_parallel_struct< tmpl::_1 > >, tmpl::transform< typename Metavariables::component_list, detail::get_mutable_global_cache_tags_from_pdal< tmpl::_1 > >> >> get_mutable_global_cache_tags
Given the metavariables, get a list of the unique tags that will specify the mutable items in the Glo...
Definition: ParallelComponentHelpers.hpp:134
optional
make_not_null
gsl::not_null< T * > make_not_null(T *ptr) noexcept
Construct a not_null from a pointer. Often this will be done as an implicit conversion,...
Definition: Gsl.hpp:880
Parallel::charmxx::RegisterChare
Derived class for registering chares.
Definition: CharmRegistration.hpp:186
Parallel::get
auto get(const GlobalCache< Metavariables > &cache) noexcept -> const GlobalCache_detail::type_for_get< GlobalCacheTag, Metavariables > &
Access data in the cache.
Definition: GlobalCache.hpp:485
Parallel
Contains functions that forward to Charm++ parallel functions.
Definition: ElementReceiveInterpPoints.hpp:13
TMPL.hpp
cpp20::find
constexpr InputIt find(InputIt first, InputIt last, const T &value)
Definition: Algorithm.hpp:136
std::is_base_of
string