DDC 0.0.0

a discrete domain computation library

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 <string>
8#include <utility>
9
10#include <experimental/mdspan>
11
12#include "ddc/chunk_common.hpp"
13#include "ddc/chunk_span.hpp"
14#include "ddc/chunk_traits.hpp"
15#include "ddc/kokkos_allocator.hpp"
16#include "ddc/parallel_deepcopy.hpp"
17
18namespace ddc {
19
20template <class ElementType, class, class Allocator = HostAllocator<ElementType>>
21class Chunk;
22
23template <class ElementType, class SupportType, class Allocator>
25
26template <class ElementType, class... DDims, class Allocator>
28 : public ChunkCommon<ElementType, DiscreteDomain<DDims...>, std::experimental::layout_right>
29{
30protected:
32 = ChunkCommon<ElementType, DiscreteDomain<DDims...>, std::experimental::layout_right>;
33
35 using internal_mdspan_type = typename base_type::internal_mdspan_type;
36
37public:
39 using span_type = ChunkSpan<
42 std::experimental::layout_right,
43 typename Allocator::memory_space>;
44
46 using view_type = ChunkSpan<
47 ElementType const,
49 std::experimental::layout_right,
50 typename Allocator::memory_space>;
51
53 using allocation_mdspan_type = typename base_type::allocation_mdspan_type;
55 using const_allocation_mdspan_type = typename base_type::const_allocation_mdspan_type;
57 using mdomain_type = typename base_type::mdomain_type;
59 using memory_space = typename Allocator::memory_space;
61 using discrete_element_type = typename base_type::discrete_element_type;
63 using extents_type = typename base_type::extents_type;
65 using layout_type = typename base_type::layout_type;
67 using mapping_type = typename base_type::mapping_type;
69 using element_type = typename base_type::element_type;
71 using value_type = typename base_type::value_type;
73 using size_type = typename base_type::size_type;
75 using data_handle_type = typename base_type::data_handle_type;
77 using reference = typename base_type::reference;
78
79 template <class, class, class>
80 friend class Chunk;
81
82private:
83 Allocator m_allocator;
84
85 std::string m_label;
86
87public:
89 Chunk() = default;
90
92 explicit Chunk(
93 std::string const& label,
94 mdomain_type const& domain,
95 Allocator allocator = Allocator())
96 : base_type(allocator.allocate(label, domain.size()), domain)
97 , m_allocator(std::move(allocator))
98 , m_label(label)
99 {
100 }
101
103 explicit Chunk(mdomain_type const& domain, Allocator allocator = Allocator())
104 : Chunk("no-label", domain, std::move(allocator))
105 {
106 }
107
109 Chunk(Chunk const& other) = delete;
110
114 Chunk(Chunk&& other)
115 : base_type(std::move(static_cast<base_type&>(other)))
116 , m_allocator(std::move(other.m_allocator))
117 , m_label(std::move(other.m_label))
118 {
119 other.m_internal_mdspan = internal_mdspan_type(nullptr, other.m_internal_mdspan.mapping());
120 }
122 ~Chunk()
123 {
124 if (this->m_internal_mdspan.data_handle()) {
125 m_allocator.deallocate(this->data_handle(), this->size());
126 }
127 }
128
130 Chunk& operator=(Chunk const& other) = delete;
131
136 Chunk& operator=(Chunk&& other)
137 {
138 if (this == &other) {
139 return *this;
140 }
141 if (this->m_internal_mdspan.data_handle()) {
142 m_allocator.deallocate(this->data_handle(), this->size());
143 }
144 static_cast<base_type&>(*this) = std::move(static_cast<base_type&>(other));
145 m_allocator = std::move(other.m_allocator);
146 m_label = std::move(other.m_label);
147 other.m_internal_mdspan = internal_mdspan_type(nullptr, other.m_internal_mdspan.mapping());
148
149 return *this;
150 }
151
153 template <class... QueryDDims>
154 auto operator[](DiscreteElement<QueryDDims...> const& slice_spec) const
155 {
156 return view_type(*this)[slice_spec];
157 }
158
160 template <class... QueryDDims>
161 auto operator[](DiscreteElement<QueryDDims...> const& slice_spec)
162 {
163 return span_view()[slice_spec];
164 }
165
167 template <class... QueryDDims>
168 auto operator[](DiscreteDomain<QueryDDims...> const& odomain) const
169 {
170 return span_view()[odomain];
171 }
172
174 template <class... QueryDDims>
175 auto operator[](DiscreteDomain<QueryDDims...> const& odomain)
176 {
177 return span_view()[odomain];
178 }
179
184 template <class... DElems>
185 element_type const& operator()(DElems const&... delems) const noexcept
186 {
187 static_assert(
188 sizeof...(DDims) == (0 + ... + DElems::size()),
189 "Invalid number of dimensions");
190 static_assert((is_discrete_element_v<DElems> && ...), "Expected DiscreteElements");
191 assert(((select<DDims>(take<DDims>(delems...)) >= front<DDims>(this->m_domain)) && ...));
192 assert(((select<DDims>(take<DDims>(delems...)) <= back<DDims>(this->m_domain)) && ...));
193 return this->m_internal_mdspan(uid<DDims>(take<DDims>(delems...))...);
194 }
195
200 template <class... DElems>
201 element_type& operator()(DElems const&... delems) noexcept
202 {
203 static_assert(
204 sizeof...(DDims) == (0 + ... + DElems::size()),
205 "Invalid number of dimensions");
206 static_assert((is_discrete_element_v<DElems> && ...), "Expected DiscreteElements");
207 assert(((select<DDims>(take<DDims>(delems...)) >= front<DDims>(this->m_domain)) && ...));
208 assert(((select<DDims>(take<DDims>(delems...)) <= back<DDims>(this->m_domain)) && ...));
209 return this->m_internal_mdspan(uid<DDims>(take<DDims>(delems...))...);
210 }
211
215 char const* label() const
216 {
217 return m_label.c_str();
218 }
219
223 ElementType const* data_handle() const
224 {
225 return base_type::data_handle();
226 }
227
231 ElementType* data_handle()
232 {
233 return base_type::data_handle();
234 }
235
239 const_allocation_mdspan_type allocation_mdspan() const
240 {
241 return base_type::allocation_mdspan();
242 }
243
247 allocation_mdspan_type allocation_mdspan()
248 {
249 return base_type::allocation_mdspan();
250 }
251
255 auto allocation_kokkos_view()
256 {
257 auto s = this->allocation_mdspan();
258 auto kokkos_layout = detail::build_kokkos_layout(
259 s.extents(),
260 s.mapping(),
261 std::make_index_sequence<sizeof...(DDims)> {});
262 return Kokkos::View<
263 detail::mdspan_to_kokkos_element_t<ElementType, sizeof...(DDims)>,
264 decltype(kokkos_layout),
265 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
266 }
267
271 auto allocation_kokkos_view() const
272 {
273 auto s = this->allocation_mdspan();
274 auto kokkos_layout = detail::build_kokkos_layout(
275 s.extents(),
276 s.mapping(),
277 std::make_index_sequence<sizeof...(DDims)> {});
278 return Kokkos::View<
279 detail::mdspan_to_kokkos_element_t<const ElementType, sizeof...(DDims)>,
280 decltype(kokkos_layout),
281 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
282 }
284 view_type span_cview() const
285 {
286 return view_type(*this);
287 }
289 view_type span_view() const
290 {
291 return view_type(*this);
292 }
294 span_type span_view()
295 {
296 return span_type(*this);
297 }
298};
299
300template <class... DDims, class Allocator>
301Chunk(std::string const&, DiscreteDomain<DDims...> const&, Allocator)
302 -> Chunk<typename Allocator::value_type, DiscreteDomain<DDims...>, Allocator>;
303
304template <class... DDims, class Allocator>
306 -> Chunk<typename Allocator::value_type, DiscreteDomain<DDims...>, Allocator>;
307
308} // namespace ddc
typename base_type::element_type element_type
Definition chunk.hpp:68
typename base_type::mdomain_type mdomain_type
Definition chunk.hpp:56
typename base_type::const_allocation_mdspan_type const_allocation_mdspan_type
Definition chunk.hpp:54
typename base_type::allocation_mdspan_type allocation_mdspan_type
The dereferenceable part of the co-domain but with indexing starting at 0.
Definition chunk.hpp:52
typename base_type::size_type size_type
Definition chunk.hpp:72
typename base_type::data_handle_type data_handle_type
Definition chunk.hpp:74
typename base_type::reference reference
Definition chunk.hpp:76
typename Allocator::memory_space memory_space
Definition chunk.hpp:58
typename base_type::mapping_type mapping_type
Definition chunk.hpp:66
typename base_type::extents_type extents_type
Definition chunk.hpp:62
typename base_type::value_type value_type
Definition chunk.hpp:70
typename base_type::internal_mdspan_type internal_mdspan_type
ND memory view.
Definition chunk.hpp:34
typename base_type::discrete_element_type discrete_element_type
Definition chunk.hpp:60
typename base_type::layout_type layout_type
Definition chunk.hpp:64
Definition discrete_domain.hpp:51
A DiscreteElement identifies an element of the discrete dimension.
Definition discrete_element.hpp:146
The top-level namespace of DDC.
Definition aligned_allocator.hpp:11
constexpr bool enable_chunk
Definition chunk_traits.hpp:16
Chunk(std::string const &, DiscreteDomain< DDims... > const &, Allocator) -> Chunk< typename Allocator::value_type, DiscreteDomain< DDims... >, Allocator >
Definition chunk.hpp:21
Definition chunk_common.hpp:34
Definition chunk_span.hpp:30