Section.hpp
1 // Distributed under the MIT License.
2 // See LICENSE.txt for details.
3 
4 #pragma once
5 
6 #include <charm++.h>
7 #include <optional>
8 #include <pup.h>
9 
10 #include "Parallel/ParallelComponentHelpers.hpp"
11 
12 namespace Parallel {
13 
14 /*!
15  * \brief A subset of chares in a parallel component
16  *
17  * The section is identified at compile time by the parallel component and a
18  * `SectionIdTag`. The `SectionIdTag` describes the quantity that partitions the
19  * chares into one or more sections. For example, the `SectionIdTag` could be
20  * the block ID in the computational domain, so elements are partitioned per
21  * block. Chares can be a member of multiple sections.
22  *
23  * - [Details on sections in the Charm++
24  * documentation](https://charm.readthedocs.io/en/latest/charm++/manual.html#sections-subsets-of-a-chare-array-group)
25  *
26  * Here's an example how to work with sections in an array parallel component:
27  *
28  * \snippet Test_SectionReductions.cpp sections_example
29  *
30  * \warning The Charm++ documentation indicates some [creation order
31  * restrictions](https://charm.readthedocs.io/en/latest/charm++/manual.html#creation-order-restrictions)
32  * for sections that may become relevant if we encounter issues with race
33  * conditions in the future.
34  */
35 template <typename ParallelComponent, typename SectionIdTag>
36 struct Section {
37  private:
38  using chare_type = typename ParallelComponent::chare_type;
39  using charm_type = charm_types_with_parameters<
40  ParallelComponent,
41  typename get_array_index<chare_type>::template f<ParallelComponent>>;
42  using IdType = typename SectionIdTag::type;
43 
44  public:
45  using parallel_component = ParallelComponent;
46  using cproxy_section = typename charm_type::cproxy_section;
47  using section_id_tag = SectionIdTag;
48 
49  Section(IdType id, cproxy_section proxy) noexcept
50  : id_(id), proxy_(std::move(proxy)), cookie_(proxy_.ckGetSectionInfo()) {}
51 
52  Section() = default;
53  Section(Section&& rhs) = default;
54  Section& operator=(Section&& rhs) = default;
55  // The copy constructors currently copy the cookie as well. This seems to work
56  // fine, but if issues come up with updating the cookie we can consider
57  // re-creating it when copying the section to each element.
58  Section(const Section&) = default;
59  Section& operator=(const Section&) = default;
60  ~Section() = default;
61 
62  /// The section ID corresponding to the `SectionIdTag`
63  const IdType& id() const noexcept { return id_; }
64 
65  /// @{
66  /// The Charm++ section proxy
67  const cproxy_section& proxy() const noexcept { return proxy_; }
68  cproxy_section& proxy() noexcept { return proxy_; }
69  /// @}
70 
71  /*!
72  * \brief The Charm++ section cookie that keeps track of reductions
73  *
74  * The section cookie must be stored on each element and updated when
75  * performing reductions. For details on Charm++ sections and section
76  * reductions see:
77  * https://charm.readthedocs.io/en/latest/charm++/manual.html?#sections-subsets-of-a-chare-array-group
78  */
79  /// @{
80  const CkSectionInfo& cookie() const noexcept { return cookie_; }
81  CkSectionInfo& cookie() noexcept { return cookie_; }
82  /// @}
83 
84  // NOLINTNEXTLINE(google-runtime-references)
85  void pup(PUP::er& p) noexcept {
86  p | id_;
87  p | proxy_;
88  p | cookie_;
89  }
90 
91  private:
92  IdType id_{};
93  cproxy_section proxy_{};
94  CkSectionInfo cookie_{};
95 };
96 
97 } // namespace Parallel
Parallel::Section::proxy
const cproxy_section & proxy() const noexcept
The Charm++ section proxy.
Definition: Section.hpp:67
Parallel::Section::proxy
cproxy_section & proxy() noexcept
The Charm++ section proxy.
Definition: Section.hpp:68
Parallel::Section::cookie
CkSectionInfo & cookie() noexcept
The Charm++ section cookie that keeps track of reductions.
Definition: Section.hpp:81
Parallel::Section::id
const IdType & id() const noexcept
The section ID corresponding to the SectionIdTag
Definition: Section.hpp:63
optional
Parallel::Section
A subset of chares in a parallel component.
Definition: Section.hpp:36
Parallel
Functionality for parallelization.
Definition: ElementReceiveInterpPoints.hpp:13
Parallel::Section::cookie
const CkSectionInfo & cookie() const noexcept
The Charm++ section cookie that keeps track of reductions.
Definition: Section.hpp:80