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 : } // namespace Parallel