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