Line data Source code
1 0 : // 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 1 : struct Section {
37 : private:
38 0 : using chare_type = typename ParallelComponent::chare_type;
39 0 : using charm_type = charm_types_with_parameters<
40 : ParallelComponent,
41 : typename get_array_index<chare_type>::template f<ParallelComponent>>;
42 0 : using IdType = typename SectionIdTag::type;
43 :
44 : public:
45 0 : using parallel_component = ParallelComponent;
46 0 : using cproxy_section = typename charm_type::cproxy_section;
47 0 : using section_id_tag = SectionIdTag;
48 :
49 0 : Section(IdType id, cproxy_section proxy)
50 : : id_(id), proxy_(std::move(proxy)), cookie_(proxy_.ckGetSectionInfo()) {}
51 :
52 0 : Section() = default;
53 0 : Section(Section&& rhs) = default;
54 0 : 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 0 : Section(const Section&) = default;
59 0 : Section& operator=(const Section&) = default;
60 0 : ~Section() = default;
61 :
62 : /// The section ID corresponding to the `SectionIdTag`
63 1 : const IdType& id() const { return id_; }
64 :
65 : /// @{
66 : /// The Charm++ section proxy
67 1 : const cproxy_section& proxy() const { return proxy_; }
68 1 : cproxy_section& proxy() { 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 1 : const CkSectionInfo& cookie() const { return cookie_; }
81 1 : CkSectionInfo& cookie() { return cookie_; }
82 : /// @}
83 :
84 : // NOLINTNEXTLINE(google-runtime-references)
85 0 : void pup(PUP::er& p) {
86 : p | id_;
87 : p | proxy_;
88 : p | cookie_;
89 : }
90 :
91 : private:
92 0 : IdType id_{};
93 0 : cproxy_section proxy_{};
94 0 : CkSectionInfo cookie_{};
95 : };
96 :
97 : template <typename ParallelComponent, typename SectionIdTag>
98 0 : bool operator==(const Section<ParallelComponent, SectionIdTag>& a,
99 : const Section<ParallelComponent, SectionIdTag>& b) {
100 : return a.id() == b.id();
101 : }
102 : } // namespace Parallel
|