DDC 0.6.0
Loading...
Searching...
No Matches
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 <Kokkos_Core.hpp>
14
15#include "ddc/chunk_common.hpp"
16#include "ddc/detail/kokkos.hpp"
17#include "ddc/detail/type_seq.hpp"
18#include "ddc/discrete_domain.hpp"
19#include "ddc/discrete_element.hpp"
20
21namespace ddc {
22
23template <class, class, class>
24class Chunk;
25
26template <
27 class ElementType,
28 class SupportType,
29 class LayoutStridedPolicy = Kokkos::layout_right,
30 class MemorySpace = Kokkos::DefaultHostExecutionSpace::memory_space>
31class ChunkSpan;
32
33template <class ElementType, class SupportType, class LayoutStridedPolicy, class MemorySpace>
34inline constexpr bool
36 = true;
37
38template <class ElementType, class SupportType, class LayoutStridedPolicy, class MemorySpace>
39inline constexpr bool
41 = true;
42
43template <class ElementType, class... DDims, class LayoutStridedPolicy, class MemorySpace>
44class ChunkSpan<ElementType, DiscreteDomain<DDims...>, LayoutStridedPolicy, MemorySpace>
45 : public ChunkCommon<ElementType, DiscreteDomain<DDims...>, LayoutStridedPolicy>
46{
47 static_assert(
48 std::is_same_v<LayoutStridedPolicy, Kokkos::layout_left>
49 || std::is_same_v<LayoutStridedPolicy, Kokkos::layout_right>
50 || std::is_same_v<LayoutStridedPolicy, Kokkos::layout_stride>,
51 "ChunkSpan only supports layout_left, layout_right or layout_stride");
52
53protected:
54 using base_type = ChunkCommon<ElementType, DiscreteDomain<DDims...>, LayoutStridedPolicy>;
55
56 /// the raw mdspan underlying this, with the same indexing (0 might no be dereferenceable)
57 using typename base_type::internal_mdspan_type;
58
59public:
60 /// type of a span of this full chunk
61 using span_type
62 = ChunkSpan<ElementType, DiscreteDomain<DDims...>, LayoutStridedPolicy, MemorySpace>;
63
64 /// type of a view of this full chunk
65 using view_type = ChunkSpan<
66 ElementType const,
67 DiscreteDomain<DDims...>,
68 LayoutStridedPolicy,
69 MemorySpace>;
70
71 using discrete_domain_type = typename base_type::discrete_domain_type;
72
73 using memory_space = MemorySpace;
74
75 /// The dereferenceable part of the co-domain but with a different domain, starting at 0
76 using allocation_mdspan_type = typename base_type::allocation_mdspan_type;
77
78 using const_allocation_mdspan_type = typename base_type::const_allocation_mdspan_type;
79
80 using discrete_element_type = typename discrete_domain_type::discrete_element_type;
81
82 using extents_type = typename base_type::extents_type;
83
84 using layout_type = typename base_type::layout_type;
85
86 using accessor_type = typename base_type::accessor_type;
87
88 using mapping_type = typename base_type::mapping_type;
89
90 using element_type = typename base_type::element_type;
91
92 using value_type = typename base_type::value_type;
93
94 using size_type = typename base_type::size_type;
95
96 using data_handle_type = typename base_type::data_handle_type;
97
98 using reference = typename base_type::reference;
99
100 template <class, class, class, class>
101 friend class ChunkSpan;
102
103protected:
104 static KOKKOS_FUNCTION internal_mdspan_type build_internal_mdspan(
105 allocation_mdspan_type const& allocation_mdspan,
106 discrete_domain_type const& domain)
107 {
108 if (!domain.empty()) {
109 extents_type const extents_s(
110 (front<DDims>(domain) + ddc::extents<DDims>(domain)).uid()...);
111 std::array<std::size_t, sizeof...(DDims)> const strides_s {
112 allocation_mdspan.mapping().stride(
113 type_seq_rank_v<DDims, detail::TypeSeq<DDims...>>)...};
114 Kokkos::layout_stride::mapping<extents_type> const mapping_s(extents_s, strides_s);
115 return internal_mdspan_type(
116 allocation_mdspan.data_handle() - mapping_s(front<DDims>(domain).uid()...),
117 mapping_s);
118 }
119
120 return internal_mdspan_type(allocation_mdspan);
121 }
122
123 template <class QueryDDim, class... ODDims>
124 KOKKOS_FUNCTION constexpr auto get_slicer_for(DiscreteElement<ODDims...> const& c) const
125 {
126 DDC_IF_NVCC_THEN_PUSH_AND_SUPPRESS(implicit_return_from_non_void_function)
127 if constexpr (in_tags_v<QueryDDim, detail::TypeSeq<ODDims...>>) {
128 return (uid<QueryDDim>(c) - front<QueryDDim>(this->m_domain).uid());
129 } else {
130 return Kokkos::full_extent;
131 }
132 DDC_IF_NVCC_THEN_POP
133 }
134
135 template <class QueryDDim, class... ODDims>
136 KOKKOS_FUNCTION constexpr auto get_slicer_for(DiscreteDomain<ODDims...> const& c) const
137 {
138 DDC_IF_NVCC_THEN_PUSH_AND_SUPPRESS(implicit_return_from_non_void_function)
139 if constexpr (in_tags_v<QueryDDim, detail::TypeSeq<ODDims...>>) {
140 return std::pair<std::size_t, std::size_t>(
141 front<QueryDDim>(c) - front<QueryDDim>(this->m_domain),
142 back<QueryDDim>(c) + 1 - front<QueryDDim>(this->m_domain));
143 } else {
144 return Kokkos::full_extent;
145 }
146 DDC_IF_NVCC_THEN_POP
147 }
148
149public:
150 /// Empty ChunkSpan
151 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan() = default;
152
153 /** Constructs a new ChunkSpan by copy, yields a new view to the same data
154 * @param other the ChunkSpan to copy
155 */
156 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan(ChunkSpan const& other) = default;
157
158 /** Constructs a new ChunkSpan by move
159 * @param other the ChunkSpan to move
160 */
161 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan(ChunkSpan&& other) noexcept = default;
162
163 /** Forbids to construct a ChunkSpan from a rvalue of type Chunk.
164 */
165 template <
166 class OElementType,
167 class Allocator,
168 class = std::enable_if_t<std::is_same_v<typename Allocator::memory_space, MemorySpace>>>
169 ChunkSpan(Chunk<OElementType, discrete_domain_type, Allocator>&& other) noexcept = delete;
170
171 /** Constructs a new ChunkSpan from a Chunk, yields a new view to the same data
172 * @param other the Chunk to view
173 */
174 template <
175 class OElementType,
176 class Allocator,
177 class = std::enable_if_t<std::is_same_v<typename Allocator::memory_space, MemorySpace>>>
178 KOKKOS_FUNCTION constexpr explicit ChunkSpan(
179 Chunk<OElementType, discrete_domain_type, Allocator>& other) noexcept
180 : base_type(other.m_internal_mdspan, other.m_domain)
181 {
182 }
183
184 /** Constructs a new ChunkSpan from a Chunk, yields a new view to the same data
185 * @param other the Chunk to view
186 */
187 // Disabled by SFINAE in the case of `ElementType` is not `const` to avoid write access
188 template <
189 class OElementType,
190 class SFINAEElementType = ElementType,
191 class = std::enable_if_t<std::is_const_v<SFINAEElementType>>,
192 class Allocator,
193 class = std::enable_if_t<std::is_same_v<typename Allocator::memory_space, MemorySpace>>>
194 KOKKOS_FUNCTION constexpr explicit ChunkSpan(
195 Chunk<OElementType, discrete_domain_type, Allocator> const& other) noexcept
196 : base_type(other.m_internal_mdspan, other.m_domain)
197 {
198 }
199
200 /** Constructs a new ChunkSpan by copy of a chunk, yields a new view to the same data
201 * @param other the ChunkSpan to move
202 */
203 template <class OElementType>
204 KOKKOS_FUNCTION constexpr explicit ChunkSpan(
205 ChunkSpan<OElementType, discrete_domain_type, layout_type, MemorySpace> const&
206 other) noexcept
207 : base_type(other.m_internal_mdspan, other.m_domain)
208 {
209 }
210
211 /** Constructs a new ChunkSpan from scratch
212 * @param ptr the allocation pointer to the data
213 * @param domain the domain that sustains the view
214 */
215 template <
216 class Mapping = mapping_type,
217 std::enable_if_t<std::is_constructible_v<Mapping, extents_type>, int> = 0>
218 KOKKOS_FUNCTION constexpr ChunkSpan(ElementType* const ptr, discrete_domain_type const& domain)
219 : base_type(ptr, domain)
220 {
221 }
222
223 /** Constructs a new ChunkSpan from scratch
224 * @param allocation_mdspan the allocation mdspan to the data
225 * @param domain the domain that sustains the view
226 */
227 KOKKOS_FUNCTION constexpr ChunkSpan(
228 allocation_mdspan_type allocation_mdspan,
229 discrete_domain_type const& domain)
230 : base_type(build_internal_mdspan(allocation_mdspan, domain), domain)
231 {
232 assert(((allocation_mdspan.extent(type_seq_rank_v<DDims, detail::TypeSeq<DDims...>>)
233 == static_cast<std::size_t>(domain.template extent<DDims>().value()))
234 && ...));
235 }
236
237 /** Constructs a new ChunkSpan from scratch
238 * @param view the Kokkos view
239 * @param domain the domain that sustains the view
240 */
241 template <class KokkosView, class = std::enable_if_t<Kokkos::is_view_v<KokkosView>>>
242 KOKKOS_FUNCTION constexpr ChunkSpan(
243 KokkosView const& view,
244 discrete_domain_type const& domain) noexcept
245 : ChunkSpan(
246 detail::build_mdspan(view, std::make_index_sequence<sizeof...(DDims)> {}),
247 domain)
248 {
249 }
250
251 KOKKOS_DEFAULTED_FUNCTION ~ChunkSpan() noexcept = default;
252
253 /** Copy-assigns a new value to this ChunkSpan, yields a new view to the same data
254 * @param other the ChunkSpan to copy
255 * @return *this
256 */
257 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan& operator=(ChunkSpan const& other) = default;
258
259 /** Move-assigns a new value to this ChunkSpan
260 * @param other the ChunkSpan to move
261 * @return *this
262 */
263 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan& operator=(ChunkSpan&& other) noexcept = default;
264
265 /** Slice out some dimensions
266 */
267 template <class... QueryDDims>
268 KOKKOS_FUNCTION constexpr auto operator[](
269 DiscreteElement<QueryDDims...> const& slice_spec) const
270 {
271 auto subview = Kokkos::submdspan(allocation_mdspan(), get_slicer_for<DDims>(slice_spec)...);
272 using layout_type = typename decltype(subview)::layout_type;
273 using extents_type = typename decltype(subview)::extents_type;
274 using detail::TypeSeq;
275 using OutTypeSeqDDims = type_seq_remove_t<TypeSeq<DDims...>, TypeSeq<QueryDDims...>>;
276 using OutDDom = detail::convert_type_seq_to_discrete_domain_t<OutTypeSeqDDims>;
277 if constexpr (
278 std::is_same_v<layout_type, Kokkos::Experimental::layout_left_padded<>>
279 || std::is_same_v<layout_type, Kokkos::Experimental::layout_right_padded<>>) {
280 Kokkos::layout_stride::mapping<extents_type> const mapping_stride(subview.mapping());
281 Kokkos::mdspan<ElementType, extents_type, Kokkos::layout_stride> const
282 a(subview.data_handle(), mapping_stride);
283 return ChunkSpan<
284 ElementType,
285 OutDDom,
286 Kokkos::layout_stride,
287 memory_space>(a, OutDDom(this->m_domain));
288 } else {
289 return ChunkSpan<
290 ElementType,
291 OutDDom,
292 layout_type,
293 memory_space>(subview, OutDDom(this->m_domain));
294 }
295 }
296
297 /** Restrict to a subdomain
298 */
299 template <class... QueryDDims>
300 KOKKOS_FUNCTION constexpr auto operator[](DiscreteDomain<QueryDDims...> const& odomain) const
301 {
302 auto subview = Kokkos::submdspan(allocation_mdspan(), get_slicer_for<DDims>(odomain)...);
303 using layout_type = typename decltype(subview)::layout_type;
304 using extents_type = typename decltype(subview)::extents_type;
305 if constexpr (
306 std::is_same_v<layout_type, Kokkos::Experimental::layout_left_padded<>>
307 || std::is_same_v<layout_type, Kokkos::Experimental::layout_right_padded<>>) {
308 Kokkos::layout_stride::mapping<extents_type> const mapping_stride(subview.mapping());
309 Kokkos::mdspan<ElementType, extents_type, Kokkos::layout_stride> const
310 a(subview.data_handle(), mapping_stride);
311 return ChunkSpan<
312 ElementType,
313 decltype(this->m_domain.restrict_with(odomain)),
314 Kokkos::layout_stride,
315 memory_space>(a, this->m_domain.restrict_with(odomain));
316 } else {
317 return ChunkSpan<
318 ElementType,
319 decltype(this->m_domain.restrict_with(odomain)),
320 layout_type,
321 memory_space>(subview, this->m_domain.restrict_with(odomain));
322 }
323 }
324
325 /** Element access using a list of DiscreteElement
326 * @param delems discrete elements
327 * @return reference to this element
328 */
329 template <class... DElems>
330 KOKKOS_FUNCTION constexpr reference operator()(DElems const&... delems) const noexcept
331 {
332 static_assert(
333 sizeof...(DDims) == (0 + ... + DElems::size()),
334 "Invalid number of dimensions");
335 static_assert((is_discrete_element_v<DElems> && ...), "Expected DiscreteElements");
336 assert(((DiscreteElement<DDims>(take<DDims>(delems...)) >= front<DDims>(this->m_domain))
337 && ...));
338 assert(((DiscreteElement<DDims>(take<DDims>(delems...)) <= back<DDims>(this->m_domain))
339 && ...));
340 return DDC_MDSPAN_ACCESS_OP(this->m_internal_mdspan, uid<DDims>(take<DDims>(delems...))...);
341 }
342
343 /** Access to the underlying allocation pointer
344 * @return allocation pointer
345 */
346 KOKKOS_FUNCTION constexpr ElementType* data_handle() const
347 {
348 return base_type::data_handle();
349 }
350
351 /** Provide a mdspan on the memory allocation
352 * @return allocation mdspan
353 */
354 KOKKOS_FUNCTION constexpr allocation_mdspan_type allocation_mdspan() const
355 {
356 return base_type::allocation_mdspan();
357 }
358
359 /** Provide a mdspan on the memory allocation
360 * @return allocation mdspan
361 */
362 KOKKOS_FUNCTION constexpr auto allocation_kokkos_view() const
363 {
364 auto s = this->allocation_mdspan();
365 auto kokkos_layout = detail::build_kokkos_layout(
366 s.extents(),
367 s.mapping(),
368 std::make_index_sequence<sizeof...(DDims)> {});
369 return Kokkos::View<
370 detail::mdspan_to_kokkos_element_t<ElementType, sizeof...(DDims)>,
371 decltype(kokkos_layout),
372 MemorySpace>(s.data_handle(), kokkos_layout);
373 }
374
375 KOKKOS_FUNCTION constexpr view_type span_cview() const
376 {
377 return view_type(*this);
378 }
379
380 KOKKOS_FUNCTION constexpr span_type span_view() const
381 {
382 return *this;
383 }
384};
385
386template <class ElementType, class SupportType, class LayoutStridedPolicy, class MemorySpace>
387class ChunkSpan : public ChunkCommon<ElementType, SupportType, LayoutStridedPolicy>
388{
389 static_assert(
390 std::is_same_v<LayoutStridedPolicy, Kokkos::layout_left>
391 || std::is_same_v<LayoutStridedPolicy, Kokkos::layout_right>
392 || std::is_same_v<LayoutStridedPolicy, Kokkos::layout_stride>,
393 "ChunkSpan only supports layout_left, layout_right or layout_stride");
394
395protected:
396 using base_type = ChunkCommon<ElementType, SupportType, LayoutStridedPolicy>;
397
398public:
399 /// type of a span of this full chunk
400 using span_type = ChunkSpan<ElementType, SupportType, LayoutStridedPolicy, MemorySpace>;
401
402 /// type of a view of this full chunk
403 using view_type = ChunkSpan<ElementType const, SupportType, LayoutStridedPolicy, MemorySpace>;
404
405 using discrete_domain_type = typename base_type::discrete_domain_type;
406
407 using memory_space = MemorySpace;
408
409 /// The dereferenceable part of the co-domain but with a different domain, starting at 0
410 using allocation_mdspan_type = typename base_type::allocation_mdspan_type;
411
412 using const_allocation_mdspan_type = typename base_type::const_allocation_mdspan_type;
413
414 using discrete_element_type = typename discrete_domain_type::discrete_element_type;
415
416 using extents_type = typename base_type::extents_type;
417
418 using layout_type = typename base_type::layout_type;
419
420 using accessor_type = typename base_type::accessor_type;
421
422 using mapping_type = typename base_type::mapping_type;
423
424 using element_type = typename base_type::element_type;
425
426 using value_type = typename base_type::value_type;
427
428 using size_type = typename base_type::size_type;
429
430 using data_handle_type = typename base_type::data_handle_type;
431
432 using reference = typename base_type::reference;
433
434 template <class, class, class, class>
435 friend class ChunkSpan;
436
437protected:
438 template <class QueryDDim, class... ODDims>
439 KOKKOS_FUNCTION static constexpr auto get_slicer_for(DiscreteVector<ODDims...> const& c)
440 {
441 DDC_IF_NVCC_THEN_PUSH_AND_SUPPRESS(implicit_return_from_non_void_function)
442 if constexpr (in_tags_v<QueryDDim, detail::TypeSeq<ODDims...>>) {
443 return c.template get<QueryDDim>();
444 } else {
445 return Kokkos::full_extent;
446 }
447 DDC_IF_NVCC_THEN_POP
448 }
449
450 template <class TypeSeq>
451 struct slicer;
452
453 template <class... DDims>
454 struct slicer<detail::TypeSeq<DDims...>>
455 {
456 template <class... ODDims>
457 KOKKOS_FUNCTION constexpr auto operator()(
458 allocation_mdspan_type const& span,
459 DiscreteVector<ODDims...> const& c) const
460 {
461 return Kokkos::submdspan(span, get_slicer_for<DDims>(c)...);
462 }
463 };
464
465public:
466 /// Empty ChunkSpan
467 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan() = default;
468
469 /** Constructs a new ChunkSpan by copy, yields a new view to the same data
470 * @param other the ChunkSpan to copy
471 */
472 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan(ChunkSpan const& other) = default;
473
474 /** Constructs a new ChunkSpan by move
475 * @param other the ChunkSpan to move
476 */
477 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan(ChunkSpan&& other) noexcept = default;
478
479 /** Forbids to construct a ChunkSpan from a rvalue of type Chunk.
480 */
481 template <
482 class OElementType,
483 class Allocator,
484 class = std::enable_if_t<std::is_same_v<typename Allocator::memory_space, MemorySpace>>>
485 ChunkSpan(Chunk<OElementType, SupportType, Allocator>&& other) noexcept = delete;
486
487 /** Constructs a new ChunkSpan from a Chunk, yields a new view to the same data
488 * @param other the Chunk to view
489 */
490 template <
491 class OElementType,
492 class Allocator,
493 class = std::enable_if_t<std::is_same_v<typename Allocator::memory_space, MemorySpace>>>
494 KOKKOS_FUNCTION constexpr explicit ChunkSpan(
495 Chunk<OElementType, SupportType, Allocator>& other) noexcept
496 : base_type(other.m_allocation_mdspan, other.m_domain)
497 {
498 }
499
500 /** Constructs a new ChunkSpan from a Chunk, yields a new view to the same data
501 * @param other the Chunk to view
502 */
503 // Disabled by SFINAE in the case of `ElementType` is not `const` to avoid write access
504 template <
505 class OElementType,
506 class SFINAEElementType = ElementType,
507 class = std::enable_if_t<std::is_const_v<SFINAEElementType>>,
508 class Allocator,
509 class = std::enable_if_t<std::is_same_v<typename Allocator::memory_space, MemorySpace>>>
510 KOKKOS_FUNCTION constexpr explicit ChunkSpan(
511 Chunk<OElementType, SupportType, Allocator> const& other) noexcept
512 : base_type(other.m_allocation_mdspan, other.m_domain)
513 {
514 }
515
516 /** Constructs a new ChunkSpan by copy of a chunk, yields a new view to the same data
517 * @param other the ChunkSpan to move
518 */
519 template <class OElementType>
520 KOKKOS_FUNCTION constexpr explicit ChunkSpan(
521 ChunkSpan<OElementType, SupportType, layout_type, MemorySpace> const& other) noexcept
522 : base_type(other.m_allocation_mdspan, other.m_domain)
523 {
524 }
525
526 /** Constructs a new ChunkSpan from scratch
527 * @param ptr the allocation pointer to the data
528 * @param domain the domain that sustains the view
529 */
530 template <
531 class Mapping = mapping_type,
532 std::enable_if_t<std::is_constructible_v<Mapping, extents_type>, int> = 0>
533 KOKKOS_FUNCTION constexpr ChunkSpan(ElementType* const ptr, SupportType const& domain)
534 : base_type(ptr, domain)
535 {
536 }
537
538 /** Constructs a new ChunkSpan from scratch
539 * @param allocation_mdspan the allocation mdspan to the data
540 * @param domain the domain that sustains the view
541 */
542 KOKKOS_FUNCTION constexpr ChunkSpan(
543 allocation_mdspan_type allocation_mdspan,
544 SupportType const& domain)
545 : base_type(allocation_mdspan, domain)
546 {
547 for (std::size_t i = 0; i < SupportType::rank(); ++i) {
548 assert(allocation_mdspan.extent(i)
549 == static_cast<std::size_t>(detail::array(domain.extents())[i]));
550 }
551 }
552
553 /** Constructs a new ChunkSpan from scratch
554 * @param view the Kokkos view
555 * @param domain the domain that sustains the view
556 */
557 template <class KokkosView, class = std::enable_if_t<Kokkos::is_view_v<KokkosView>>>
558 KOKKOS_FUNCTION constexpr ChunkSpan(KokkosView const& view, SupportType const& domain) noexcept
559 : ChunkSpan(
560 detail::build_mdspan(view, std::make_index_sequence<SupportType::rank()> {}),
561 domain)
562 {
563 }
564
565 KOKKOS_DEFAULTED_FUNCTION ~ChunkSpan() noexcept = default;
566
567 /** Copy-assigns a new value to this ChunkSpan, yields a new view to the same data
568 * @param other the ChunkSpan to copy
569 * @return *this
570 */
571 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan& operator=(ChunkSpan const& other) = default;
572
573 /** Move-assigns a new value to this ChunkSpan
574 * @param other the ChunkSpan to move
575 * @return *this
576 */
577 KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan& operator=(ChunkSpan&& other) noexcept = default;
578
579 /** Slice out some dimensions
580 */
581 template <class... QueryDDims>
582 KOKKOS_FUNCTION constexpr auto operator[](
583 DiscreteElement<QueryDDims...> const& slice_spec) const
584 {
585 slicer<to_type_seq_t<SupportType>> const slicer;
586 auto subview
587 = slicer(this->allocation_mdspan(), this->m_domain.distance_from_front(slice_spec));
588 using layout_type = typename decltype(subview)::layout_type;
589 using extents_type = typename decltype(subview)::extents_type;
590 using detail::TypeSeq;
591 using OutTypeSeqDDims
592 = type_seq_remove_t<to_type_seq_t<SupportType>, TypeSeq<QueryDDims...>>;
593 using OutDDom = typename detail::RebindDomain<SupportType, OutTypeSeqDDims>::type;
594 if constexpr (
595 std::is_same_v<layout_type, Kokkos::Experimental::layout_left_padded<>>
596 || std::is_same_v<layout_type, Kokkos::Experimental::layout_right_padded<>>) {
597 Kokkos::layout_stride::mapping<extents_type> const mapping_stride(subview.mapping());
598 Kokkos::mdspan<ElementType, extents_type, Kokkos::layout_stride> const
599 a(subview.data_handle(), mapping_stride);
600 return ChunkSpan<
601 ElementType,
602 OutDDom,
603 Kokkos::layout_stride,
604 memory_space>(a, OutDDom(this->m_domain));
605 } else {
606 return ChunkSpan<
607 ElementType,
608 OutDDom,
609 layout_type,
610 memory_space>(subview, OutDDom(this->m_domain));
611 }
612 }
613
614 /** Element access using a list of DiscreteElement
615 * @param delems discrete elements
616 * @return reference to this element
617 */
618 template <class... DElems>
619 KOKKOS_FUNCTION constexpr reference operator()(DElems const&... delems) const noexcept
620 {
621 static_assert(
622 SupportType::rank() == (0 + ... + DElems::size()),
623 "Invalid number of dimensions");
624 static_assert((is_discrete_element_v<DElems> && ...), "Expected DiscreteElements");
625 assert(this->m_domain.contains(delems...));
626 return DDC_MDSPAN_ACCESS_OP(
627 this->m_allocation_mdspan,
628 detail::array(this->m_domain.distance_from_front(delems...)));
629 }
630
631 /** Access to the underlying allocation pointer
632 * @return allocation pointer
633 */
634 KOKKOS_FUNCTION constexpr ElementType* data_handle() const
635 {
636 return base_type::data_handle();
637 }
638
639 /** Provide a mdspan on the memory allocation
640 * @return allocation mdspan
641 */
642 KOKKOS_FUNCTION constexpr allocation_mdspan_type allocation_mdspan() const
643 {
644 return base_type::allocation_mdspan();
645 }
646
647 /** Provide a mdspan on the memory allocation
648 * @return allocation mdspan
649 */
650 KOKKOS_FUNCTION constexpr auto allocation_kokkos_view() const
651 {
652 auto s = this->allocation_mdspan();
653 auto kokkos_layout = detail::build_kokkos_layout(
654 s.extents(),
655 s.mapping(),
656 std::make_index_sequence<SupportType::rank()> {});
657 return Kokkos::View<
658 detail::mdspan_to_kokkos_element_t<ElementType, SupportType::rank()>,
659 decltype(kokkos_layout),
660 MemorySpace>(s.data_handle(), kokkos_layout);
661 }
662
663 KOKKOS_FUNCTION constexpr view_type span_cview() const
664 {
665 return view_type(*this);
666 }
667
668 KOKKOS_FUNCTION constexpr span_type span_view() const
669 {
670 return *this;
671 }
672};
673
674template <class DataType, class... Properties, class SupportType>
676 Kokkos::View<DataType, Properties...> const& view,
677 SupportType domain)
678 -> ChunkSpan<
679 detail::kokkos_to_mdspan_element_t<
680 typename Kokkos::View<DataType, Properties...>::data_type>,
681 SupportType,
682 detail::kokkos_to_mdspan_layout_t<
683 typename Kokkos::View<DataType, Properties...>::array_layout>,
684 typename Kokkos::View<DataType, Properties...>::memory_space>;
685
686template <class ElementType, class SupportType, class Allocator>
687ChunkSpan(Chunk<ElementType, SupportType, Allocator>& other) -> ChunkSpan<
688 ElementType,
689 SupportType,
690 Kokkos::layout_right,
691 typename Allocator::memory_space>;
692
693template <class ElementType, class SupportType, class Allocator>
694ChunkSpan(Chunk<ElementType, SupportType, Allocator> const& other) -> ChunkSpan<
695 const ElementType,
696 SupportType,
697 Kokkos::layout_right,
698 typename Allocator::memory_space>;
699
700template <
701 class ElementType,
702 class SupportType,
703 class LayoutStridedPolicy = Kokkos::layout_right,
704 class MemorySpace = Kokkos::HostSpace>
705using ChunkView = ChunkSpan<ElementType const, SupportType, LayoutStridedPolicy, MemorySpace>;
706
707} // namespace ddc
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan & operator=(ChunkSpan const &other)=default
Copy-assigns a new value to this ChunkSpan, yields a new view to the same data.
KOKKOS_FUNCTION constexpr auto allocation_kokkos_view() const
Provide a mdspan on the memory allocation.
KOKKOS_FUNCTION constexpr ElementType * data_handle() const
Access to the underlying allocation pointer.
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan()=default
Empty ChunkSpan.
KOKKOS_FUNCTION constexpr reference operator()(DElems const &... delems) const noexcept
Element access using a list of DiscreteElement.
KOKKOS_FUNCTION constexpr ChunkSpan(Chunk< OElementType, discrete_domain_type, Allocator > &other) noexcept
Constructs a new ChunkSpan from a Chunk, yields a new view to the same data.
ChunkSpan(Chunk< OElementType, discrete_domain_type, Allocator > &&other) noexcept=delete
Forbids to construct a ChunkSpan from a rvalue of type Chunk.
KOKKOS_FUNCTION constexpr auto get_slicer_for(DiscreteElement< ODDims... > const &c) const
KOKKOS_FUNCTION constexpr allocation_mdspan_type allocation_mdspan() const
Provide a mdspan on the memory allocation.
KOKKOS_FUNCTION constexpr auto operator[](DiscreteDomain< QueryDDims... > const &odomain) const
Restrict to a subdomain.
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan(ChunkSpan &&other) noexcept=default
Constructs a new ChunkSpan by move.
KOKKOS_FUNCTION constexpr ChunkSpan(KokkosView const &view, discrete_domain_type const &domain) noexcept
Constructs a new ChunkSpan from scratch.
static KOKKOS_FUNCTION internal_mdspan_type build_internal_mdspan(allocation_mdspan_type const &allocation_mdspan, discrete_domain_type const &domain)
KOKKOS_FUNCTION constexpr ChunkSpan(Chunk< OElementType, discrete_domain_type, Allocator > const &other) noexcept
Constructs a new ChunkSpan from a Chunk, yields a new view to the same data.
KOKKOS_FUNCTION constexpr auto operator[](DiscreteElement< QueryDDims... > const &slice_spec) const
Slice out some dimensions.
KOKKOS_FUNCTION constexpr ChunkSpan(ElementType *const ptr, discrete_domain_type const &domain)
Constructs a new ChunkSpan from scratch.
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan & operator=(ChunkSpan &&other) noexcept=default
Move-assigns a new value to this ChunkSpan.
KOKKOS_FUNCTION constexpr ChunkSpan(ChunkSpan< OElementType, discrete_domain_type, layout_type, MemorySpace > const &other) noexcept
Constructs a new ChunkSpan by copy of a chunk, yields a new view to the same data.
KOKKOS_FUNCTION constexpr ChunkSpan(allocation_mdspan_type allocation_mdspan, discrete_domain_type const &domain)
Constructs a new ChunkSpan from scratch.
KOKKOS_FUNCTION constexpr auto get_slicer_for(DiscreteDomain< ODDims... > const &c) const
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan(ChunkSpan const &other)=default
Constructs a new ChunkSpan by copy, yields a new view to the same data.
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan(ChunkSpan &&other) noexcept=default
Constructs a new ChunkSpan by move.
KOKKOS_FUNCTION constexpr view_type span_cview() const
KOKKOS_FUNCTION constexpr ChunkSpan(Chunk< OElementType, SupportType, Allocator > const &other) noexcept
Constructs a new ChunkSpan from a Chunk, yields a new view to the same data.
KOKKOS_FUNCTION constexpr ChunkSpan(allocation_mdspan_type allocation_mdspan, SupportType const &domain)
Constructs a new ChunkSpan from scratch.
KOKKOS_FUNCTION constexpr auto operator[](DiscreteElement< QueryDDims... > const &slice_spec) const
Slice out some dimensions.
KOKKOS_FUNCTION constexpr ChunkSpan(KokkosView const &view, SupportType const &domain) noexcept
Constructs a new ChunkSpan from scratch.
ChunkSpan(Chunk< OElementType, SupportType, Allocator > &&other) noexcept=delete
Forbids to construct a ChunkSpan from a rvalue of type Chunk.
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan(ChunkSpan const &other)=default
Constructs a new ChunkSpan by copy, yields a new view to the same data.
KOKKOS_FUNCTION constexpr ChunkSpan(ElementType *const ptr, SupportType const &domain)
Constructs a new ChunkSpan from scratch.
static KOKKOS_FUNCTION constexpr auto get_slicer_for(DiscreteVector< ODDims... > const &c)
KOKKOS_FUNCTION constexpr reference operator()(DElems const &... delems) const noexcept
Element access using a list of DiscreteElement.
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan()=default
Empty ChunkSpan.
KOKKOS_FUNCTION constexpr allocation_mdspan_type allocation_mdspan() const
Provide a mdspan on the memory allocation.
KOKKOS_FUNCTION constexpr ElementType * data_handle() const
Access to the underlying allocation pointer.
KOKKOS_FUNCTION constexpr auto allocation_kokkos_view() const
Provide a mdspan on the memory allocation.
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan & operator=(ChunkSpan const &other)=default
Copy-assigns a new value to this ChunkSpan, yields a new view to the same data.
KOKKOS_FUNCTION constexpr ChunkSpan(Chunk< OElementType, SupportType, Allocator > &other) noexcept
Constructs a new ChunkSpan from a Chunk, yields a new view to the same data.
KOKKOS_FUNCTION constexpr ChunkSpan(ChunkSpan< OElementType, SupportType, layout_type, MemorySpace > const &other) noexcept
Constructs a new ChunkSpan by copy of a chunk, yields a new view to the same data.
KOKKOS_DEFAULTED_FUNCTION ~ChunkSpan() noexcept=default
KOKKOS_FUNCTION constexpr span_type span_view() const
KOKKOS_DEFAULTED_FUNCTION constexpr ChunkSpan & operator=(ChunkSpan &&other) noexcept=default
Move-assigns a new value to this ChunkSpan.
friend class DiscreteDomain
KOKKOS_FUNCTION constexpr bool operator!=(DiscreteVector< OTags... > const &rhs) const noexcept
The top-level namespace of DDC.
constexpr bool enable_borrowed_chunk< ChunkSpan< ElementType, SupportType, LayoutStridedPolicy, MemorySpace > >
ChunkSpan(Chunk< ElementType, SupportType, Allocator > &other) -> ChunkSpan< ElementType, SupportType, Kokkos::layout_right, typename Allocator::memory_space >
constexpr bool enable_chunk< ChunkSpan< ElementType, SupportType, LayoutStridedPolicy, MemorySpace > >
ChunkSpan(Chunk< ElementType, SupportType, Allocator > const &other) -> ChunkSpan< const ElementType, SupportType, Kokkos::layout_right, typename Allocator::memory_space >
KOKKOS_DEDUCTION_GUIDE ChunkSpan(Kokkos::View< DataType, Properties... > const &view, SupportType domain) -> ChunkSpan< detail::kokkos_to_mdspan_element_t< typename Kokkos::View< DataType, Properties... >::data_type >, SupportType, detail::kokkos_to_mdspan_layout_t< typename Kokkos::View< DataType, Properties... >::array_layout >, typename Kokkos::View< DataType, Properties... >::memory_space >