17#ifndef KOKKOS_DYNAMIC_VIEW_HPP
18#define KOKKOS_DYNAMIC_VIEW_HPP
19#ifndef KOKKOS_IMPL_PUBLIC_INCLUDE
20#define KOKKOS_IMPL_PUBLIC_INCLUDE
21#define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_DYNAMICVIEW
26#include <Kokkos_Core.hpp>
27#include <impl/Kokkos_Error.hpp>
30namespace Experimental {
37template <
typename MemorySpace,
typename ValueType>
38struct ChunkedArrayManager {
39 using value_type = ValueType;
40 using pointer_type = ValueType*;
41 using track_type = Kokkos::Impl::SharedAllocationTracker;
43 ChunkedArrayManager() =
default;
44 ChunkedArrayManager(ChunkedArrayManager
const&) =
default;
45 ChunkedArrayManager(ChunkedArrayManager&&) =
default;
46 ChunkedArrayManager& operator=(ChunkedArrayManager&&) =
default;
47 ChunkedArrayManager& operator=(
const ChunkedArrayManager&) =
default;
49 template <
typename Space,
typename Value>
50 friend struct ChunkedArrayManager;
52 template <
typename Space,
typename Value>
53 inline ChunkedArrayManager(
const ChunkedArrayManager<Space, Value>& rhs)
54 : m_valid(rhs.m_valid),
55 m_chunk_max(rhs.m_chunk_max),
56 m_chunks((ValueType**)(rhs.m_chunks)),
58 m_chunk_size(rhs.m_chunk_size) {
60 Kokkos::Impl::MemorySpaceAccess<MemorySpace, Space>::assignable,
61 "Incompatible ChunkedArrayManager copy construction");
64 ChunkedArrayManager(
const unsigned arg_chunk_max,
65 const unsigned arg_chunk_size)
66 : m_chunk_max(arg_chunk_max), m_chunk_size(arg_chunk_size) {}
69 struct ACCESSIBLE_TAG {};
70 struct INACCESSIBLE_TAG {};
72 ChunkedArrayManager(ACCESSIBLE_TAG, pointer_type* arg_chunks,
73 const unsigned arg_chunk_max)
74 : m_valid(
true), m_chunk_max(arg_chunk_max), m_chunks(arg_chunks) {}
76 ChunkedArrayManager(INACCESSIBLE_TAG,
const unsigned arg_chunk_max,
77 const unsigned arg_chunk_size)
78 : m_chunk_max(arg_chunk_max), m_chunk_size(arg_chunk_size) {}
81 template <
typename Space,
typename Enable_ =
void>
82 struct IsAccessibleFrom;
84 template <
typename Space>
85 struct IsAccessibleFrom<
86 Space, typename std::enable_if_t<Kokkos::Impl::MemorySpaceAccess<
87 MemorySpace, Space>::accessible>> : std::true_type {};
89 template <
typename Space>
90 struct IsAccessibleFrom<
91 Space, typename std::enable_if_t<!Kokkos::Impl::MemorySpaceAccess<
92 MemorySpace, Space>::accessible>> : std::false_type {};
94 template <
typename Space>
95 static ChunkedArrayManager<Space, ValueType> create_mirror(
96 ChunkedArrayManager<MemorySpace, ValueType>
const& other,
97 std::enable_if_t<IsAccessibleFrom<Space>::value>* =
nullptr) {
98 return ChunkedArrayManager<Space, ValueType>{
99 ACCESSIBLE_TAG{}, other.m_chunks, other.m_chunk_max};
102 template <
typename Space>
103 static ChunkedArrayManager<Space, ValueType> create_mirror(
104 ChunkedArrayManager<MemorySpace, ValueType>
const& other,
105 std::enable_if_t<!IsAccessibleFrom<Space>::value>* =
nullptr) {
107 typename ChunkedArrayManager<Space, ValueType>::INACCESSIBLE_TAG;
108 return ChunkedArrayManager<Space, ValueType>{tag_type{}, other.m_chunk_max,
113 void allocate_device(
const std::string& label) {
114 if (m_chunks ==
nullptr) {
115 m_chunks =
reinterpret_cast<pointer_type*
>(MemorySpace().allocate(
116 label.c_str(), (
sizeof(pointer_type) * (m_chunk_max + 2))));
121 for (
unsigned i = 0; i < m_chunk_max + 2; i++) {
122 m_chunks[i] =
nullptr;
130 template <
typename Space>
133 Destroy(Destroy&&) =
default;
134 Destroy(
const Destroy&) =
default;
135 Destroy& operator=(Destroy&&) =
default;
136 Destroy& operator=(
const Destroy&) =
default;
138 Destroy(std::string label, value_type** arg_chunk,
139 const unsigned arg_chunk_max,
const unsigned arg_chunk_size,
140 value_type** arg_linked)
143 m_linked(arg_linked),
144 m_chunk_max(arg_chunk_max),
145 m_chunk_size(arg_chunk_size) {}
150 uintptr_t
const len =
151 *
reinterpret_cast<uintptr_t*
>(m_chunks + m_chunk_max);
152 for (
unsigned i = 0; i < len; i++) {
153 Space().deallocate(m_label.c_str(), m_chunks[i],
154 sizeof(value_type) * m_chunk_size);
157 if (m_linked !=
nullptr) {
158 Space().deallocate(m_label.c_str(), m_linked,
159 (
sizeof(value_type*) * (m_chunk_max + 2)));
163 void destroy_shared_allocation() { execute(); }
166 value_type** m_chunks =
nullptr;
167 value_type** m_linked =
nullptr;
168 unsigned m_chunk_max;
169 unsigned m_chunk_size;
173 template <
typename Space>
174 void allocate_with_destroy(
const std::string& label,
175 pointer_type* linked_allocation =
nullptr) {
176 using destroy_type = Destroy<Space>;
178 Kokkos::Impl::SharedAllocationRecord<MemorySpace, destroy_type>;
183 record_type*
const record = record_type::allocate(
184 MemorySpace(), label, (
sizeof(pointer_type) * (m_chunk_max + 2)));
185 m_chunks =
static_cast<pointer_type*
>(record->data());
186 m_track.assign_allocated_record_to_uninitialized(record);
188 record->m_destroy = destroy_type(label, m_chunks, m_chunk_max, m_chunk_size,
192 pointer_type* get_ptr()
const {
return m_chunks; }
194 template <
typename OtherMemorySpace,
typename ExecutionSpace>
196 const ExecutionSpace& exec_space,
197 ChunkedArrayManager<OtherMemorySpace, ValueType>
const& other)
const {
198 if (other.m_chunks != m_chunks) {
199 Kokkos::Impl::DeepCopy<OtherMemorySpace, MemorySpace, ExecutionSpace>(
200 exec_space, other.m_chunks, m_chunks,
201 sizeof(pointer_type) * (m_chunk_max + 2));
205 KOKKOS_INLINE_FUNCTION
206 pointer_type* operator+(
int i)
const {
return m_chunks + i; }
208 KOKKOS_INLINE_FUNCTION
209 pointer_type& operator[](
int i)
const {
return m_chunks[i]; }
211 track_type
const& track()
const {
return m_track; }
213 KOKKOS_INLINE_FUNCTION
214 bool valid()
const {
return m_valid; }
217 bool m_valid =
false;
218 unsigned m_chunk_max = 0;
219 pointer_type* m_chunks =
nullptr;
221 unsigned m_chunk_size = 0;
230template <
typename DataType,
typename... P>
235 using value_type =
typename traits::value_type;
236 using device_space =
typename traits::memory_space;
238 typename Kokkos::Impl::HostMirror<device_space>::Space::memory_space;
243 template <
class,
class...>
244 friend class DynamicView;
246 using track_type = Kokkos::Impl::SharedAllocationTracker;
248 static_assert(traits::rank == 1 && traits::rank_dynamic == 1,
249 "DynamicView must be rank-one");
253 static_assert(std::is_void<typename traits::specialize>::value,
254 "DynamicView only implemented for non-specialized View type");
257 device_accessor m_chunks;
258 host_accessor m_chunks_host;
259 unsigned m_chunk_shift;
260 unsigned m_chunk_mask;
261 unsigned m_chunk_max;
263 unsigned m_chunk_size;
270 DynamicView<typename traits::data_type, typename traits::device_type>;
273 using const_type = DynamicView<
typename traits::const_data_type,
274 typename traits::device_type>;
278 typename traits::device_type>;
285 Kokkos::Device<
typename traits::device_type::execution_space,
286 Kokkos::AnonymousSpace>;
290 using uniform_runtime_const_type =
const_type;
291 using uniform_nomemspace_type =
292 DynamicView<typename traits::data_type, uniform_device>;
293 using uniform_const_nomemspace_type =
294 DynamicView<typename traits::const_data_type, uniform_device>;
295 using uniform_runtime_nomemspace_type =
296 DynamicView<typename traits::data_type, uniform_device>;
297 using uniform_runtime_const_nomemspace_type =
298 DynamicView<typename traits::const_data_type, uniform_device>;
304 KOKKOS_INLINE_FUNCTION
305 size_t allocation_extent() const noexcept {
307 *
reinterpret_cast<const uintptr_t*
>(m_chunks_host + m_chunk_max);
308 return (n << m_chunk_shift);
311 KOKKOS_INLINE_FUNCTION
312 size_t chunk_size() const noexcept {
return m_chunk_size; }
314 KOKKOS_INLINE_FUNCTION
315 size_t chunk_max() const noexcept {
return m_chunk_max; }
317 KOKKOS_INLINE_FUNCTION
318 size_t size() const noexcept {
320 *
reinterpret_cast<const size_t*
>(m_chunks_host + m_chunk_max + 1);
324 template <
typename iType>
325 KOKKOS_INLINE_FUNCTION
size_t extent(
const iType& r)
const {
326 return r == 0 ? size() : 1;
329 template <
typename iType>
330 KOKKOS_INLINE_FUNCTION
size_t extent_int(
const iType& r)
const {
331 return r == 0 ? size() : 1;
334 KOKKOS_INLINE_FUNCTION
constexpr size_t stride_0()
const {
return 0; }
335 KOKKOS_INLINE_FUNCTION
constexpr size_t stride_1()
const {
return 0; }
336 KOKKOS_INLINE_FUNCTION
constexpr size_t stride_2()
const {
return 0; }
337 KOKKOS_INLINE_FUNCTION
constexpr size_t stride_3()
const {
return 0; }
338 KOKKOS_INLINE_FUNCTION
constexpr size_t stride_4()
const {
return 0; }
339 KOKKOS_INLINE_FUNCTION
constexpr size_t stride_5()
const {
return 0; }
340 KOKKOS_INLINE_FUNCTION
constexpr size_t stride_6()
const {
return 0; }
341 KOKKOS_INLINE_FUNCTION
constexpr size_t stride_7()
const {
return 0; }
343 template <
typename iType>
344 KOKKOS_INLINE_FUNCTION
void stride(iType*
const s)
const {
351 KOKKOS_INLINE_FUNCTION
352 int use_count()
const {
return m_chunks_host.track().use_count(); }
354 inline const std::string label()
const {
355 return m_chunks_host.track().template get_label<host_space>();
361 using reference_type =
typename traits::value_type&;
362 using pointer_type =
typename traits::value_type*;
365 reference_type_is_lvalue_reference =
366 std::is_lvalue_reference<reference_type>::value
369 KOKKOS_INLINE_FUNCTION
constexpr bool span_is_contiguous()
const {
372 KOKKOS_INLINE_FUNCTION
constexpr size_t span()
const {
return 0; }
373 KOKKOS_INLINE_FUNCTION
constexpr pointer_type data()
const {
return 0; }
377 template <
typename I0,
class... Args>
378 KOKKOS_INLINE_FUNCTION reference_type
379 operator()(
const I0& i0,
const Args&... )
const {
380 static_assert(Kokkos::Impl::are_integral<I0, Args...>::value,
381 "Indices must be integral type");
383 Kokkos::Impl::runtime_check_memory_access_violation<
384 typename traits::memory_space>(
385 "Kokkos::DynamicView ERROR: attempt to access inaccessible memory "
389 const uintptr_t ic = uintptr_t(i0) >> m_chunk_shift;
391#if defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
392 const uintptr_t n = *
reinterpret_cast<uintptr_t*
>(m_chunks + m_chunk_max);
393 if (n <= ic) Kokkos::abort(
"Kokkos::DynamicView array bounds error");
396 typename traits::value_type**
const ch = m_chunks + ic;
397 return (*ch)[i0 & m_chunk_mask];
404 template <
typename IntType>
406 using local_value_type =
typename traits::value_type;
407 using value_pointer_type = local_value_type*;
410 (n + m_chunk_mask) >>
413 if (m_chunk_max < NC) {
414 Kokkos::abort(
"DynamicView::resize_serial exceeded maximum size");
418 uintptr_t*
const pc =
419 reinterpret_cast<uintptr_t*
>(m_chunks_host + m_chunk_max);
420 std::string _label = m_chunks_host.track().template get_label<host_space>();
425 reinterpret_cast<value_pointer_type
>(device_space().allocate(
426 _label.c_str(),
sizeof(local_value_type) << m_chunk_shift));
430 while (NC + 1 <= *pc) {
432 device_space().deallocate(_label.c_str(), m_chunks_host[*pc],
433 sizeof(local_value_type) << m_chunk_shift);
434 m_chunks_host[*pc] =
nullptr;
440 typename device_space::execution_space exec{};
441 m_chunks_host.deep_copy_to(exec, m_chunks);
443 "DynamicView::resize_serial: Fence after copying chunks to the device");
446 KOKKOS_INLINE_FUNCTION
bool is_allocated()
const {
447 if (m_chunks_host.valid()) {
450 uintptr_t*
const pc =
451 reinterpret_cast<uintptr_t*
>(m_chunks_host + m_chunk_max);
452 return (*(pc + 1) > 0);
458 KOKKOS_FUNCTION
const device_accessor& impl_get_chunks()
const {
462 KOKKOS_FUNCTION device_accessor& impl_get_chunks() {
return m_chunks; }
466 ~DynamicView() =
default;
467 DynamicView() =
default;
468 DynamicView(DynamicView&&) =
default;
469 DynamicView(
const DynamicView&) =
default;
470 DynamicView& operator=(DynamicView&&) =
default;
471 DynamicView& operator=(
const DynamicView&) =
default;
473 template <
class RT,
class... RP>
474 DynamicView(
const DynamicView<RT, RP...>& rhs)
475 : m_chunks(rhs.m_chunks),
476 m_chunks_host(rhs.m_chunks_host),
477 m_chunk_shift(rhs.m_chunk_shift),
478 m_chunk_mask(rhs.m_chunk_mask),
479 m_chunk_max(rhs.m_chunk_max),
480 m_chunk_size(rhs.m_chunk_size) {
481 using SrcTraits =
typename DynamicView<RT, RP...>::traits;
482 using Mapping = Kokkos::Impl::ViewMapping<traits, SrcTraits, void>;
483 static_assert(Mapping::is_assignable,
484 "Incompatible DynamicView copy construction");
493 template <
class... Prop>
495 const unsigned min_chunk_size,
496 const unsigned max_extent)
498 m_chunk_shift(Kokkos::Impl::integral_power_of_two_that_contains(
501 m_chunk_mask((1 << m_chunk_shift) - 1)
503 m_chunk_max((max_extent + m_chunk_mask) >>
506 m_chunk_size(2 << (m_chunk_shift - 1)) {
507 m_chunks = device_accessor(m_chunk_max, m_chunk_size);
509 const std::string& label =
510 Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(arg_prop);
512 if (device_accessor::template IsAccessibleFrom<host_space>::value) {
513 m_chunks.template allocate_with_destroy<device_space>(label);
514 m_chunks.initialize();
516 device_accessor::template create_mirror<host_space>(m_chunks);
518 m_chunks.allocate_device(label);
520 device_accessor::template create_mirror<host_space>(m_chunks);
521 m_chunks_host.template allocate_with_destroy<device_space>(
522 label, m_chunks.get_ptr());
523 m_chunks_host.initialize();
525 using alloc_prop_input = Kokkos::Impl::ViewCtorProp<Prop...>;
527 auto arg_prop_copy = ::Kokkos::Impl::with_properties_if_unset(
528 arg_prop,
typename device_space::execution_space{});
531 Kokkos::Impl::get_property<Kokkos::Impl::ExecutionSpaceTag>(
533 m_chunks_host.deep_copy_to(exec, m_chunks);
534 if (!alloc_prop_input::has_execution_space)
536 "DynamicView::DynamicView(): Fence after copying chunks to the "
541 DynamicView(
const std::string& arg_label,
const unsigned min_chunk_size,
542 const unsigned max_extent)
543 :
DynamicView(Kokkos::view_alloc(arg_label), min_chunk_size, max_extent) {
550struct is_dynamic_view :
public std::false_type {};
552template <
class D,
class... P>
554 :
public std::true_type {};
557inline constexpr bool is_dynamic_view_v = is_dynamic_view<T>::value;
566template <
class Space,
class T,
class... P>
567struct MirrorDynamicViewType {
569 using src_view_type =
typename Kokkos::Experimental::DynamicView<T, P...>;
571 using memory_space =
typename Space::memory_space;
575 std::is_same<memory_space, typename src_view_type::memory_space>::value
578 using array_layout =
typename src_view_type::array_layout;
581 using data_type =
typename src_view_type::non_const_data_type;
583 using dest_view_type =
584 Kokkos::Experimental::DynamicView<data_type, array_layout, Space>;
588 std::conditional_t<is_same_memspace, src_view_type, dest_view_type>;
593template <
class T,
class... P,
class... ViewCtorArgs>
594inline auto create_mirror(
595 const Kokkos::Experimental::DynamicView<T, P...>& src,
596 const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
597 std::enable_if_t<!Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space>* =
599 using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
602 !alloc_prop_input::has_label,
603 "The view constructor arguments passed to Kokkos::create_mirror "
604 "must not include a label!");
606 !alloc_prop_input::has_pointer,
607 "The view constructor arguments passed to Kokkos::create_mirror must "
608 "not include a pointer!");
610 !alloc_prop_input::allow_padding,
611 "The view constructor arguments passed to Kokkos::create_mirror must "
612 "not explicitly allow padding!");
614 auto prop_copy = Impl::with_properties_if_unset(
615 arg_prop, std::string(src.label()).append(
"_mirror"));
618 prop_copy, src.chunk_size(), src.chunk_max() * src.chunk_size());
620 ret.resize_serial(src.extent(0));
625template <
class T,
class... P,
class... ViewCtorArgs>
626inline auto create_mirror(
627 const Kokkos::Experimental::DynamicView<T, P...>& src,
628 const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
629 std::enable_if_t<Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space>* =
631 using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
634 !alloc_prop_input::has_label,
635 "The view constructor arguments passed to Kokkos::create_mirror "
636 "must not include a label!");
638 !alloc_prop_input::has_pointer,
639 "The view constructor arguments passed to Kokkos::create_mirror must "
640 "not include a pointer!");
642 !alloc_prop_input::allow_padding,
643 "The view constructor arguments passed to Kokkos::create_mirror must "
644 "not explicitly allow padding!");
646 using MemorySpace =
typename alloc_prop_input::memory_space;
647 auto prop_copy = Impl::with_properties_if_unset(
648 arg_prop, std::string(src.label()).append(
"_mirror"));
650 auto ret =
typename Kokkos::Impl::MirrorDynamicViewType<
651 MemorySpace, T, P...>::view_type(prop_copy, src.chunk_size(),
652 src.chunk_max() * src.chunk_size());
654 ret.resize_serial(src.extent(0));
661template <
class T,
class... P>
662inline auto create_mirror(
663 const Kokkos::Experimental::DynamicView<T, P...>& src) {
664 return Impl::create_mirror(src, Impl::ViewCtorProp<>{});
667template <
class T,
class... P>
668inline auto create_mirror(
669 Kokkos::Impl::WithoutInitializing_t wi,
670 const Kokkos::Experimental::DynamicView<T, P...>& src) {
671 return Impl::create_mirror(src, Kokkos::view_alloc(wi));
675template <
class Space,
class T,
class... P>
676inline auto create_mirror(
677 const Space&,
const Kokkos::Experimental::DynamicView<T, P...>& src) {
678 return Impl::create_mirror(
679 src, Kokkos::view_alloc(
typename Space::memory_space{}));
682template <
class Space,
class T,
class... P>
683typename Kokkos::Impl::MirrorDynamicViewType<Space, T, P...>::view_type
684create_mirror(Kokkos::Impl::WithoutInitializing_t wi,
const Space&,
685 const Kokkos::Experimental::DynamicView<T, P...>& src) {
686 return Impl::create_mirror(
687 src, Kokkos::view_alloc(wi,
typename Space::memory_space{}));
690template <
class T,
class... P,
class... ViewCtorArgs>
691inline auto create_mirror(
692 const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
693 const Kokkos::Experimental::DynamicView<T, P...>& src) {
694 return Impl::create_mirror(src, arg_prop);
699template <
class T,
class... P,
class... ViewCtorArgs>
700inline std::enable_if_t<
701 !Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space &&
703 typename Kokkos::Experimental::DynamicView<T, P...>::memory_space,
704 typename Kokkos::Experimental::DynamicView<
705 T, P...>::HostMirror::memory_space>::value &&
707 typename Kokkos::Experimental::DynamicView<T, P...>::data_type,
708 typename Kokkos::Experimental::DynamicView<
709 T, P...>::HostMirror::data_type>::value),
711create_mirror_view(
const Kokkos::Experimental::DynamicView<T, P...>& src,
712 const Impl::ViewCtorProp<ViewCtorArgs...>&) {
716template <
class T,
class... P,
class... ViewCtorArgs>
717inline std::enable_if_t<
718 !Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space &&
720 typename Kokkos::Experimental::DynamicView<T, P...>::memory_space,
721 typename Kokkos::Experimental::DynamicView<
722 T, P...>::HostMirror::memory_space>::value &&
724 typename Kokkos::Experimental::DynamicView<T, P...>::data_type,
725 typename Kokkos::Experimental::DynamicView<
726 T, P...>::HostMirror::data_type>::value),
728create_mirror_view(
const Kokkos::Experimental::DynamicView<T, P...>& src,
729 const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
730 return Kokkos::create_mirror(arg_prop, src);
733template <
class T,
class... P,
class... ViewCtorArgs,
734 class = std::enable_if_t<
735 Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space>>
736std::enable_if_t<Impl::MirrorDynamicViewType<
737 typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space,
738 T, P...>::is_same_memspace,
739 typename Impl::MirrorDynamicViewType<
740 typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space,
742create_mirror_view(
const Kokkos::Experimental::DynamicView<T, P...>& src,
743 const Impl::ViewCtorProp<ViewCtorArgs...>&) {
747template <
class T,
class... P,
class... ViewCtorArgs,
748 class = std::enable_if_t<
749 Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space>>
750std::enable_if_t<!Impl::MirrorDynamicViewType<
751 typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space,
752 T, P...>::is_same_memspace,
753 typename Impl::MirrorDynamicViewType<
754 typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space,
756create_mirror_view(
const Kokkos::Experimental::DynamicView<T, P...>& src,
757 const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
758 return Kokkos::Impl::create_mirror(src, arg_prop);
763template <
class T,
class... P>
764inline auto create_mirror_view(
765 const typename Kokkos::Experimental::DynamicView<T, P...>& src) {
766 return Impl::create_mirror_view(src, Impl::ViewCtorProp<>{});
769template <
class T,
class... P>
770inline auto create_mirror_view(
771 Kokkos::Impl::WithoutInitializing_t wi,
772 const typename Kokkos::Experimental::DynamicView<T, P...>& src) {
773 return Impl::create_mirror_view(src, Kokkos::view_alloc(wi));
777template <
class Space,
class T,
class... P>
778inline auto create_mirror_view(
779 const Space&,
const Kokkos::Experimental::DynamicView<T, P...>& src) {
780 return Impl::create_mirror_view(src,
781 view_alloc(
typename Space::memory_space{}));
784template <
class Space,
class T,
class... P>
785inline auto create_mirror_view(
786 Kokkos::Impl::WithoutInitializing_t wi,
const Space&,
787 const Kokkos::Experimental::DynamicView<T, P...>& src) {
788 return Impl::create_mirror_view(
789 src, Kokkos::view_alloc(wi,
typename Space::memory_space{}));
792template <
class T,
class... P,
class... ViewCtorArgs>
793inline auto create_mirror_view(
794 const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
795 const Kokkos::Experimental::DynamicView<T, P...>& src) {
796 return Impl::create_mirror_view(src, arg_prop);
799template <
class T,
class... DP,
class... SP>
800inline void deep_copy(
const Kokkos::Experimental::DynamicView<T, DP...>& dst,
801 const Kokkos::Experimental::DynamicView<T, SP...>& src) {
802 using dst_type = Kokkos::Experimental::DynamicView<T, DP...>;
803 using src_type = Kokkos::Experimental::DynamicView<T, SP...>;
805 using dst_execution_space =
typename ViewTraits<T, DP...>::execution_space;
806 using src_execution_space =
typename ViewTraits<T, SP...>::execution_space;
807 using dst_memory_space =
typename ViewTraits<T, DP...>::memory_space;
808 using src_memory_space =
typename ViewTraits<T, SP...>::memory_space;
810 constexpr bool DstExecCanAccessSrc =
811 Kokkos::SpaceAccessibility<dst_execution_space,
812 src_memory_space>::accessible;
813 constexpr bool SrcExecCanAccessDst =
814 Kokkos::SpaceAccessibility<src_execution_space,
815 dst_memory_space>::accessible;
817 if (DstExecCanAccessSrc)
818 Kokkos::Impl::ViewRemap<dst_type, src_type, dst_execution_space>(dst, src);
819 else if (SrcExecCanAccessDst)
820 Kokkos::Impl::ViewRemap<dst_type, src_type, src_execution_space>(dst, src);
822 src.impl_get_chunks().deep_copy_to(dst_execution_space{},
823 dst.impl_get_chunks());
824 Kokkos::fence(
"Kokkos::deep_copy(DynamicView)");
827template <
class ExecutionSpace,
class T,
class... DP,
class... SP>
828inline void deep_copy(
const ExecutionSpace& exec,
829 const Kokkos::Experimental::DynamicView<T, DP...>& dst,
830 const Kokkos::Experimental::DynamicView<T, SP...>& src) {
831 using dst_type = Kokkos::Experimental::DynamicView<T, DP...>;
832 using src_type = Kokkos::Experimental::DynamicView<T, SP...>;
834 using dst_execution_space =
typename ViewTraits<T, DP...>::execution_space;
835 using src_execution_space =
typename ViewTraits<T, SP...>::execution_space;
836 using dst_memory_space =
typename ViewTraits<T, DP...>::memory_space;
837 using src_memory_space =
typename ViewTraits<T, SP...>::memory_space;
839 constexpr bool DstExecCanAccessSrc =
840 Kokkos::SpaceAccessibility<dst_execution_space,
841 src_memory_space>::accessible;
842 constexpr bool SrcExecCanAccessDst =
843 Kokkos::SpaceAccessibility<src_execution_space,
844 dst_memory_space>::accessible;
847 if (DstExecCanAccessSrc)
848 Kokkos::Impl::ViewRemap<dst_type, src_type, dst_execution_space>(dst, src);
849 else if (SrcExecCanAccessDst)
850 Kokkos::Impl::ViewRemap<dst_type, src_type, src_execution_space>(dst, src);
852 src.impl_get_chunks().deep_copy_to(exec, dst.impl_get_chunks());
855template <
class T,
class... DP,
class... SP>
857 const Kokkos::Experimental::DynamicView<T, SP...>& src) {
858 using dst_type =
View<T, DP...>;
859 using src_type = Kokkos::Experimental::DynamicView<T, SP...>;
861 using dst_execution_space =
typename ViewTraits<T, DP...>::execution_space;
862 using src_memory_space =
typename ViewTraits<T, SP...>::memory_space;
865 DstExecCanAccessSrc =
866 Kokkos::SpaceAccessibility<dst_execution_space,
867 src_memory_space>::accessible
870 if (DstExecCanAccessSrc) {
873 Kokkos::Impl::ViewRemap<dst_type, src_type>(dst, src);
874 Kokkos::fence(
"Kokkos::deep_copy(DynamicView)");
876 Kokkos::Impl::throw_runtime_exception(
877 "deep_copy given views that would require a temporary allocation");
881template <
class T,
class... DP,
class... SP>
882inline void deep_copy(
const Kokkos::Experimental::DynamicView<T, DP...>& dst,
884 using dst_type = Kokkos::Experimental::DynamicView<T, DP...>;
885 using src_type =
View<T, SP...>;
887 using dst_execution_space =
typename ViewTraits<T, DP...>::execution_space;
888 using src_memory_space =
typename ViewTraits<T, SP...>::memory_space;
891 DstExecCanAccessSrc =
892 Kokkos::SpaceAccessibility<dst_execution_space,
893 src_memory_space>::accessible
896 if (DstExecCanAccessSrc) {
899 Kokkos::Impl::ViewRemap<dst_type, src_type>(dst, src);
900 Kokkos::fence(
"Kokkos::deep_copy(DynamicView)");
902 Kokkos::Impl::throw_runtime_exception(
903 "deep_copy given views that would require a temporary allocation");
908template <
class Arg0,
class... DP,
class... SP>
909struct CommonSubview<Kokkos::Experimental::DynamicView<DP...>,
910 Kokkos::Experimental::DynamicView<SP...>, 1, Arg0> {
911 using DstType = Kokkos::Experimental::DynamicView<DP...>;
912 using SrcType = Kokkos::Experimental::DynamicView<SP...>;
913 using dst_subview_type = DstType;
914 using src_subview_type = SrcType;
915 dst_subview_type dst_sub;
916 src_subview_type src_sub;
917 CommonSubview(
const DstType& dst,
const SrcType& src,
const Arg0& )
918 : dst_sub(dst), src_sub(src) {}
921template <
class... DP,
class SrcType,
class Arg0>
922struct CommonSubview<Kokkos::Experimental::DynamicView<DP...>, SrcType, 1,
924 using DstType = Kokkos::Experimental::DynamicView<DP...>;
925 using dst_subview_type = DstType;
926 using src_subview_type =
typename Kokkos::Subview<SrcType, Arg0>;
927 dst_subview_type dst_sub;
928 src_subview_type src_sub;
929 CommonSubview(
const DstType& dst,
const SrcType& src,
const Arg0& arg0)
930 : dst_sub(dst), src_sub(src, arg0) {}
933template <
class DstType,
class... SP,
class Arg0>
934struct CommonSubview<DstType, Kokkos::Experimental::DynamicView<SP...>, 1,
936 using SrcType = Kokkos::Experimental::DynamicView<SP...>;
937 using dst_subview_type =
typename Kokkos::Subview<DstType, Arg0>;
938 using src_subview_type = SrcType;
939 dst_subview_type dst_sub;
940 src_subview_type src_sub;
941 CommonSubview(
const DstType& dst,
const SrcType& src,
const Arg0& arg0)
942 : dst_sub(dst, arg0), src_sub(src) {}
945template <
class... DP,
class ViewTypeB,
class Layout,
class ExecSpace,
947struct ViewCopy<Kokkos::Experimental::DynamicView<DP...>, ViewTypeB, Layout,
948 ExecSpace, 1, iType> {
949 Kokkos::Experimental::DynamicView<DP...> a;
952 using policy_type = Kokkos::RangePolicy<ExecSpace, Kokkos::IndexType<iType>>;
954 ViewCopy(
const Kokkos::Experimental::DynamicView<DP...>& a_,
957 Kokkos::parallel_for(
"Kokkos::ViewCopy-1D", policy_type(0, b.extent(0)),
961 KOKKOS_INLINE_FUNCTION
962 void operator()(
const iType& i0)
const { a(i0) = b(i0); };
965template <
class... DP,
class... SP,
class Layout,
class ExecSpace,
967struct ViewCopy<Kokkos::Experimental::DynamicView<DP...>,
968 Kokkos::Experimental::DynamicView<SP...>, Layout, ExecSpace, 1,
970 Kokkos::Experimental::DynamicView<DP...> a;
971 Kokkos::Experimental::DynamicView<SP...> b;
973 using policy_type = Kokkos::RangePolicy<ExecSpace, Kokkos::IndexType<iType>>;
975 ViewCopy(
const Kokkos::Experimental::DynamicView<DP...>& a_,
976 const Kokkos::Experimental::DynamicView<SP...>& b_)
978 const iType n = std::min(a.extent(0), b.extent(0));
979 Kokkos::parallel_for(
"Kokkos::ViewCopy-1D", policy_type(0, n), *
this);
982 KOKKOS_INLINE_FUNCTION
983 void operator()(
const iType& i0)
const { a(i0) = b(i0); };
988template <
class... ViewCtorArgs,
class T,
class... P>
989auto create_mirror_view_and_copy(
990 const Impl::ViewCtorProp<ViewCtorArgs...>&,
991 const Kokkos::Experimental::DynamicView<T, P...>& src,
993 std::is_void<
typename ViewTraits<T, P...>::specialize>::value &&
994 Impl::MirrorDynamicViewType<
995 typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space, T,
996 P...>::is_same_memspace>* =
nullptr) {
997 using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
999 alloc_prop_input::has_memory_space,
1000 "The view constructor arguments passed to "
1001 "Kokkos::create_mirror_view_and_copy must include a memory space!");
1002 static_assert(!alloc_prop_input::has_pointer,
1003 "The view constructor arguments passed to "
1004 "Kokkos::create_mirror_view_and_copy must "
1005 "not include a pointer!");
1006 static_assert(!alloc_prop_input::allow_padding,
1007 "The view constructor arguments passed to "
1008 "Kokkos::create_mirror_view_and_copy must "
1009 "not explicitly allow padding!");
1012 if (!alloc_prop_input::has_execution_space)
1014 "Kokkos::create_mirror_view_and_copy: fence before returning src view");
1018template <
class... ViewCtorArgs,
class T,
class... P>
1019auto create_mirror_view_and_copy(
1020 const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
1021 const Kokkos::Experimental::DynamicView<T, P...>& src,
1023 std::is_void<
typename ViewTraits<T, P...>::specialize>::value &&
1024 !Impl::MirrorDynamicViewType<
1025 typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space, T,
1026 P...>::is_same_memspace>* =
nullptr) {
1027 using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
1029 alloc_prop_input::has_memory_space,
1030 "The view constructor arguments passed to "
1031 "Kokkos::create_mirror_view_and_copy must include a memory space!");
1032 static_assert(!alloc_prop_input::has_pointer,
1033 "The view constructor arguments passed to "
1034 "Kokkos::create_mirror_view_and_copy must "
1035 "not include a pointer!");
1036 static_assert(!alloc_prop_input::allow_padding,
1037 "The view constructor arguments passed to "
1038 "Kokkos::create_mirror_view_and_copy must "
1039 "not explicitly allow padding!");
1040 using Space =
typename alloc_prop_input::memory_space;
1042 typename Impl::MirrorDynamicViewType<Space, T, P...>::view_type;
1044 auto arg_prop_copy = Impl::with_properties_if_unset(
1045 arg_prop, std::string{}, WithoutInitializing,
1046 typename Space::execution_space{});
1048 std::string& label = Impl::get_property<Impl::LabelTag>(arg_prop_copy);
1049 if (label.empty()) label = src.label();
1050 auto mirror =
typename Mirror::non_const_type(
1051 arg_prop_copy, src.chunk_size(), src.chunk_max() * src.chunk_size());
1052 mirror.resize_serial(src.extent(0));
1053 if constexpr (alloc_prop_input::has_execution_space) {
1054 deep_copy(Impl::get_property<Impl::ExecutionSpaceTag>(arg_prop_copy),
1057 deep_copy(mirror, src);
1061template <
class Space,
class T,
class... P>
1062auto create_mirror_view_and_copy(
1063 const Space&,
const Kokkos::Experimental::DynamicView<T, P...>& src,
1064 std::string
const& name =
"") {
1065 return create_mirror_view_and_copy(
1066 Kokkos::view_alloc(
typename Space::memory_space{}, name), src);
1071#ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_DYNAMICVIEW
1072#undef KOKKOS_IMPL_PUBLIC_INCLUDE
1073#undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_DYNAMICVIEW
Dynamic views are restricted to rank-one and no layout. Resize only occurs on host outside of paralle...
DynamicView(const Kokkos::Impl::ViewCtorProp< Prop... > &arg_prop, const unsigned min_chunk_size, const unsigned max_extent)
Allocation constructor.
DynamicView< typename traits::non_const_data_type, typename traits::device_type > non_const_type
Kokkos::Device< typename traits::device_type::execution_space, Kokkos::AnonymousSpace > uniform_device
void resize_serial(IntType const &n)
Resizing in serial can grow or shrink the array size up to the maximum number of chunks.
DynamicView< typename traits::const_data_type, typename traits::device_type > const_type
DynamicView< typename traits::data_type, typename traits::device_type > array_type
Compatible view of array of scalar types.
View to an array of data.
ScopeGuard Some user scope issues have been identified with some Kokkos::finalize calls; ScopeGuard a...
Traits class for accessing attributes of a View.