12#include <Kokkos_Core.hpp>
14#include "ddc/chunk_common.hpp"
15#include "ddc/chunk_span.hpp"
16#include "ddc/chunk_traits.hpp"
17#include "ddc/detail/kokkos.hpp"
18#include "ddc/detail/type_traits.hpp"
19#include "ddc/kokkos_allocator.hpp"
23template <
class ElementType,
class,
class Allocator = HostAllocator<ElementType>>
29template <
class ElementType,
class... DDims,
class Allocator>
37 using internal_mdspan_type =
typename base_type::internal_mdspan_type;
45 typename Allocator::memory_space>;
52 typename Allocator::memory_space>;
55 using allocation_mdspan_type =
typename base_type::allocation_mdspan_type;
57 using const_allocation_mdspan_type =
typename base_type::const_allocation_mdspan_type;
59 using discrete_domain_type =
typename base_type::discrete_domain_type;
61 using memory_space =
typename Allocator::memory_space;
63 using discrete_element_type =
typename base_type::discrete_element_type;
65 using discrete_vector_type =
typename base_type::discrete_vector_type;
67 using extents_type =
typename base_type::extents_type;
69 using layout_type =
typename base_type::layout_type;
71 using mapping_type =
typename base_type::mapping_type;
73 using element_type =
typename base_type::element_type;
75 using value_type =
typename base_type::value_type;
77 using size_type =
typename base_type::size_type;
79 using data_handle_type =
typename base_type::data_handle_type;
81 using reference =
typename base_type::reference;
83 template <
class,
class,
class>
87 Allocator m_allocator;
97 std::string
const& label,
98 discrete_domain_type
const& domain,
99 Allocator allocator = Allocator())
100 : base_type(allocator.allocate(label, domain.size()), domain)
101 , m_allocator(std::move(allocator))
107 explicit Chunk(discrete_domain_type
const& domain, Allocator allocator = Allocator())
108 :
Chunk(
"no-label", domain, std::move(allocator))
116
117
119 : base_type(std::move(
static_cast<base_type&>(other)))
120 , m_allocator(std::move(other.m_allocator))
121 , m_label(std::move(other.m_label))
123 other.m_internal_mdspan = internal_mdspan_type(
nullptr, other.m_internal_mdspan.mapping());
128 if (
this->m_internal_mdspan.data_handle()) {
129 m_allocator.deallocate(
this->data_handle(),
this->size());
137
138
139
142 if (
this == &other) {
145 if (
this->m_internal_mdspan.data_handle()) {
146 m_allocator.deallocate(
this->data_handle(),
this->size());
148 static_cast<base_type&>(*
this) = std::move(
static_cast<base_type&>(other));
149 m_allocator = std::move(other.m_allocator);
150 m_label = std::move(other.m_label);
151 other.m_internal_mdspan = internal_mdspan_type(
nullptr, other.m_internal_mdspan.mapping());
157 template <
class... QueryDDims>
158 auto operator[](DiscreteElement<QueryDDims...>
const& slice_spec)
const
160 return view_type(*
this)[slice_spec];
164 template <
class... QueryDDims>
165 auto operator[](DiscreteElement<QueryDDims...>
const& slice_spec)
167 return span_view()[slice_spec];
171 template <
class... QueryDDims>
174 return span_view()[odomain];
178 template <
class... QueryDDims>
181 return span_view()[odomain];
185
186
187
190 std::enable_if_t<detail::all_of_v<is_discrete_element_v<DElems>...>,
int> = 0>
191 element_type
const&
operator()(DElems
const&... delems)
const noexcept
194 sizeof...(DDims) == (0 + ... + DElems::size()),
195 "Invalid number of dimensions");
196 static_assert((is_discrete_element_v<DElems> && ...),
"Expected DiscreteElements");
197 assert(
this->m_domain.contains(delems...));
198 return DDC_MDSPAN_ACCESS_OP(
this->m_internal_mdspan, uid<DDims>(take<DDims>(delems...))...);
202
203
204
207 std::enable_if_t<detail::all_of_v<is_discrete_vector_v<DVects>...>,
int> = 0,
208 std::enable_if_t<
sizeof...(DVects) != 0,
int> = 0>
209 element_type
const&
operator()(DVects
const&... dvects)
const noexcept
212 sizeof...(DDims) == (0 + ... + DVects::size()),
213 "Invalid number of dimensions");
214 discrete_element_type
const delem
215 =
this->m_domain.front() + discrete_vector_type(dvects...);
216 return DDC_MDSPAN_ACCESS_OP(
this->m_internal_mdspan, uid<DDims>(delem)...);
220
221
222
225 std::enable_if_t<detail::all_of_v<is_discrete_element_v<DElems>...>,
int> = 0>
226 element_type&
operator()(DElems
const&... delems)
noexcept
229 sizeof...(DDims) == (0 + ... + DElems::size()),
230 "Invalid number of dimensions");
231 static_assert((is_discrete_element_v<DElems> && ...),
"Expected DiscreteElements");
232 assert(
this->m_domain.contains(delems...));
233 return DDC_MDSPAN_ACCESS_OP(
this->m_internal_mdspan, uid<DDims>(take<DDims>(delems...))...);
237
238
239
242 std::enable_if_t<detail::all_of_v<is_discrete_vector_v<DVects>...>,
int> = 0,
243 std::enable_if_t<
sizeof...(DVects) != 0,
int> = 0>
244 element_type&
operator()(DVects
const&... dvects)
noexcept
247 sizeof...(DDims) == (0 + ... + DVects::size()),
248 "Invalid number of dimensions");
249 discrete_element_type
const delem
250 =
this->m_domain.front() + discrete_vector_type(dvects...);
251 return DDC_MDSPAN_ACCESS_OP(
this->m_internal_mdspan, uid<DDims>(delem)...);
255
256
257 char const*
label()
const
259 return m_label.c_str();
263
264
267 return base_type::data_handle();
271
272
275 return base_type::data_handle();
279
280
283 return base_type::allocation_mdspan();
287
288
291 return base_type::allocation_mdspan();
295
296
299 auto s =
this->allocation_mdspan();
300 auto kokkos_layout = detail::build_kokkos_layout(
303 std::make_index_sequence<
sizeof...(DDims)> {});
305 detail::mdspan_to_kokkos_element_t<ElementType,
sizeof...(DDims)>,
306 decltype(kokkos_layout),
307 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
311
312
315 auto s =
this->allocation_mdspan();
316 auto kokkos_layout = detail::build_kokkos_layout(
319 std::make_index_sequence<
sizeof...(DDims)> {});
321 detail::mdspan_to_kokkos_element_t<ElementType
const,
sizeof...(DDims)>,
322 decltype(kokkos_layout),
323 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
328 return view_type(*
this);
333 return view_type(*
this);
338 return span_type(*
this);
342template <
class ElementType,
class SupportType,
class Allocator>
343class Chunk :
public ChunkCommon<ElementType, SupportType, Kokkos::layout_right>
346 using base_type =
ChunkCommon<ElementType, SupportType, Kokkos::layout_right>;
353 Kokkos::layout_right,
354 typename Allocator::memory_space>;
360 Kokkos::layout_right,
361 typename Allocator::memory_space>;
364 using allocation_mdspan_type =
typename base_type::allocation_mdspan_type;
366 using const_allocation_mdspan_type =
typename base_type::const_allocation_mdspan_type;
368 using discrete_domain_type =
typename base_type::discrete_domain_type;
370 using memory_space =
typename Allocator::memory_space;
372 using discrete_element_type =
typename base_type::discrete_element_type;
374 using discrete_vector_type =
typename base_type::discrete_vector_type;
376 using extents_type =
typename base_type::extents_type;
378 using layout_type =
typename base_type::layout_type;
380 using mapping_type =
typename base_type::mapping_type;
382 using element_type =
typename base_type::element_type;
384 using value_type =
typename base_type::value_type;
386 using size_type =
typename base_type::size_type;
388 using data_handle_type =
typename base_type::data_handle_type;
390 using reference =
typename base_type::reference;
392 template <
class,
class,
class>
396 Allocator m_allocator;
406 std::string
const& label,
407 SupportType
const& domain,
408 Allocator allocator = Allocator())
409 : base_type(allocator.allocate(label, domain.size()), domain)
410 , m_allocator(std::move(allocator))
416 explicit Chunk(SupportType
const& domain, Allocator allocator = Allocator())
417 :
Chunk(
"no-label", domain, std::move(allocator))
425
426
428 : base_type(std::move(
static_cast<base_type&>(other)))
429 , m_allocator(std::move(other.m_allocator))
430 , m_label(std::move(other.m_label))
432 other.m_allocation_mdspan
433 = allocation_mdspan_type(
nullptr, other.m_allocation_mdspan.mapping());
438 if (
this->m_allocation_mdspan.data_handle()) {
439 m_allocator.deallocate(
this->data_handle(),
this->size());
447
448
449
452 if (
this == &other) {
455 if (
this->m_allocation_mdspan.data_handle()) {
456 m_allocator.deallocate(
this->data_handle(),
this->size());
458 static_cast<base_type&>(*
this) = std::move(
static_cast<base_type&>(other));
459 m_allocator = std::move(other.m_allocator);
460 m_label = std::move(other.m_label);
461 other.m_allocation_mdspan
462 = allocation_mdspan_type(
nullptr, other.m_allocation_mdspan.mapping());
468 template <
class... QueryDDims>
469 auto operator[](DiscreteElement<QueryDDims...>
const& slice_spec)
const
471 return view_type(*
this)[slice_spec];
475 template <
class... QueryDDims>
476 auto operator[](DiscreteElement<QueryDDims...>
const& slice_spec)
478 return span_view()[slice_spec];
482
483
484
487 std::enable_if_t<detail::all_of_v<is_discrete_element_v<DElems>...>,
int> = 0>
488 element_type
const&
operator()(DElems
const&... delems)
const noexcept
491 SupportType::rank() == (0 + ... + DElems::size()),
492 "Invalid number of dimensions");
493 assert(
this->m_domain.contains(delems...));
494 return DDC_MDSPAN_ACCESS_OP(
495 this->m_allocation_mdspan,
496 detail::array(
this->m_domain.distance_from_front(delems...)));
500
501
502
505 std::enable_if_t<detail::all_of_v<is_discrete_vector_v<DVects>...>,
int> = 0,
506 std::enable_if_t<
sizeof...(DVects) != 0,
int> = 0>
507 element_type
const&
operator()(DVects
const&... dvects)
const noexcept
510 SupportType::rank() == (0 + ... + DVects::size()),
511 "Invalid number of dimensions");
512 return DDC_MDSPAN_ACCESS_OP(
513 this->m_allocation_mdspan,
514 detail::array(discrete_vector_type(dvects...)));
518
519
520
523 std::enable_if_t<detail::all_of_v<is_discrete_element_v<DElems>...>,
int> = 0>
524 element_type&
operator()(DElems
const&... delems)
noexcept
527 SupportType::rank() == (0 + ... + DElems::size()),
528 "Invalid number of dimensions");
529 assert(
this->m_domain.contains(delems...));
530 return DDC_MDSPAN_ACCESS_OP(
531 this->m_allocation_mdspan,
532 detail::array(
this->m_domain.distance_from_front(delems...)));
536
537
538
541 std::enable_if_t<detail::all_of_v<is_discrete_vector_v<DVects>...>,
int> = 0,
542 std::enable_if_t<
sizeof...(DVects) != 0,
int> = 0>
543 element_type&
operator()(DVects
const&... dvects)
noexcept
546 SupportType::rank() == (0 + ... + DVects::size()),
547 "Invalid number of dimensions");
548 return DDC_MDSPAN_ACCESS_OP(
549 this->m_allocation_mdspan,
550 detail::array(discrete_vector_type(dvects...)));
554
555
556 char const*
label()
const
558 return m_label.c_str();
562
563
566 return base_type::data_handle();
570
571
574 return base_type::data_handle();
578
579
582 return base_type::allocation_mdspan();
586
587
590 return base_type::allocation_mdspan();
594
595
598 auto s =
this->allocation_mdspan();
599 auto kokkos_layout = detail::build_kokkos_layout(
602 std::make_index_sequence<SupportType::rank()> {});
604 detail::mdspan_to_kokkos_element_t<ElementType, SupportType::rank()>,
605 decltype(kokkos_layout),
606 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
610
611
614 auto s =
this->allocation_mdspan();
615 auto kokkos_layout = detail::build_kokkos_layout(
618 std::make_index_sequence<SupportType::rank()> {});
620 detail::mdspan_to_kokkos_element_t<ElementType
const, SupportType::rank()>,
621 decltype(kokkos_layout),
622 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
627 return view_type(*
this);
632 return view_type(*
this);
637 return span_type(*
this);
641template <
class SupportType,
class Allocator>
642Chunk(std::string
const&, SupportType
const&, Allocator)
645template <
class SupportType,
class Allocator>
646Chunk(SupportType
const&, Allocator)
auto operator[](DiscreteDomain< QueryDDims... > const &odomain)
Slice out some dimensions.
auto operator[](DiscreteDomain< QueryDDims... > const &odomain) const
Slice out some dimensions.
Chunk(discrete_domain_type const &domain, Allocator allocator=Allocator())
Construct a Chunk on a domain with uninitialized values.
Chunk(Chunk &&other) noexcept
Constructs a new Chunk by move.
allocation_mdspan_type allocation_mdspan()
Provide a mdspan on the memory allocation.
ElementType * data_handle()
Access to the underlying allocation pointer.
auto operator[](DiscreteElement< QueryDDims... > const &slice_spec) const
Slice out some dimensions.
Chunk & operator=(Chunk const &other)=delete
Deleted: use deepcopy instead.
element_type & operator()(DVects const &... dvects) noexcept
Element access using a list of DiscreteVector.
const_allocation_mdspan_type allocation_mdspan() const
Provide a mdspan on the memory allocation.
Chunk & operator=(Chunk &&other) noexcept
Move-assigns a new value to this field.
element_type & operator()(DElems const &... delems) noexcept
Element access using a list of DiscreteElement.
auto allocation_kokkos_view() const
Provide an unmanaged Kokkos::View on the memory allocation.
ElementType const * data_handle() const
Access to the underlying allocation pointer.
auto allocation_kokkos_view()
Provide an unmanaged Kokkos::View on the memory allocation.
element_type const & operator()(DVects const &... dvects) const noexcept
Element access using a list of DiscreteVector.
Chunk(Chunk const &other)=delete
Deleted: use deepcopy instead.
Chunk(std::string const &label, discrete_domain_type const &domain, Allocator allocator=Allocator())
Construct a labeled Chunk on a domain with uninitialized values.
Chunk()=default
Empty Chunk.
char const * label() const
Returns the label of the Chunk.
view_type span_view() const
element_type const & operator()(DElems const &... delems) const noexcept
Element access using a list of DiscreteElement.
auto operator[](DiscreteElement< QueryDDims... > const &slice_spec)
Slice out some dimensions.
view_type span_cview() const
auto operator[](DiscreteElement< QueryDDims... > const &slice_spec) const
Slice out some dimensions.
char const * label() const
Returns the label of the Chunk.
const_allocation_mdspan_type allocation_mdspan() const
Provide a mdspan on the memory allocation.
element_type & operator()(DVects const &... dvects) noexcept
Element access using a list of DiscreteVector.
ElementType const * data_handle() const
Access to the underlying allocation pointer.
auto allocation_kokkos_view()
Provide an unmanaged Kokkos::View on the memory allocation.
auto allocation_kokkos_view() const
Provide an unmanaged Kokkos::View on the memory allocation.
Chunk(SupportType const &domain, Allocator allocator=Allocator())
Construct a Chunk on a domain with uninitialized values.
Chunk & operator=(Chunk const &other)=delete
Deleted: use deepcopy instead.
allocation_mdspan_type allocation_mdspan()
Provide a mdspan on the memory allocation.
ElementType * data_handle()
Access to the underlying allocation pointer.
element_type const & operator()(DVects const &... dvects) const noexcept
Element access using a list of DiscreteVector.
view_type span_cview() const
Chunk(Chunk const &other)=delete
Deleted: use deepcopy instead.
Chunk(std::string const &label, SupportType const &domain, Allocator allocator=Allocator())
Construct a labeled Chunk on a domain with uninitialized values.
element_type & operator()(DElems const &... delems) noexcept
Element access using a list of DiscreteElement.
Chunk()=default
Empty Chunk.
Chunk & operator=(Chunk &&other) noexcept
Move-assigns a new value to this field.
Chunk(Chunk &&other) noexcept
Constructs a new Chunk by move.
view_type span_view() const
element_type const & operator()(DElems const &... delems) const noexcept
Element access using a list of DiscreteElement.
auto operator[](DiscreteElement< QueryDDims... > const &slice_spec)
Slice out some dimensions.
friend class DiscreteDomain
The top-level namespace of DDC.
constexpr bool enable_chunk< Chunk< ElementType, SupportType, Allocator > >
Chunk(SupportType const &, Allocator) -> Chunk< typename Allocator::value_type, SupportType, Allocator >
Chunk(std::string const &, SupportType const &, Allocator) -> Chunk< typename Allocator::value_type, SupportType, Allocator >