11#include <Kokkos_Core.hpp>
13#include "ddc/chunk_common.hpp"
14#include "ddc/chunk_span.hpp"
15#include "ddc/chunk_traits.hpp"
16#include "ddc/detail/kokkos.hpp"
17#include "ddc/kokkos_allocator.hpp"
21template <
class ElementType,
class,
class Allocator = HostAllocator<ElementType>>
27template <
class ElementType,
class... DDims,
class Allocator>
35 using internal_mdspan_type =
typename base_type::internal_mdspan_type;
43 typename Allocator::memory_space>;
50 typename Allocator::memory_space>;
53 using allocation_mdspan_type =
typename base_type::allocation_mdspan_type;
55 using const_allocation_mdspan_type =
typename base_type::const_allocation_mdspan_type;
57 using discrete_domain_type =
typename base_type::discrete_domain_type;
59 using memory_space =
typename Allocator::memory_space;
61 using discrete_element_type =
typename base_type::discrete_element_type;
63 using extents_type =
typename base_type::extents_type;
65 using layout_type =
typename base_type::layout_type;
67 using mapping_type =
typename base_type::mapping_type;
69 using element_type =
typename base_type::element_type;
71 using value_type =
typename base_type::value_type;
73 using size_type =
typename base_type::size_type;
75 using data_handle_type =
typename base_type::data_handle_type;
77 using reference =
typename base_type::reference;
79 template <
class,
class,
class>
83 Allocator m_allocator;
93 std::string
const& label,
94 discrete_domain_type
const& domain,
95 Allocator allocator = Allocator())
96 : base_type(allocator.allocate(label, domain.size()), domain)
97 , m_allocator(std::move(allocator))
103 explicit Chunk(discrete_domain_type
const& domain, Allocator allocator = Allocator())
104 :
Chunk(
"no-label", domain, std::move(allocator))
112
113
115 : base_type(std::move(
static_cast<base_type&>(other)))
116 , m_allocator(std::move(other.m_allocator))
117 , m_label(std::move(other.m_label))
119 other.m_internal_mdspan = internal_mdspan_type(
nullptr, other.m_internal_mdspan.mapping());
124 if (
this->m_internal_mdspan.data_handle()) {
125 m_allocator.deallocate(
this->data_handle(),
this->size());
133
134
135
138 if (
this == &other) {
141 if (
this->m_internal_mdspan.data_handle()) {
142 m_allocator.deallocate(
this->data_handle(),
this->size());
144 static_cast<base_type&>(*
this) = std::move(
static_cast<base_type&>(other));
145 m_allocator = std::move(other.m_allocator);
146 m_label = std::move(other.m_label);
147 other.m_internal_mdspan = internal_mdspan_type(
nullptr, other.m_internal_mdspan.mapping());
153 template <
class... QueryDDims>
154 auto operator[](DiscreteElement<QueryDDims...>
const& slice_spec)
const
156 return view_type(*
this)[slice_spec];
160 template <
class... QueryDDims>
161 auto operator[](DiscreteElement<QueryDDims...>
const& slice_spec)
163 return span_view()[slice_spec];
167 template <
class... QueryDDims>
170 return span_view()[odomain];
174 template <
class... QueryDDims>
177 return span_view()[odomain];
181
182
183
184 template <
class... DElems>
185 element_type
const&
operator()(DElems
const&... delems)
const noexcept
188 sizeof...(DDims) == (0 + ... + DElems::size()),
189 "Invalid number of dimensions");
190 static_assert((is_discrete_element_v<DElems> && ...),
"Expected DiscreteElements");
191 assert(((DiscreteElement<DDims>(take<DDims>(delems...)) >= front<DDims>(
this->m_domain))
193 assert(((DiscreteElement<DDims>(take<DDims>(delems...)) <= back<DDims>(
this->m_domain))
195 return DDC_MDSPAN_ACCESS_OP(
this->m_internal_mdspan, uid<DDims>(take<DDims>(delems...))...);
199
200
201
202 template <
class... DElems>
203 element_type&
operator()(DElems
const&... delems)
noexcept
206 sizeof...(DDims) == (0 + ... + DElems::size()),
207 "Invalid number of dimensions");
208 static_assert((is_discrete_element_v<DElems> && ...),
"Expected DiscreteElements");
209 assert(((DiscreteElement<DDims>(take<DDims>(delems...)) >= front<DDims>(
this->m_domain))
211 assert(((DiscreteElement<DDims>(take<DDims>(delems...)) <= back<DDims>(
this->m_domain))
213 return DDC_MDSPAN_ACCESS_OP(
this->m_internal_mdspan, uid<DDims>(take<DDims>(delems...))...);
217
218
219 char const*
label()
const
221 return m_label.c_str();
225
226
229 return base_type::data_handle();
233
234
237 return base_type::data_handle();
241
242
245 return base_type::allocation_mdspan();
249
250
253 return base_type::allocation_mdspan();
257
258
261 auto s =
this->allocation_mdspan();
262 auto kokkos_layout = detail::build_kokkos_layout(
265 std::make_index_sequence<
sizeof...(DDims)> {});
267 detail::mdspan_to_kokkos_element_t<ElementType,
sizeof...(DDims)>,
268 decltype(kokkos_layout),
269 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
273
274
277 auto s =
this->allocation_mdspan();
278 auto kokkos_layout = detail::build_kokkos_layout(
281 std::make_index_sequence<
sizeof...(DDims)> {});
283 detail::mdspan_to_kokkos_element_t<
const ElementType,
sizeof...(DDims)>,
284 decltype(kokkos_layout),
285 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
290 return view_type(*
this);
295 return view_type(*
this);
300 return span_type(*
this);
304template <
class ElementType,
class SupportType,
class Allocator>
305class Chunk :
public ChunkCommon<ElementType, SupportType, Kokkos::layout_right>
308 using base_type =
ChunkCommon<ElementType, SupportType, Kokkos::layout_right>;
315 Kokkos::layout_right,
316 typename Allocator::memory_space>;
322 Kokkos::layout_right,
323 typename Allocator::memory_space>;
326 using allocation_mdspan_type =
typename base_type::allocation_mdspan_type;
328 using const_allocation_mdspan_type =
typename base_type::const_allocation_mdspan_type;
330 using discrete_domain_type =
typename base_type::discrete_domain_type;
332 using memory_space =
typename Allocator::memory_space;
334 using discrete_element_type =
typename base_type::discrete_element_type;
336 using extents_type =
typename base_type::extents_type;
338 using layout_type =
typename base_type::layout_type;
340 using mapping_type =
typename base_type::mapping_type;
342 using element_type =
typename base_type::element_type;
344 using value_type =
typename base_type::value_type;
346 using size_type =
typename base_type::size_type;
348 using data_handle_type =
typename base_type::data_handle_type;
350 using reference =
typename base_type::reference;
352 template <
class,
class,
class>
356 Allocator m_allocator;
366 std::string
const& label,
367 SupportType
const& domain,
368 Allocator allocator = Allocator())
369 : base_type(allocator.allocate(label, domain.size()), domain)
370 , m_allocator(std::move(allocator))
376 explicit Chunk(SupportType
const& domain, Allocator allocator = Allocator())
377 :
Chunk(
"no-label", domain, std::move(allocator))
385
386
388 : base_type(std::move(
static_cast<base_type&>(other)))
389 , m_allocator(std::move(other.m_allocator))
390 , m_label(std::move(other.m_label))
392 other.m_allocation_mdspan
393 = allocation_mdspan_type(
nullptr, other.m_allocation_mdspan.mapping());
398 if (
this->m_allocation_mdspan.data_handle()) {
399 m_allocator.deallocate(
this->data_handle(),
this->size());
407
408
409
412 if (
this == &other) {
415 if (
this->m_allocation_mdspan.data_handle()) {
416 m_allocator.deallocate(
this->data_handle(),
this->size());
418 static_cast<base_type&>(*
this) = std::move(
static_cast<base_type&>(other));
419 m_allocator = std::move(other.m_allocator);
420 m_label = std::move(other.m_label);
421 other.m_allocation_mdspan
422 = allocation_mdspan_type(
nullptr, other.m_allocation_mdspan.mapping());
428 template <
class... QueryDDims>
429 auto operator[](DiscreteElement<QueryDDims...>
const& slice_spec)
const
431 return view_type(*
this)[slice_spec];
435 template <
class... QueryDDims>
436 auto operator[](DiscreteElement<QueryDDims...>
const& slice_spec)
438 return span_view()[slice_spec];
442
443
444
445 template <
class... DElems>
446 element_type
const&
operator()(DElems
const&... delems)
const noexcept
449 SupportType::rank() == (0 + ... + DElems::size()),
450 "Invalid number of dimensions");
451 static_assert((is_discrete_element_v<DElems> && ...),
"Expected DiscreteElements");
452 assert(
this->m_domain.contains(delems...));
453 return DDC_MDSPAN_ACCESS_OP(
454 this->m_allocation_mdspan,
455 detail::array(
this->m_domain.distance_from_front(delems...)));
459
460
461
462 template <
class... DElems>
463 element_type&
operator()(DElems
const&... delems)
noexcept
466 SupportType::rank() == (0 + ... + DElems::size()),
467 "Invalid number of dimensions");
468 static_assert((is_discrete_element_v<DElems> && ...),
"Expected DiscreteElements");
469 assert(
this->m_domain.contains(delems...));
470 return DDC_MDSPAN_ACCESS_OP(
471 this->m_allocation_mdspan,
472 detail::array(
this->m_domain.distance_from_front(delems...)));
476
477
478 char const*
label()
const
480 return m_label.c_str();
484
485
488 return base_type::data_handle();
492
493
496 return base_type::data_handle();
500
501
504 return base_type::allocation_mdspan();
508
509
512 return base_type::allocation_mdspan();
516
517
520 auto s =
this->allocation_mdspan();
521 auto kokkos_layout = detail::build_kokkos_layout(
524 std::make_index_sequence<SupportType::rank()> {});
526 detail::mdspan_to_kokkos_element_t<ElementType, SupportType::rank()>,
527 decltype(kokkos_layout),
528 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
532
533
536 auto s =
this->allocation_mdspan();
537 auto kokkos_layout = detail::build_kokkos_layout(
540 std::make_index_sequence<SupportType::rank()> {});
542 detail::mdspan_to_kokkos_element_t<
const ElementType, SupportType::rank()>,
543 decltype(kokkos_layout),
544 typename Allocator::memory_space>(s.data_handle(), kokkos_layout);
549 return view_type(*
this);
554 return view_type(*
this);
559 return span_type(*
this);
563template <
class SupportType,
class Allocator>
564Chunk(std::string
const&,
566 Allocator) ->
Chunk<
typename Allocator::
value_type, SupportType, Allocator>;
568template <
class SupportType,
class Allocator>
569Chunk(SupportType
const&,
570 Allocator) ->
Chunk<
typename Allocator::
value_type, SupportType, 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.
element_type const & operator()(DElems const &... delems) const noexcept
Element access using a list of DiscreteElement.
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.
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.
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.
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
auto operator[](DiscreteElement< QueryDDims... > const &slice_spec)
Slice out some dimensions.
view_type span_cview() const
element_type & operator()(DElems const &... delems) noexcept
Element access using a list of DiscreteElement.
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.
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.
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 >