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