DDC 0.12.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 = typename base_type::allocation_mdspan_type;
53
54 using const_allocation_mdspan_type = typename base_type::const_allocation_mdspan_type;
55
56 using discrete_domain_type = typename base_type::discrete_domain_type;
57
58 using memory_space = typename Allocator::memory_space;
59
60 using discrete_element_type = typename base_type::discrete_element_type;
61
62 using discrete_vector_type = typename base_type::discrete_vector_type;
63
64 using extents_type = typename base_type::extents_type;
65
66 using layout_type = typename base_type::layout_type;
67
68 using mapping_type = typename base_type::mapping_type;
69
70 using element_type = typename base_type::element_type;
71
72 using value_type = typename base_type::value_type;
73
74 using size_type = typename base_type::size_type;
75
76 using data_handle_type = typename base_type::data_handle_type;
77
78 using reference = typename 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[](DiscreteElement<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[](DiscreteElement<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[](DiscreteDomain<QueryDDims...> const& odomain) const
169 requires(is_discrete_domain_v<SupportType>)
170 {
171 return span_view()[odomain];
172 }
173
174 /// Slice out some dimensions
175 template <class... QueryDDims>
176 auto operator[](DiscreteDomain<QueryDDims...> const& odomain)
177 requires(is_discrete_domain_v<SupportType>)
178 {
179 return span_view()[odomain];
180 }
181
182 /** Element access using a list of DiscreteElement
183 * @param delems discrete coordinates
184 * @return const-reference to this element
185 */
186 template <concepts::discrete_element... DElems>
187 element_type const& operator()(DElems const&... delems) const noexcept
188 {
189 static_assert(
190 SupportType::rank() == (0 + ... + DElems::size()),
191 "Invalid number of dimensions");
192 assert(this->m_domain.contains(delems...));
193 return DDC_MDSPAN_ACCESS_OP(
194 this->m_allocation_mdspan,
195 detail::array(this->m_domain.distance_from_front(delems...)));
196 }
197
198 /** Element access using a list of DiscreteVector
199 * @param dvects discrete vectors
200 * @return reference to this element
201 */
202 template <concepts::discrete_vector... DVects>
203 element_type const& operator()(DVects const&... dvects) const noexcept
204 requires(sizeof...(DVects) != 0)
205 {
206 static_assert(
207 SupportType::rank() == (0 + ... + DVects::size()),
208 "Invalid number of dimensions");
209 return DDC_MDSPAN_ACCESS_OP(
210 this->m_allocation_mdspan,
211 detail::array(discrete_vector_type(dvects...)));
212 }
213
214 /** Element access using a list of DiscreteElement
215 * @param delems discrete coordinates
216 * @return reference to this element
217 */
218 template <concepts::discrete_element... DElems>
219 element_type& operator()(DElems const&... delems) noexcept
220 {
221 static_assert(
222 SupportType::rank() == (0 + ... + DElems::size()),
223 "Invalid number of dimensions");
224 assert(this->m_domain.contains(delems...));
225 return DDC_MDSPAN_ACCESS_OP(
226 this->m_allocation_mdspan,
227 detail::array(this->m_domain.distance_from_front(delems...)));
228 }
229
230 /** Element access using a list of DiscreteVector
231 * @param dvects discrete vectors
232 * @return reference to this element
233 */
234 template <concepts::discrete_vector... DVects>
235 element_type& operator()(DVects const&... dvects) noexcept
236 requires(sizeof...(DVects) != 0)
237 {
238 static_assert(
239 SupportType::rank() == (0 + ... + DVects::size()),
240 "Invalid number of dimensions");
241 return DDC_MDSPAN_ACCESS_OP(
242 this->m_allocation_mdspan,
243 detail::array(discrete_vector_type(dvects...)));
244 }
245
246 /** Returns the label of the Chunk
247 * @return c-string
248 */
249 char const* label() const
250 {
251 return m_label.c_str();
252 }
253
254 /** Access to the underlying allocation pointer
255 * @return read-only allocation pointer
256 */
257 ElementType const* data_handle() const
258 {
259 return base_type::data_handle();
260 }
261
262 /** Access to the underlying allocation pointer
263 * @return allocation pointer
264 */
265 ElementType* data_handle()
266 {
267 return base_type::data_handle();
268 }
269
270 /** Provide a mdspan on the memory allocation
271 * @return read-only allocation mdspan
272 */
273 const_allocation_mdspan_type allocation_mdspan() const
274 {
275 return base_type::allocation_mdspan();
276 }
277
278 /** Provide a mdspan on the memory allocation
279 * @return allocation mdspan
280 */
281 allocation_mdspan_type allocation_mdspan()
282 {
283 return base_type::allocation_mdspan();
284 }
285
286 /** Provide an unmanaged `Kokkos::View` on the memory allocation
287 * @return allocation `Kokkos::View`
288 */
290 {
291 auto s = this->allocation_mdspan();
292 auto kokkos_layout = detail::build_kokkos_layout(
293 s.extents(),
294 s.mapping(),
295 std::make_index_sequence<SupportType::rank()> {});
296 return Kokkos::View<
297 detail::mdspan_to_kokkos_element_t<ElementType, SupportType::rank()>,
298 decltype(kokkos_layout),
299 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
300 }
301
302 /** Provide an unmanaged `Kokkos::View` on the memory allocation
303 * @return read-only allocation `Kokkos::View`
304 */
305 auto allocation_kokkos_view() const
306 {
307 auto s = this->allocation_mdspan();
308 auto kokkos_layout = detail::build_kokkos_layout(
309 s.extents(),
310 s.mapping(),
311 std::make_index_sequence<SupportType::rank()> {});
312 return Kokkos::View<
313 detail::mdspan_to_kokkos_element_t<ElementType const, SupportType::rank()>,
314 decltype(kokkos_layout),
315 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
316 }
317
318 view_type span_cview() const
319 {
320 return view_type(*this);
321 }
322
323 view_type span_view() const
324 {
325 return view_type(*this);
326 }
327
328 span_type span_view()
329 {
330 return span_type(*this);
331 }
332};
333
334template <class SupportType, class Allocator>
335Chunk(std::string const&, SupportType const&, Allocator)
336 -> Chunk<typename Allocator::value_type, SupportType, Allocator>;
337
338template <class SupportType, class Allocator>
339Chunk(SupportType const&, Allocator)
340 -> Chunk<typename Allocator::value_type, SupportType, Allocator>;
341
342} // namespace ddc
friend class ChunkSpan
auto operator[](DiscreteElement< 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:249
const_allocation_mdspan_type allocation_mdspan() const
Provide a mdspan on the memory allocation.
Definition chunk.hpp:273
ElementType const * data_handle() const
Access to the underlying allocation pointer.
Definition chunk.hpp:257
auto allocation_kokkos_view()
Provide an unmanaged Kokkos::View on the memory allocation.
Definition chunk.hpp:289
auto operator[](DiscreteDomain< QueryDDims... > const &odomain)
Slice out some dimensions.
Definition chunk.hpp:176
auto allocation_kokkos_view() const
Provide an unmanaged Kokkos::View on the memory allocation.
Definition chunk.hpp:305
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:281
ElementType * data_handle()
Access to the underlying allocation pointer.
Definition chunk.hpp:265
view_type span_cview() const
Definition chunk.hpp:318
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:219
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:328
view_type span_view() const
Definition chunk.hpp:323
auto operator[](DiscreteDomain< QueryDDims... > const &odomain) const
Slice out some dimensions.
Definition chunk.hpp:168
element_type const & operator()(DElems const &... delems) const noexcept
Element access using a list of DiscreteElement.
Definition chunk.hpp:187
auto operator[](DiscreteElement< QueryDDims... > const &slice_spec)
Slice out some dimensions.
Definition chunk.hpp:161
friend class DiscreteDomain
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 >