DDC 0.0.0

a discrete domain computation library

chunk_span.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 <experimental/mdspan>
14
15#include "ddc/chunk_common.hpp"
16#include "ddc/detail/kokkos.hpp"
17#include "ddc/discrete_domain.hpp"
18#include "ddc/discrete_element.hpp"
19
20namespace ddc {
21
22template <class, class, class>
23class Chunk;
24
25template <
26 class ElementType,
27 class SupportType,
28 class LayoutStridedPolicy = std::experimental::layout_right,
29 class MemorySpace = Kokkos::DefaultHostExecutionSpace::memory_space>
31
32template <class ElementType, class SupportType, class LayoutStridedPolicy, class MemorySpace>
33inline constexpr bool
35
36template <class ElementType, class SupportType, class LayoutStridedPolicy, class MemorySpace>
37inline constexpr bool enable_borrowed_chunk<
39
40template <class ElementType, class... DDims, class LayoutStridedPolicy, class MemorySpace>
42 : public ChunkCommon<ElementType, DiscreteDomain<DDims...>, LayoutStridedPolicy>
43{
44protected:
46
49
50public:
54
56 using view_type = ChunkSpan<
57 ElementType const,
65
75 using layout_type = typename base_type::layout_type;
83 using value_type = typename base_type::value_type;
85 using size_type = typename base_type::size_type;
89 using reference = typename base_type::reference;
90
91 template <class, class, class, class>
92 friend class ChunkSpan;
93
94protected:
95 template <class QueryDDim, class... ODDims>
96 KOKKOS_FUNCTION constexpr auto get_slicer_for(DiscreteElement<ODDims...> const& c) const
97 {
99 if constexpr (in_tags_v<QueryDDim, detail::TypeSeq<ODDims...>>) {
100 return (uid<QueryDDim>(c) - front<QueryDDim>(this->m_domain).uid());
101 } else {
102 return std::experimental::full_extent;
103 }
105 }
106
107 template <class QueryDDim, class... ODDims>
108 KOKKOS_FUNCTION constexpr auto get_slicer_for(DiscreteDomain<ODDims...> const& c) const
109 {
111 if constexpr (in_tags_v<QueryDDim, detail::TypeSeq<ODDims...>>) {
112 return std::pair<std::size_t, std::size_t>(
113 front<QueryDDim>(c) - front<QueryDDim>(this->m_domain),
114 back<QueryDDim>(c) + 1 - front<QueryDDim>(this->m_domain));
115 } else {
116 return std::experimental::full_extent;
117 }
119 }
120
121public:
123 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan() = default;
124
128 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan(ChunkSpan const& other) = default;
129
133 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan(ChunkSpan&& other) = default;
134
138 template <
139 class OElementType,
140 class Allocator,
141 class = std::enable_if_t<std::is_same_v<typename Allocator::memory_space, MemorySpace>>>
142 KOKKOS_FUNCTION constexpr ChunkSpan(
144 : base_type(other.m_internal_mdspan, other.m_domain)
145 {
146 }
147
151 // Disabled by SFINAE in the case of `ElementType` is not `const` to avoid write access
152 template <
153 class OElementType,
155 class = std::enable_if_t<std::is_const_v<SFINAEElementType>>,
156 class Allocator,
157 class = std::enable_if_t<std::is_same_v<typename Allocator::memory_space, MemorySpace>>>
158 KOKKOS_FUNCTION constexpr ChunkSpan(
160 : base_type(other.m_internal_mdspan, other.m_domain)
161 {
162 }
163
167 template <class OElementType>
168 KOKKOS_FUNCTION constexpr ChunkSpan(
170 : base_type(other.m_internal_mdspan, other.m_domain)
171 {
172 }
173
178 template <
179 class Mapping = mapping_type,
180 std::enable_if_t<std::is_constructible_v<Mapping, extents_type>, int> = 0>
181 KOKKOS_FUNCTION constexpr ChunkSpan(ElementType* const ptr, mdomain_type const& domain)
182 : base_type(ptr, domain)
183 {
184 }
185
190 KOKKOS_FUNCTION constexpr ChunkSpan(
191 allocation_mdspan_type allocation_mdspan,
192 mdomain_type const& domain)
193 {
194 assert(((allocation_mdspan.extent(type_seq_rank_v<DDims, detail::TypeSeq<DDims...>>)
195 == static_cast<std::size_t>(domain.template extent<DDims>().value()))
196 && ...));
197 namespace stdex = std::experimental;
198 if (!domain.empty()) {
199 extents_type extents_s((front<DDims>(domain) + extents<DDims>(domain)).uid()...);
200 std::array<std::size_t, sizeof...(DDims)> strides_s {allocation_mdspan.mapping().stride(
201 type_seq_rank_v<DDims, detail::TypeSeq<DDims...>>)...};
202 stdex::layout_stride::mapping<extents_type> mapping_s(extents_s, strides_s);
203 this->m_internal_mdspan = internal_mdspan_type(
204 allocation_mdspan.data_handle() - mapping_s(front<DDims>(domain).uid()...),
205 mapping_s);
206 } else {
207 this->m_internal_mdspan = allocation_mdspan;
208 }
209 this->m_domain = domain;
210 }
211
217 KOKKOS_FUNCTION constexpr ChunkSpan(KokkosView const& view, mdomain_type const& domain) noexcept
218 : ChunkSpan(
219 detail::build_mdspan(view, std::make_index_sequence<sizeof...(DDims)> {}),
220 domain)
221 {
222 }
225
230 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan& operator=(ChunkSpan const& other) = default;
231
236 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan& operator=(ChunkSpan&& other) = default;
237
240 template <class... QueryDDims>
241 KOKKOS_FUNCTION constexpr auto operator[](
243 {
244 auto subview = std::experimental::
245 submdspan(allocation_mdspan(), get_slicer_for<DDims>(slice_spec)...);
246 using detail::TypeSeq;
248 return ChunkSpan<
250 decltype(select_by_type_seq<selected_meshes>(this->m_domain)),
251 typename decltype(subview)::layout_type,
253 }
254
257 template <class... QueryDDims>
258 KOKKOS_FUNCTION constexpr auto operator[](DiscreteDomain<QueryDDims...> const& odomain) const
259 {
260 auto subview = std::experimental::
261 submdspan(allocation_mdspan(), get_slicer_for<DDims>(odomain)...);
262 return ChunkSpan<
264 decltype(this->m_domain.restrict(odomain)),
265 typename decltype(subview)::layout_type,
266 memory_space>(subview, this->m_domain.restrict(odomain));
267 }
268
273 template <class... DElems>
274 KOKKOS_FUNCTION constexpr reference operator()(DElems const&... delems) const noexcept
275 {
276 static_assert(
277 sizeof...(DDims) == (0 + ... + DElems::size()),
278 "Invalid number of dimensions");
279 static_assert((is_discrete_element_v<DElems> && ...), "Expected DiscreteElements");
280 assert(((select<DDims>(take<DDims>(delems...)) >= front<DDims>(this->m_domain)) && ...));
281 assert(((select<DDims>(take<DDims>(delems...)) <= back<DDims>(this->m_domain)) && ...));
282 return this->m_internal_mdspan(uid<DDims>(take<DDims>(delems...))...);
283 }
284
288 KOKKOS_FUNCTION constexpr ElementType* data_handle() const
289 {
290 return base_type::data_handle();
291 }
292
296 KOKKOS_FUNCTION constexpr allocation_mdspan_type allocation_mdspan() const
297 {
298 return base_type::allocation_mdspan();
299 }
300
304 KOKKOS_FUNCTION constexpr auto allocation_kokkos_view() const
305 {
306 auto s = this->allocation_mdspan();
307 auto kokkos_layout = detail::build_kokkos_layout(
308 s.extents(),
309 s.mapping(),
310 std::make_index_sequence<sizeof...(DDims)> {});
311 return Kokkos::View<
312 detail::mdspan_to_kokkos_element_t<ElementType, sizeof...(DDims)>,
313 decltype(kokkos_layout),
314 MemorySpace>(s.data_handle(), kokkos_layout);
315 }
317 KOKKOS_FUNCTION constexpr view_type span_cview() const
318 {
319 return view_type(*this);
320 }
322 KOKKOS_FUNCTION constexpr span_type span_view() const
323 {
324 return *this;
325 }
326};
327
328template <
329 class KokkosView,
330 class... DDims,
331 class = std::enable_if_t<Kokkos::is_view<KokkosView>::value>>
333 detail::kokkos_to_mdspan_element_t<typename KokkosView::data_type>,
335 detail::kokkos_to_mdspan_layout_t<typename KokkosView::array_layout>,
336 typename KokkosView::memory_space>;
337
338template <
339 class ElementType,
340 class SupportType,
341 class LayoutStridedPolicy = std::experimental::layout_right,
342 class MemorySpace = Kokkos::HostSpace>
344
345} // namespace ddc
std::experimental::mdspan< const ElementType, std::experimental::dextents< std::size_t, sizeof...(DDims)>, LayoutStridedPolicy > const_allocation_mdspan_type
Definition chunk_common.hpp:55
std::experimental::mdspan< ElementType, std::experimental::dextents< std::size_t, sizeof...(DDims)>, std::experimental::layout_stride > internal_mdspan_type
the raw mdspan underlying this, with the same indexing (0 might no be dereferenceable)
Definition chunk_common.hpp:41
typename allocation_mdspan_type::mapping_type mapping_type
Definition chunk_common.hpp:68
std::experimental::mdspan< ElementType, std::experimental::dextents< std::size_t, sizeof...(DDims)>, LayoutStridedPolicy > allocation_mdspan_type
The dereferenceable part of the co-domain but with a different domain, starting at 0.
Definition chunk_common.hpp:50
typename allocation_mdspan_type::size_type size_type
Definition chunk_common.hpp:74
typename allocation_mdspan_type::data_handle_type data_handle_type
Definition chunk_common.hpp:76
typename allocation_mdspan_type::layout_type layout_type
Definition chunk_common.hpp:64
typename allocation_mdspan_type::accessor_type accessor_type
Definition chunk_common.hpp:66
typename allocation_mdspan_type::reference reference
Definition chunk_common.hpp:78
typename allocation_mdspan_type::element_type element_type
Definition chunk_common.hpp:70
typename allocation_mdspan_type::extents_type extents_type
Definition chunk_common.hpp:62
typename allocation_mdspan_type::value_type value_type
Definition chunk_common.hpp:72
typename base_type::const_allocation_mdspan_type const_allocation_mdspan_type
Definition chunk_span.hpp:68
typename base_type::mapping_type mapping_type
Definition chunk_span.hpp:78
typename mdomain_type::discrete_element_type discrete_element_type
Definition chunk_span.hpp:70
typename base_type::accessor_type accessor_type
Definition chunk_span.hpp:76
typename base_type::extents_type extents_type
Definition chunk_span.hpp:72
typename base_type::value_type value_type
Definition chunk_span.hpp:82
typename base_type::layout_type layout_type
Definition chunk_span.hpp:74
typename base_type::allocation_mdspan_type allocation_mdspan_type
The dereferenceable part of the co-domain but with a different domain, starting at 0.
Definition chunk_span.hpp:66
typename base_type::element_type element_type
Definition chunk_span.hpp:80
typename base_type::data_handle_type data_handle_type
Definition chunk_span.hpp:86
Definition discrete_domain.hpp:51
The top-level namespace of DDC.
Definition aligned_allocator.hpp:11
constexpr bool enable_borrowed_chunk
Definition chunk_traits.hpp:13
constexpr bool enable_chunk
Definition chunk_traits.hpp:16
ChunkSpan(KokkosView const &view, DiscreteDomain< DDims... > domain) -> ChunkSpan< detail::kokkos_to_mdspan_element_t< typename KokkosView::data_type >, DiscreteDomain< DDims... >, detail::kokkos_to_mdspan_layout_t< typename KokkosView::array_layout >, typename KokkosView::memory_space >
Chunk(std::string const &, DiscreteDomain< DDims... > const &, Allocator) -> Chunk< typename Allocator::value_type, DiscreteDomain< DDims... >, Allocator >
KOKKOS_FUNCTION constexpr DiscreteElementType const & uid(DiscreteElement< Tag > const &tuple) noexcept
Definition discrete_element.hpp:51
Definition chunk.hpp:21
Definition chunk_common.hpp:34
Definition chunk_span.hpp:30