DDC 0.1.0
Loading...
Searching...
No Matches
chunk_common.hpp
1// Copyright (C) The DDC development team, see COPYRIGHT.md file
2//
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
7#include <array>
8#include <cassert>
9#include <cstddef>
10#include <type_traits>
11#include <utility>
12
13#include <Kokkos_Core.hpp>
14
15#include "ddc/chunk_traits.hpp"
16#include "ddc/detail/macros.hpp"
17#include "ddc/discrete_domain.hpp"
18
19namespace ddc {
20
21/** Access the domain (or subdomain) of a view
22 * @param[in] chunk the view whose domain to access
23 * @return the domain of view in the queried dimensions
24 */
25template <class... QueryDDims, class ChunkType>
26KOKKOS_FUNCTION auto get_domain(ChunkType const& chunk) noexcept
27{
28 static_assert(is_chunk_v<ChunkType>, "Not a chunk span type");
29 return chunk.template domain<QueryDDims...>();
30}
31
32template <class ElementType, class SupportType, class LayoutStridedPolicy>
33class ChunkCommon;
34
35template <class ElementType, class... DDims, class LayoutStridedPolicy>
36class ChunkCommon<ElementType, DiscreteDomain<DDims...>, LayoutStridedPolicy>
37{
38protected:
39 /// the raw mdspan underlying this, with the same indexing (0 might no be dereferenceable)
40 using internal_mdspan_type = Kokkos::mdspan<
41 ElementType,
42 Kokkos::dextents<std::size_t, sizeof...(DDims)>,
43 Kokkos::layout_stride>;
44
45public:
46 using discrete_domain_type = DiscreteDomain<DDims...>;
47
48 using mdomain_type [[deprecated("Use `discrete_domain_type` instead")]]
49 = DiscreteDomain<DDims...>;
50
51 /// The dereferenceable part of the co-domain but with a different domain, starting at 0
52 using allocation_mdspan_type = Kokkos::mdspan<
53 ElementType,
54 Kokkos::dextents<std::size_t, sizeof...(DDims)>,
55 LayoutStridedPolicy>;
56
57 using const_allocation_mdspan_type = Kokkos::mdspan<
58 const ElementType,
59 Kokkos::dextents<std::size_t, sizeof...(DDims)>,
60 LayoutStridedPolicy>;
61
62 using discrete_element_type = typename discrete_domain_type::discrete_element_type;
63
64 using extents_type = typename allocation_mdspan_type::extents_type;
65
66 using layout_type = typename allocation_mdspan_type::layout_type;
67
68 using accessor_type = typename allocation_mdspan_type::accessor_type;
69
70 using mapping_type = typename allocation_mdspan_type::mapping_type;
71
72 using element_type = typename allocation_mdspan_type::element_type;
73
74 using value_type = typename allocation_mdspan_type::value_type;
75
76 using size_type = typename allocation_mdspan_type::size_type;
77
78 using data_handle_type = typename allocation_mdspan_type::data_handle_type;
79
80 using reference = typename allocation_mdspan_type::reference;
81
82 // ChunkCommon, ChunkSpan and Chunk need to access to m_internal_mdspan and m_domain of other template versions
83 template <class, class, class>
84 friend class ChunkCommon;
85
86 template <class, class, class, class>
87 friend class ChunkSpan;
88
89 template <class, class, class>
90 friend class Chunk;
91
92 static_assert(mapping_type::is_always_strided());
93
94protected:
95 /// The raw view of the data
96 internal_mdspan_type m_internal_mdspan;
97
98 /// The mesh on which this chunk is defined
99 discrete_domain_type m_domain;
100
101public:
102 static KOKKOS_FUNCTION constexpr int rank() noexcept
103 {
104 return extents_type::rank();
105 }
106
107 static KOKKOS_FUNCTION constexpr int rank_dynamic() noexcept
108 {
109 return extents_type::rank_dynamic();
110 }
111
112 static KOKKOS_FUNCTION constexpr size_type static_extent(std::size_t r) noexcept
113 {
114 return extents_type::static_extent(r);
115 }
116
117 static KOKKOS_FUNCTION constexpr bool is_always_unique() noexcept
118 {
119 return mapping_type::is_always_unique();
120 }
121
122 static KOKKOS_FUNCTION constexpr bool is_always_exhaustive() noexcept
123 {
124 return mapping_type::is_always_exhaustive();
125 }
126
127 static KOKKOS_FUNCTION constexpr bool is_always_strided() noexcept
128 {
129 return mapping_type::is_always_strided();
130 }
131
132private:
133 template <class Mapping = mapping_type>
134 static KOKKOS_FUNCTION constexpr std::
135 enable_if_t<std::is_constructible_v<Mapping, extents_type>, internal_mdspan_type>
136 make_internal_mdspan(ElementType* ptr, discrete_domain_type const& domain)
137 {
138 if (domain.empty()) {
139 return internal_mdspan_type(ptr, Kokkos::layout_stride::mapping<extents_type>());
140 }
141 extents_type const extents_r(::ddc::extents<DDims>(domain).value()...);
142 mapping_type const mapping_r(extents_r);
143
144 extents_type const extents_s((front<DDims>(domain) + ddc::extents<DDims>(domain)).uid()...);
145 std::array<std::size_t, sizeof...(DDims)> const strides_s {
146 mapping_r.stride(type_seq_rank_v<DDims, detail::TypeSeq<DDims...>>)...};
147 Kokkos::layout_stride::mapping<extents_type> const mapping_s(extents_s, strides_s);
148 return internal_mdspan_type(ptr - mapping_s(front<DDims>(domain).uid()...), mapping_s);
149 }
150
151public:
152 KOKKOS_FUNCTION constexpr accessor_type accessor() const
153 {
154 return m_internal_mdspan.accessor();
155 }
156
157 KOKKOS_FUNCTION constexpr DiscreteVector<DDims...> extents() const noexcept
158 {
159 return m_domain.extents();
160 }
161
162 template <class QueryDDim>
163 KOKKOS_FUNCTION constexpr size_type extent() const noexcept
164 {
165 return m_domain.template extent<QueryDDim>();
166 }
167
168 KOKKOS_FUNCTION constexpr size_type size() const noexcept
169 {
170 return allocation_mdspan().size();
171 }
172
173 KOKKOS_FUNCTION constexpr mapping_type mapping() const noexcept
174 {
175 return allocation_mdspan().mapping();
176 }
177
178 KOKKOS_FUNCTION constexpr bool is_unique() const noexcept
179 {
180 return allocation_mdspan().is_unique();
181 }
182
183 KOKKOS_FUNCTION constexpr bool is_exhaustive() const noexcept
184 {
185 return allocation_mdspan().is_exhaustive();
186 }
187
188 KOKKOS_FUNCTION constexpr bool is_strided() const noexcept
189 {
190 return allocation_mdspan().is_strided();
191 }
192
193 template <class QueryDDim>
194 KOKKOS_FUNCTION constexpr size_type stride() const
195 {
196 return m_internal_mdspan.stride(type_seq_rank_v<QueryDDim, detail::TypeSeq<DDims...>>);
197 }
198
199 /** Provide access to the domain on which this chunk is defined
200 * @return the domain on which this chunk is defined
201 */
202 KOKKOS_FUNCTION constexpr discrete_domain_type domain() const noexcept
203 {
204 return m_domain;
205 }
206
207 /** Provide access to the domain on which this chunk is defined
208 * @return the domain on which this chunk is defined
209 */
210 template <class... QueryDDims>
211 KOKKOS_FUNCTION constexpr DiscreteDomain<QueryDDims...> domain() const noexcept
212 {
213 return select<QueryDDims...>(domain());
214 }
215
216protected:
217 /// Empty ChunkCommon
218 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkCommon() = default;
219
220 /** Constructs a new ChunkCommon from scratch
221 * @param internal_mdspan
222 * @param domain
223 */
225 internal_mdspan_type internal_mdspan,
226 discrete_domain_type const& domain) noexcept
227 : m_internal_mdspan(std::move(internal_mdspan))
228 , m_domain(domain)
229 {
230 }
231
232 /** Constructs a new ChunkCommon from scratch
233 * @param ptr the allocation pointer to the data
234 * @param domain the domain that sustains the view
235 */
236 template <
237 class Mapping = mapping_type,
238 std::enable_if_t<std::is_constructible_v<Mapping, extents_type>, int> = 0>
239 KOKKOS_FUNCTION constexpr ChunkCommon(ElementType* ptr, discrete_domain_type const& domain)
240 : m_internal_mdspan(make_internal_mdspan(ptr, domain))
241 , m_domain(domain)
242 {
243 // Handle the case where an allocation of size 0 returns a nullptr.
244 assert(domain.empty() || ((ptr != nullptr) && !domain.empty()));
245 }
246
247 /** Constructs a new ChunkCommon by copy, yields a new view to the same data
248 * @param other the ChunkCommon to copy
249 */
250 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkCommon(ChunkCommon const& other) = default;
251
252 /** Constructs a new ChunkCommon by move
253 * @param other the ChunkCommon to move
254 */
255 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkCommon(ChunkCommon&& other) = default;
256
258
259 /** Copy-assigns a new value to this ChunkCommon, yields a new view to the same data
260 * @param other the ChunkCommon to copy
261 * @return *this
262 */
263 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkCommon& operator=(ChunkCommon const& other) = default;
264
265 /** Move-assigns a new value to this ChunkCommon
266 * @param other the ChunkCommon to move
267 * @return *this
268 */
269 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkCommon& operator=(ChunkCommon&& other) = default;
270
271 /** Access to the underlying allocation pointer
272 * @return allocation pointer
273 */
274 KOKKOS_FUNCTION constexpr ElementType* data_handle() const
275 {
276 ElementType* ptr = m_internal_mdspan.data_handle();
277 if (!m_domain.empty()) {
278 ptr += m_internal_mdspan.mapping()(front<DDims>(m_domain).uid()...);
279 }
280 return ptr;
281 }
282
283 /** Provide a modifiable view of the data
284 * @return a modifiable view of the data
285 */
286 KOKKOS_FUNCTION constexpr internal_mdspan_type internal_mdspan() const
287 {
288 return m_internal_mdspan;
289 }
290
291 /** Provide a modifiable view of the data
292 * @return a modifiable view of the data
293 */
294 KOKKOS_FUNCTION constexpr allocation_mdspan_type allocation_mdspan() const
295 {
296 DDC_IF_NVCC_THEN_PUSH_AND_SUPPRESS(implicit_return_from_non_void_function)
297 extents_type const extents_s(::ddc::extents<DDims>(m_domain).value()...);
298 if constexpr (std::is_same_v<LayoutStridedPolicy, Kokkos::layout_stride>) {
299 mapping_type const map(extents_s, m_internal_mdspan.mapping().strides());
300 return allocation_mdspan_type(data_handle(), map);
301 } else {
302 mapping_type const map(extents_s);
303 return allocation_mdspan_type(data_handle(), map);
304 }
305 DDC_IF_NVCC_THEN_POP
306 }
307};
308
309} // namespace ddc
KOKKOS_FUNCTION constexpr mapping_type mapping() const noexcept
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkCommon & operator=(ChunkCommon const &other)=default
Copy-assigns a new value to this ChunkCommon, yields a new view to the same data.
KOKKOS_FUNCTION constexpr discrete_domain_type domain() const noexcept
Provide access to the domain on which this chunk is defined.
discrete_domain_type m_domain
The mesh on which this chunk is defined.
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkCommon(ChunkCommon const &other)=default
Constructs a new ChunkCommon by copy, yields a new view to the same data.
KOKKOS_FUNCTION constexpr DiscreteVector< DDims... > extents() const noexcept
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkCommon()=default
Empty ChunkCommon.
KOKKOS_FUNCTION constexpr ElementType * data_handle() const
Access to the underlying allocation pointer.
KOKKOS_FUNCTION constexpr allocation_mdspan_type allocation_mdspan() const
Provide a modifiable view of the data.
KOKKOS_FUNCTION constexpr ChunkCommon(internal_mdspan_type internal_mdspan, discrete_domain_type const &domain) noexcept
Constructs a new ChunkCommon from scratch.
KOKKOS_FUNCTION constexpr internal_mdspan_type internal_mdspan() const
Provide a modifiable view of the data.
static KOKKOS_FUNCTION constexpr size_type static_extent(std::size_t r) noexcept
KOKKOS_FUNCTION constexpr ChunkCommon(ElementType *ptr, discrete_domain_type const &domain)
Constructs a new ChunkCommon from scratch.
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkCommon & operator=(ChunkCommon &&other)=default
Move-assigns a new value to this ChunkCommon.
KOKKOS_FUNCTION constexpr DiscreteDomain< QueryDDims... > domain() const noexcept
Provide access to the domain on which this chunk is defined.
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkCommon(ChunkCommon &&other)=default
Constructs a new ChunkCommon by move.
friend class DiscreteDomain
KOKKOS_FUNCTION constexpr bool operator!=(DiscreteVector< OTags... > const &rhs) const noexcept
The top-level namespace of DDC.
KOKKOS_FUNCTION auto get_domain(ChunkType const &chunk) noexcept
Access the domain (or subdomain) of a view.