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