DDC 0.14.0
Loading...
Searching...
No Matches
chunk.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 <cassert>
8#include <string>
9#include <utility>
10
11#include <Kokkos_Core.hpp>
12
13#include "detail/kokkos.hpp"
14
15#include "chunk_common.hpp"
16#include "chunk_span.hpp"
21
22namespace ddc {
23
24template <class ElementType, class, class Allocator = HostAllocator<ElementType>>
25class Chunk;
26
27template <class ElementType, class SupportType, class Allocator>
28inline constexpr bool enable_chunk<Chunk<ElementType, SupportType, Allocator>> = true;
29
30template <class ElementType, class SupportType, class Allocator>
31class Chunk : public ChunkCommon<ElementType, SupportType, Kokkos::layout_right>
32{
33protected:
34 using base_type = ChunkCommon<ElementType, SupportType, Kokkos::layout_right>;
35
36public:
37 /// type of a span of this full chunk
38 using span_type = ChunkSpan<
39 ElementType,
40 SupportType,
41 Kokkos::layout_right,
42 typename Allocator::memory_space>;
43
44 /// type of a view of this full chunk
45 using view_type = ChunkSpan<
46 ElementType const,
47 SupportType,
48 Kokkos::layout_right,
49 typename Allocator::memory_space>;
50
51 /// The dereferenceable part of the co-domain but with indexing starting at 0
52 using allocation_mdspan_type = base_type::allocation_mdspan_type;
53
54 using const_allocation_mdspan_type = base_type::const_allocation_mdspan_type;
55
56 using discrete_domain_type = base_type::discrete_domain_type;
57
58 using memory_space = Allocator::memory_space;
59
60 using discrete_element_type = base_type::discrete_element_type;
61
62 using discrete_vector_type = base_type::discrete_vector_type;
63
64 using extents_type = base_type::extents_type;
65
66 using layout_type = base_type::layout_type;
67
68 using mapping_type = base_type::mapping_type;
69
70 using element_type = base_type::element_type;
71
72 using value_type = base_type::value_type;
73
74 using size_type = base_type::size_type;
75
76 using data_handle_type = base_type::data_handle_type;
77
78 using reference = base_type::reference;
79
80 template <class, class, class>
81 friend class Chunk;
82
83private:
84 Allocator m_allocator;
85
86 std::string m_label;
87
88public:
89 /// Empty Chunk
90 Chunk() = default;
91
92 /// Construct a labeled Chunk on a domain with uninitialized values
93 explicit Chunk(
94 std::string const& label,
95 SupportType const& domain,
96 Allocator allocator = Allocator())
97 : base_type(allocator.allocate(label, domain.size()), domain)
98 , m_allocator(std::move(allocator))
99 , m_label(label)
100 {
101 }
102
103 /// Construct a Chunk on a domain with uninitialized values
104 explicit Chunk(SupportType const& domain, Allocator allocator = Allocator())
105 : Chunk("no-label", domain, std::move(allocator))
106 {
107 }
108
109 /// Deleted: use deepcopy instead
110 Chunk(Chunk const& other) = delete;
111
112 /** Constructs a new Chunk by move
113 * @param other the Chunk to move
114 */
115 Chunk(Chunk&& other) noexcept
116 : base_type(std::move(static_cast<base_type&>(other)))
117 , m_allocator(std::move(other.m_allocator))
118 , m_label(std::move(other.m_label))
119 {
120 other.m_allocation_mdspan
121 = allocation_mdspan_type(nullptr, other.m_allocation_mdspan.mapping());
122 }
123
124 ~Chunk() noexcept
125 {
126 if (this->m_allocation_mdspan.data_handle()) {
127 m_allocator.deallocate(this->data_handle(), this->size());
128 }
129 }
130
131 /// Deleted: use deepcopy instead
132 Chunk& operator=(Chunk const& other) = delete;
133
134 /** Move-assigns a new value to this field
135 * @param other the Chunk to move
136 * @return *this
137 */
138 Chunk& operator=(Chunk&& other) noexcept
139 {
140 if (this->data_handle()) {
141 m_allocator.deallocate(this->data_handle(), this->size());
142 }
143 static_cast<base_type&>(*this) = std::move(static_cast<base_type&>(other));
144 m_allocator = std::move(other.m_allocator);
145 m_label = std::move(other.m_label);
146 other.m_allocation_mdspan
147 = allocation_mdspan_type(nullptr, other.m_allocation_mdspan.mapping());
148
149 return *this;
150 }
151
152 /// Slice out some dimensions
153 template <class... QueryDDims>
154 auto operator[](DiscreteVector<QueryDDims...> const& slice_spec) const
155 {
156 return view_type(*this)[slice_spec];
157 }
158
159 /// Slice out some dimensions
160 template <class... QueryDDims>
161 auto operator[](DiscreteVector<QueryDDims...> const& slice_spec)
162 {
163 return span_view()[slice_spec];
164 }
165
166 /// Slice out some dimensions
167 template <class... QueryDDims>
168 auto operator[](DiscreteElement<QueryDDims...> const& slice_spec) const
169 {
170 return view_type(*this)[slice_spec];
171 }
172
173 /// Slice out some dimensions
174 template <class... QueryDDims>
175 auto operator[](DiscreteElement<QueryDDims...> const& slice_spec)
176 {
177 return span_view()[slice_spec];
178 }
179
180 /// Slice out some dimensions
181 template <class... QueryDDims>
182 auto operator[](DiscreteDomain<QueryDDims...> const& odomain) const
183 requires(is_discrete_domain_v<SupportType>)
184 {
185 return span_view()[odomain];
186 }
187
188 /// Slice out some dimensions
189 template <class... QueryDDims>
190 auto operator[](DiscreteDomain<QueryDDims...> const& odomain)
191 requires(is_discrete_domain_v<SupportType>)
192 {
193 return span_view()[odomain];
194 }
195
196 /** Element access using a list of DiscreteElement
197 * @param delems discrete coordinates
198 * @return const-reference to this element
199 */
200 template <concepts::discrete_element... DElems>
201 element_type const& operator()(DElems const&... delems) const noexcept
202 {
203 static_assert(
204 SupportType::rank() == (0 + ... + DElems::size()),
205 "Invalid number of dimensions");
206 assert(this->m_domain.contains(delems...));
207 return DDC_MDSPAN_ACCESS_OP(
208 this->m_allocation_mdspan,
209 detail::array(this->m_domain.distance_from_front(delems...)));
210 }
211
212 /** Element access using a list of DiscreteVector
213 * @param dvects discrete vectors
214 * @return reference to this element
215 */
216 template <concepts::discrete_vector... DVects>
217 element_type const& operator()(DVects const&... dvects) const noexcept
218 requires(sizeof...(DVects) != 0)
219 {
220 static_assert(
221 SupportType::rank() == (0 + ... + DVects::size()),
222 "Invalid number of dimensions");
223 return DDC_MDSPAN_ACCESS_OP(
224 this->m_allocation_mdspan,
225 detail::array(discrete_vector_type(dvects...)));
226 }
227
228 /** Element access using a list of DiscreteElement
229 * @param delems discrete coordinates
230 * @return reference to this element
231 */
232 template <concepts::discrete_element... DElems>
233 element_type& operator()(DElems const&... delems) noexcept
234 {
235 static_assert(
236 SupportType::rank() == (0 + ... + DElems::size()),
237 "Invalid number of dimensions");
238 assert(this->m_domain.contains(delems...));
239 return DDC_MDSPAN_ACCESS_OP(
240 this->m_allocation_mdspan,
241 detail::array(this->m_domain.distance_from_front(delems...)));
242 }
243
244 /** Element access using a list of DiscreteVector
245 * @param dvects discrete vectors
246 * @return reference to this element
247 */
248 template <concepts::discrete_vector... DVects>
249 element_type& operator()(DVects const&... dvects) noexcept
250 requires(sizeof...(DVects) != 0)
251 {
252 static_assert(
253 SupportType::rank() == (0 + ... + DVects::size()),
254 "Invalid number of dimensions");
255 return DDC_MDSPAN_ACCESS_OP(
256 this->m_allocation_mdspan,
257 detail::array(discrete_vector_type(dvects...)));
258 }
259
260 /** Returns the label of the Chunk
261 * @return c-string
262 */
263 char const* label() const
264 {
265 return m_label.c_str();
266 }
267
268 /** Access to the underlying allocation pointer
269 * @return read-only allocation pointer
270 */
271 ElementType const* data_handle() const
272 {
273 return base_type::data_handle();
274 }
275
276 /** Access to the underlying allocation pointer
277 * @return allocation pointer
278 */
279 ElementType* data_handle()
280 {
281 return base_type::data_handle();
282 }
283
284 /** Provide a mdspan on the memory allocation
285 * @return read-only allocation mdspan
286 */
287 const_allocation_mdspan_type allocation_mdspan() const
288 {
289 return base_type::allocation_mdspan();
290 }
291
292 /** Provide a mdspan on the memory allocation
293 * @return allocation mdspan
294 */
295 allocation_mdspan_type allocation_mdspan()
296 {
297 return base_type::allocation_mdspan();
298 }
299
300 /** Provide an unmanaged `Kokkos::View` on the memory allocation
301 * @return allocation `Kokkos::View`
302 */
304 {
305 auto s = this->allocation_mdspan();
306 auto kokkos_layout = detail::build_kokkos_layout(
307 s.extents(),
308 s.mapping(),
309 std::make_index_sequence<SupportType::rank()> {});
310 return Kokkos::View<
311 detail::mdspan_to_kokkos_element_t<ElementType, SupportType::rank()>,
312 decltype(kokkos_layout),
313 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
314 }
315
316 /** Provide an unmanaged `Kokkos::View` on the memory allocation
317 * @return read-only allocation `Kokkos::View`
318 */
319 auto allocation_kokkos_view() const
320 {
321 auto s = this->allocation_mdspan();
322 auto kokkos_layout = detail::build_kokkos_layout(
323 s.extents(),
324 s.mapping(),
325 std::make_index_sequence<SupportType::rank()> {});
326 return Kokkos::View<
327 detail::mdspan_to_kokkos_element_t<ElementType const, SupportType::rank()>,
328 decltype(kokkos_layout),
329 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
330 }
331
332 view_type span_cview() const
333 {
334 return view_type(*this);
335 }
336
337 view_type span_view() const
338 {
339 return view_type(*this);
340 }
341
342 span_type span_view()
343 {
344 return span_type(*this);
345 }
346};
347
348template <class SupportType, class Allocator>
349Chunk(std::string const&, SupportType const&, Allocator)
350 -> Chunk<typename Allocator::value_type, SupportType, Allocator>;
351
352template <class SupportType, class Allocator>
353Chunk(SupportType const&, Allocator)
354 -> Chunk<typename Allocator::value_type, SupportType, Allocator>;
355
356} // namespace ddc
friend class ChunkSpan
auto operator[](DiscreteElement< QueryDDims... > const &slice_spec) const
Slice out some dimensions.
Definition chunk.hpp:168
auto operator[](DiscreteVector< QueryDDims... > const &slice_spec) const
Slice out some dimensions.
Definition chunk.hpp:154
char const * label() const
Returns the label of the Chunk.
Definition chunk.hpp:263
const_allocation_mdspan_type allocation_mdspan() const
Provide a mdspan on the memory allocation.
Definition chunk.hpp:287
ElementType const * data_handle() const
Access to the underlying allocation pointer.
Definition chunk.hpp:271
auto allocation_kokkos_view()
Provide an unmanaged Kokkos::View on the memory allocation.
Definition chunk.hpp:303
auto operator[](DiscreteDomain< QueryDDims... > const &odomain)
Slice out some dimensions.
Definition chunk.hpp:190
auto allocation_kokkos_view() const
Provide an unmanaged Kokkos::View on the memory allocation.
Definition chunk.hpp:319
Chunk(SupportType const &domain, Allocator allocator=Allocator())
Construct a Chunk on a domain with uninitialized values.
Definition chunk.hpp:104
Chunk & operator=(Chunk const &other)=delete
Deleted: use deepcopy instead.
allocation_mdspan_type allocation_mdspan()
Provide a mdspan on the memory allocation.
Definition chunk.hpp:295
ElementType * data_handle()
Access to the underlying allocation pointer.
Definition chunk.hpp:279
view_type span_cview() const
Definition chunk.hpp:332
Chunk(Chunk const &other)=delete
Deleted: use deepcopy instead.
~Chunk() noexcept
Definition chunk.hpp:124
Chunk(std::string const &label, SupportType const &domain, Allocator allocator=Allocator())
Construct a labeled Chunk on a domain with uninitialized values.
Definition chunk.hpp:93
element_type & operator()(DElems const &... delems) noexcept
Element access using a list of DiscreteElement.
Definition chunk.hpp:233
Chunk()=default
Empty Chunk.
Chunk & operator=(Chunk &&other) noexcept
Move-assigns a new value to this field.
Definition chunk.hpp:138
Chunk(Chunk &&other) noexcept
Constructs a new Chunk by move.
Definition chunk.hpp:115
friend class Chunk
Definition chunk.hpp:81
span_type span_view()
Definition chunk.hpp:342
view_type span_view() const
Definition chunk.hpp:337
auto operator[](DiscreteDomain< QueryDDims... > const &odomain) const
Slice out some dimensions.
Definition chunk.hpp:182
element_type const & operator()(DElems const &... delems) const noexcept
Element access using a list of DiscreteElement.
Definition chunk.hpp:201
auto operator[](DiscreteVector< QueryDDims... > const &slice_spec)
Slice out some dimensions.
Definition chunk.hpp:161
auto operator[](DiscreteElement< QueryDDims... > const &slice_spec)
Slice out some dimensions.
Definition chunk.hpp:175
friend class DiscreteDomain
KOKKOS_FUNCTION constexpr bool operator!=(DiscreteVector< OTags... > const &rhs) const noexcept
The top-level namespace of DDC.
constexpr bool enable_chunk< Chunk< ElementType, SupportType, Allocator > >
Definition chunk.hpp:28
Chunk(SupportType const &, Allocator) -> Chunk< typename Allocator::value_type, SupportType, Allocator >
Chunk(std::string const &, SupportType const &, Allocator) -> Chunk< typename Allocator::value_type, SupportType, Allocator >