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>
30 namespace Experimental {
37 template <
typename MemorySpace,
typename ValueType>
38 struct 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) {
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) {
159 Space().deallocate(m_label.c_str(), m_linked,
160 (
sizeof(value_type*) * (m_chunk_max + 2)));
164 void destroy_shared_allocation() { execute(); }
167 value_type** m_chunks =
nullptr;
168 value_type** m_linked =
nullptr;
169 unsigned m_chunk_max;
170 unsigned m_chunk_size;
174 template <
typename Space>
175 void allocate_with_destroy(
const std::string& label,
176 pointer_type* linked_allocation =
nullptr) {
177 using destroy_type = Destroy<Space>;
179 Kokkos::Impl::SharedAllocationRecord<MemorySpace, destroy_type>;
184 record_type*
const record = record_type::allocate(
185 MemorySpace(), label, (
sizeof(pointer_type) * (m_chunk_max + 2)));
186 m_chunks =
static_cast<pointer_type*
>(record->data());
187 m_track.assign_allocated_record_to_uninitialized(record);
189 record->m_destroy = destroy_type(label, m_chunks, m_chunk_max, m_chunk_size,
193 pointer_type* get_ptr()
const {
return m_chunks; }
195 template <
typename OtherMemorySpace,
typename ExecutionSpace>
197 const ExecutionSpace& exec_space,
198 ChunkedArrayManager<OtherMemorySpace, ValueType>
const& other)
const {
202 Kokkos::View<uintptr_t*, OtherMemorySpace>(
203 reinterpret_cast<uintptr_t*>(other.m_chunks), m_chunk_max + 2),
204 Kokkos::View<uintptr_t*, MemorySpace>(
205 reinterpret_cast<uintptr_t*>(m_chunks), m_chunk_max + 2));
208 KOKKOS_INLINE_FUNCTION
209 pointer_type* operator+(
int i)
const {
return m_chunks + i; }
211 KOKKOS_INLINE_FUNCTION
212 pointer_type& operator[](
int i)
const {
return m_chunks[i]; }
214 track_type
const& track()
const {
return m_track; }
216 KOKKOS_INLINE_FUNCTION
217 bool valid()
const {
return m_valid; }
220 bool m_valid =
false;
221 unsigned m_chunk_max = 0;
222 pointer_type* m_chunks =
nullptr;
224 unsigned m_chunk_size = 0;
233 template <
typename DataType,
typename... P>
234 class DynamicView :
public Kokkos::ViewTraits<DataType, P...> {
236 using traits = Kokkos::ViewTraits<DataType, P...>;
238 using value_type =
typename traits::value_type;
239 using device_space =
typename traits::memory_space;
241 typename Kokkos::Impl::HostMirror<device_space>::Space::memory_space;
242 using device_accessor = Impl::ChunkedArrayManager<device_space, value_type>;
243 using host_accessor = Impl::ChunkedArrayManager<host_space, value_type>;
246 template <
class,
class...>
247 friend class DynamicView;
249 using track_type = Kokkos::Impl::SharedAllocationTracker;
251 static_assert(traits::rank == 1 && traits::rank_dynamic == 1,
252 "DynamicView must be rank-one");
256 static_assert(std::is_void_v<typename traits::specialize>,
257 "DynamicView only implemented for non-specialized View type");
260 device_accessor m_chunks;
261 host_accessor m_chunks_host;
262 unsigned m_chunk_shift;
263 unsigned m_chunk_mask;
264 unsigned m_chunk_max;
266 unsigned m_chunk_size;
273 DynamicView<typename traits::data_type, typename traits::device_type>;
276 using const_type = DynamicView<
typename traits::const_data_type,
277 typename traits::device_type>;
280 using non_const_type = DynamicView<
typename traits::non_const_data_type,
281 typename traits::device_type>;
288 Kokkos::Device<
typename traits::device_type::execution_space,
289 Kokkos::AnonymousSpace>;
293 using uniform_runtime_const_type =
const_type;
294 using uniform_nomemspace_type =
295 DynamicView<typename traits::data_type, uniform_device>;
296 using uniform_const_nomemspace_type =
297 DynamicView<typename traits::const_data_type, uniform_device>;
298 using uniform_runtime_nomemspace_type =
299 DynamicView<typename traits::data_type, uniform_device>;
300 using uniform_runtime_const_nomemspace_type =
301 DynamicView<typename traits::const_data_type, uniform_device>;
307 KOKKOS_INLINE_FUNCTION
308 size_t allocation_extent() const noexcept {
310 *
reinterpret_cast<const uintptr_t*
>(m_chunks_host + m_chunk_max);
311 return (n << m_chunk_shift);
314 KOKKOS_INLINE_FUNCTION
315 size_t chunk_size() const noexcept {
return m_chunk_size; }
317 KOKKOS_INLINE_FUNCTION
318 size_t chunk_max() const noexcept {
return m_chunk_max; }
320 KOKKOS_INLINE_FUNCTION
321 size_t size() const noexcept {
323 *
reinterpret_cast<const size_t*
>(m_chunks_host + m_chunk_max + 1);
327 template <
typename iType>
328 KOKKOS_INLINE_FUNCTION
size_t extent(
const iType& r)
const {
329 return r == 0 ? size() : 1;
332 template <
typename iType>
333 KOKKOS_INLINE_FUNCTION
size_t extent_int(
const iType& r)
const {
334 return r == 0 ? size() : 1;
337 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_0()
const {
return 0; }
338 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_1()
const {
return 0; }
339 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_2()
const {
return 0; }
340 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_3()
const {
return 0; }
341 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_4()
const {
return 0; }
342 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_5()
const {
return 0; }
343 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_6()
const {
return 0; }
344 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_7()
const {
return 0; }
346 template <
typename iType>
347 KOKKOS_INLINE_FUNCTION
void stride(iType*
const s)
const {
354 KOKKOS_INLINE_FUNCTION
355 int use_count()
const {
return m_chunks_host.track().use_count(); }
357 inline const std::string label()
const {
358 return m_chunks_host.track().template get_label<host_space>();
364 using reference_type =
typename traits::value_type&;
365 using pointer_type =
typename traits::value_type*;
368 reference_type_is_lvalue_reference =
369 std::is_lvalue_reference_v<reference_type>
372 KOKKOS_INLINE_FUNCTION constexpr
bool span_is_contiguous()
const {
375 KOKKOS_INLINE_FUNCTION constexpr
size_t span()
const {
return 0; }
376 KOKKOS_INLINE_FUNCTION constexpr pointer_type data()
const {
return 0; }
380 template <
typename I0,
class... Args>
381 KOKKOS_INLINE_FUNCTION reference_type
382 operator()(
const I0& i0,
const Args&... )
const {
383 static_assert(Kokkos::Impl::are_integral<I0, Args...>::value,
384 "Indices must be integral type");
386 Kokkos::Impl::runtime_check_memory_access_violation<
387 typename traits::memory_space>(
388 "Kokkos::DynamicView ERROR: attempt to access inaccessible memory "
392 const uintptr_t ic = uintptr_t(i0) >> m_chunk_shift;
394 #if defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
395 const uintptr_t n = *
reinterpret_cast<uintptr_t*
>(m_chunks + m_chunk_max);
396 if (n <= ic) Kokkos::abort(
"Kokkos::DynamicView array bounds error");
399 typename traits::value_type**
const ch = m_chunks + ic;
400 return (*ch)[i0 & m_chunk_mask];
407 template <
typename IntType>
409 using local_value_type =
typename traits::value_type;
410 using value_pointer_type = local_value_type*;
413 (n + m_chunk_mask) >>
416 if (m_chunk_max < NC) {
417 Kokkos::abort(
"DynamicView::resize_serial exceeded maximum size");
421 uintptr_t*
const pc =
422 reinterpret_cast<uintptr_t*
>(m_chunks_host + m_chunk_max);
423 std::string _label = m_chunks_host.track().template get_label<host_space>();
428 reinterpret_cast<value_pointer_type
>(device_space().allocate(
429 _label.c_str(),
sizeof(local_value_type) << m_chunk_shift));
433 while (NC + 1 <= *pc) {
435 device_space().deallocate(_label.c_str(), m_chunks_host[*pc],
436 sizeof(local_value_type) << m_chunk_shift);
437 m_chunks_host[*pc] =
nullptr;
443 typename device_space::execution_space exec{};
444 m_chunks_host.deep_copy_to(exec, m_chunks);
446 "DynamicView::resize_serial: Fence after copying chunks to the device");
449 KOKKOS_INLINE_FUNCTION
bool is_allocated()
const {
450 if (m_chunks_host.valid()) {
453 uintptr_t*
const pc =
454 reinterpret_cast<uintptr_t*
>(m_chunks_host + m_chunk_max);
455 return (*(pc + 1) > 0);
461 KOKKOS_FUNCTION
const device_accessor& impl_get_chunks()
const {
465 KOKKOS_FUNCTION device_accessor& impl_get_chunks() {
return m_chunks; }
469 ~DynamicView() =
default;
470 DynamicView() =
default;
471 DynamicView(DynamicView&&) =
default;
472 DynamicView(
const DynamicView&) =
default;
473 DynamicView& operator=(DynamicView&&) =
default;
474 DynamicView& operator=(
const DynamicView&) =
default;
476 template <
class RT,
class... RP>
477 DynamicView(
const DynamicView<RT, RP...>& rhs)
478 : m_chunks(rhs.m_chunks),
479 m_chunks_host(rhs.m_chunks_host),
480 m_chunk_shift(rhs.m_chunk_shift),
481 m_chunk_mask(rhs.m_chunk_mask),
482 m_chunk_max(rhs.m_chunk_max),
483 m_chunk_size(rhs.m_chunk_size) {
484 using SrcTraits =
typename DynamicView<RT, RP...>::traits;
485 using Mapping = Kokkos::Impl::ViewMapping<traits, SrcTraits, void>;
486 static_assert(Mapping::is_assignable,
487 "Incompatible DynamicView copy construction");
496 template <
class... Prop>
497 DynamicView(
const Kokkos::Impl::ViewCtorProp<Prop...>& arg_prop,
498 const unsigned min_chunk_size,
499 const unsigned max_extent)
501 m_chunk_shift(Kokkos::Impl::integral_power_of_two_that_contains(
504 m_chunk_mask((1 << m_chunk_shift) - 1)
506 m_chunk_max((max_extent + m_chunk_mask) >>
509 m_chunk_size(2 << (m_chunk_shift - 1)) {
510 m_chunks = device_accessor(m_chunk_max, m_chunk_size);
512 const std::string& label =
513 Kokkos::Impl::get_property<Kokkos::Impl::LabelTag>(arg_prop);
515 if (device_accessor::template IsAccessibleFrom<host_space>::value) {
516 m_chunks.template allocate_with_destroy<device_space>(label);
517 m_chunks.initialize();
519 device_accessor::template create_mirror<host_space>(m_chunks);
521 m_chunks.allocate_device(label);
523 device_accessor::template create_mirror<host_space>(m_chunks);
524 m_chunks_host.template allocate_with_destroy<device_space>(
525 label, m_chunks.get_ptr());
526 m_chunks_host.initialize();
528 using alloc_prop_input = Kokkos::Impl::ViewCtorProp<Prop...>;
530 auto arg_prop_copy = ::Kokkos::Impl::with_properties_if_unset(
531 arg_prop,
typename device_space::execution_space{});
534 Kokkos::Impl::get_property<Kokkos::Impl::ExecutionSpaceTag>(
536 m_chunks_host.deep_copy_to(exec, m_chunks);
537 if (!alloc_prop_input::has_execution_space)
539 "DynamicView::DynamicView(): Fence after copying chunks to the "
544 DynamicView(
const std::string& arg_label,
const unsigned min_chunk_size,
545 const unsigned max_extent)
546 : DynamicView(Kokkos::view_alloc(arg_label), min_chunk_size, max_extent) {
553 struct is_dynamic_view :
public std::false_type {};
555 template <
class D,
class... P>
556 struct is_dynamic_view<Kokkos::Experimental::DynamicView<D, P...>>
557 :
public std::true_type {};
560 inline constexpr
bool is_dynamic_view_v = is_dynamic_view<T>::value;
569 template <
class Space,
class T,
class... P>
570 struct MirrorDynamicViewType {
574 using memory_space =
typename Space::memory_space;
578 std::is_same_v<memory_space, typename src_view_type::memory_space>
581 using array_layout =
typename src_view_type::array_layout;
584 using data_type =
typename src_view_type::non_const_data_type;
586 using dest_view_type =
591 std::conditional_t<is_same_memspace, src_view_type, dest_view_type>;
600 template <
class T,
class... P,
class... ViewCtorArgs>
602 const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
603 using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
604 check_view_ctor_args_create_mirror<ViewCtorArgs...>();
606 auto prop_copy = Impl::with_properties_if_unset(
607 arg_prop, std::string(src.label()).append(
"_mirror"));
609 if constexpr (Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space) {
610 using MemorySpace =
typename alloc_prop_input::memory_space;
612 auto ret =
typename Kokkos::Impl::MirrorDynamicViewType<
613 MemorySpace, T, P...>::view_type(prop_copy, src.chunk_size(),
614 src.chunk_max() * src.chunk_size());
616 ret.resize_serial(src.extent(0));
621 prop_copy, src.chunk_size(), src.chunk_max() * src.chunk_size());
627 #if defined(KOKKOS_COMPILER_NVCC) && KOKKOS_COMPILER_NVCC >= 1130 && \
628 !defined(KOKKOS_COMPILER_MSVC)
629 __builtin_unreachable();
636 template <
class T,
class... P,
637 typename Enable = std::enable_if_t<
638 std::is_void_v<
typename ViewTraits<T, P...>::specialize>>>
639 inline auto create_mirror(
641 return Impl::create_mirror(src, Impl::ViewCtorProp<>{});
645 template <
class T,
class... P,
646 typename Enable = std::enable_if_t<
647 std::is_void_v<
typename ViewTraits<T, P...>::specialize>>>
648 inline auto create_mirror(
649 Kokkos::Impl::WithoutInitializing_t wi,
651 return Impl::create_mirror(src, Kokkos::view_alloc(wi));
655 template <
class Space,
class T,
class... P,
656 typename Enable = std::enable_if_t<
657 Kokkos::is_space<Space>::value &&
658 std::is_void_v<
typename ViewTraits<T, P...>::specialize>>>
659 inline auto create_mirror(
661 return Impl::create_mirror(
662 src, Kokkos::view_alloc(
typename Space::memory_space{}));
666 template <
class Space,
class T,
class... P,
667 typename Enable = std::enable_if_t<
668 Kokkos::is_space<Space>::value &&
669 std::is_void_v<
typename ViewTraits<T, P...>::specialize>>>
670 inline auto create_mirror(
671 Kokkos::Impl::WithoutInitializing_t wi,
const Space&,
673 return Impl::create_mirror(
674 src, Kokkos::view_alloc(wi,
typename Space::memory_space{}));
679 template <
class T,
class... P,
class... ViewCtorArgs,
680 typename Enable = std::enable_if_t<
681 std::is_void_v<
typename ViewTraits<T, P...>::specialize>>>
682 inline auto create_mirror(
683 const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
685 return Impl::create_mirror(src, arg_prop);
693 template <
class T,
class... P,
class... ViewCtorArgs>
694 inline auto create_mirror_view(
696 [[maybe_unused]]
const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
697 if constexpr (!Impl::ViewCtorProp<ViewCtorArgs...>::has_memory_space) {
699 T, P...>::memory_space,
701 T, P...>::HostMirror::memory_space> &&
705 T, P...>::HostMirror::data_type>) {
709 return Kokkos::Impl::choose_create_mirror(src, arg_prop);
712 if constexpr (Impl::MirrorDynamicViewType<
713 typename Impl::ViewCtorProp<
714 ViewCtorArgs...>::memory_space,
715 T, P...>::is_same_memspace) {
716 return typename Impl::MirrorDynamicViewType<
717 typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space, T,
718 P...>::view_type(src);
720 return Kokkos::Impl::choose_create_mirror(src, arg_prop);
723 #if defined(KOKKOS_COMPILER_NVCC) && KOKKOS_COMPILER_NVCC >= 1130 && \
724 !defined(KOKKOS_COMPILER_MSVC)
725 __builtin_unreachable();
732 template <
class T,
class... P>
733 inline auto create_mirror_view(
735 return Impl::create_mirror_view(src, Impl::ViewCtorProp<>{});
739 template <
class T,
class... P>
740 inline auto create_mirror_view(
741 Kokkos::Impl::WithoutInitializing_t wi,
743 return Impl::create_mirror_view(src, Kokkos::view_alloc(wi));
747 template <
class Space,
class T,
class... P,
748 class Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
749 inline auto create_mirror_view(
751 return Impl::create_mirror_view(src,
752 view_alloc(
typename Space::memory_space{}));
756 template <
class Space,
class T,
class... P,
757 class Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
758 inline auto create_mirror_view(
759 Kokkos::Impl::WithoutInitializing_t wi,
const Space&,
761 return Impl::create_mirror_view(
762 src, Kokkos::view_alloc(wi,
typename Space::memory_space{}));
767 template <
class T,
class... P,
class... ViewCtorArgs>
768 inline auto create_mirror_view(
769 const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
771 return Impl::create_mirror_view(src, arg_prop);
774 template <
class T,
class... DP,
class... SP>
780 using dst_execution_space =
typename ViewTraits<T, DP...>::execution_space;
781 using src_execution_space =
typename ViewTraits<T, SP...>::execution_space;
782 using dst_memory_space =
typename ViewTraits<T, DP...>::memory_space;
783 using src_memory_space =
typename ViewTraits<T, SP...>::memory_space;
785 constexpr
bool DstExecCanAccessSrc =
787 src_memory_space>::accessible;
788 constexpr
bool SrcExecCanAccessDst =
790 dst_memory_space>::accessible;
792 if (DstExecCanAccessSrc)
793 Kokkos::Impl::ViewRemap<dst_type, src_type>(dst, src);
794 else if (SrcExecCanAccessDst)
795 Kokkos::Impl::ViewRemap<dst_type, src_type>(dst, src);
797 src.impl_get_chunks().deep_copy_to(dst_execution_space{},
798 dst.impl_get_chunks());
799 Kokkos::fence(
"Kokkos::deep_copy(DynamicView)");
802 template <
class ExecutionSpace,
class T,
class... DP,
class... SP>
803 inline void deep_copy(
const ExecutionSpace& exec,
809 using dst_execution_space =
typename ViewTraits<T, DP...>::execution_space;
810 using src_execution_space =
typename ViewTraits<T, SP...>::execution_space;
811 using dst_memory_space =
typename ViewTraits<T, DP...>::memory_space;
812 using src_memory_space =
typename ViewTraits<T, SP...>::memory_space;
814 constexpr
bool DstExecCanAccessSrc =
816 src_memory_space>::accessible;
817 constexpr
bool SrcExecCanAccessDst =
819 dst_memory_space>::accessible;
822 if (DstExecCanAccessSrc)
823 Kokkos::Impl::ViewRemap<dst_type, src_type>(dst, src);
824 else if (SrcExecCanAccessDst)
825 Kokkos::Impl::ViewRemap<dst_type, src_type>(dst, src);
827 src.impl_get_chunks().deep_copy_to(exec, dst.impl_get_chunks());
830 template <
class T,
class... DP,
class... SP>
831 inline void deep_copy(
const View<T, DP...>& dst,
833 using dst_type =
View<T, DP...>;
836 using dst_execution_space =
typename ViewTraits<T, DP...>::execution_space;
837 using src_memory_space =
typename ViewTraits<T, SP...>::memory_space;
839 constexpr
bool DstExecCanAccessSrc =
841 src_memory_space>::accessible;
844 "deep_copy given views that would require a temporary allocation");
848 Kokkos::Impl::ViewRemap<dst_type, src_type>(dst, src);
849 Kokkos::fence(
"Kokkos::deep_copy(DynamicView)");
852 template <
class T,
class... DP,
class... SP>
854 const View<T, SP...>& src) {
856 using src_type =
View<T, SP...>;
858 using dst_execution_space =
typename ViewTraits<T, DP...>::execution_space;
859 using src_memory_space =
typename ViewTraits<T, SP...>::memory_space;
861 constexpr
bool DstExecCanAccessSrc =
863 src_memory_space>::accessible;
866 "deep_copy given views that would require a temporary allocation");
870 Kokkos::Impl::ViewRemap<dst_type, src_type>(dst, src);
871 Kokkos::fence(
"Kokkos::deep_copy(DynamicView)");
875 template <
class Arg0,
class... DP,
class... SP>
876 struct CommonSubview<Kokkos::Experimental::DynamicView<DP...>,
880 using dst_subview_type = DstType;
881 using src_subview_type = SrcType;
882 dst_subview_type dst_sub;
883 src_subview_type src_sub;
884 CommonSubview(
const DstType& dst,
const SrcType& src,
const Arg0& )
885 : dst_sub(dst), src_sub(src) {}
888 template <
class... DP,
class SrcType,
class Arg0>
889 struct CommonSubview<Kokkos::Experimental::DynamicView<DP...>, SrcType, Arg0> {
891 using dst_subview_type = DstType;
892 using src_subview_type =
typename Kokkos::Subview<SrcType, Arg0>;
893 dst_subview_type dst_sub;
894 src_subview_type src_sub;
895 CommonSubview(
const DstType& dst,
const SrcType& src,
const Arg0& arg0)
896 : dst_sub(dst), src_sub(src, arg0) {}
899 template <
class DstType,
class... SP,
class Arg0>
900 struct CommonSubview<DstType, Kokkos::Experimental::DynamicView<SP...>, Arg0> {
902 using dst_subview_type =
typename Kokkos::Subview<DstType, Arg0>;
903 using src_subview_type = SrcType;
904 dst_subview_type dst_sub;
905 src_subview_type src_sub;
906 CommonSubview(
const DstType& dst,
const SrcType& src,
const Arg0& arg0)
907 : dst_sub(dst, arg0), src_sub(src) {}
910 template <
class... DP,
class ViewTypeB,
class Layout,
class ExecSpace,
912 struct ViewCopy<Kokkos::Experimental::DynamicView<DP...>, ViewTypeB, Layout,
913 ExecSpace, 1, iType> {
922 Kokkos::parallel_for(
"Kokkos::ViewCopy-1D", policy_type(0, b.extent(0)),
926 KOKKOS_INLINE_FUNCTION
927 void operator()(
const iType& i0)
const { a(i0) = b(i0); };
930 template <
class... DP,
class... SP,
class Layout,
class ExecSpace,
932 struct ViewCopy<Kokkos::Experimental::DynamicView<DP...>,
943 const iType n = std::min(a.extent(0), b.extent(0));
944 Kokkos::parallel_for(
"Kokkos::ViewCopy-1D", policy_type(0, n), *
this);
947 KOKKOS_INLINE_FUNCTION
948 void operator()(
const iType& i0)
const { a(i0) = b(i0); };
956 template <
class... ViewCtorArgs,
class T,
class... P,
957 class Enable = std::enable_if_t<
958 std::is_void_v<
typename ViewTraits<T, P...>::specialize>>>
959 auto create_mirror_view_and_copy(
960 [[maybe_unused]]
const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
962 using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
964 Impl::check_view_ctor_args_create_mirror_view_and_copy<ViewCtorArgs...>();
966 if constexpr (Impl::MirrorDynamicViewType<
967 typename Impl::ViewCtorProp<ViewCtorArgs...>::memory_space,
968 T, P...>::is_same_memspace) {
970 if constexpr (!alloc_prop_input::has_execution_space)
972 "Kokkos::create_mirror_view_and_copy: fence before returning src "
976 using Space =
typename alloc_prop_input::memory_space;
978 typename Impl::MirrorDynamicViewType<Space, T, P...>::view_type;
980 auto arg_prop_copy = Impl::with_properties_if_unset(
981 arg_prop, std::string{}, WithoutInitializing,
982 typename Space::execution_space{});
984 std::string& label = Impl::get_property<Impl::LabelTag>(arg_prop_copy);
985 if (label.empty()) label = src.label();
986 auto mirror =
typename Mirror::non_const_type(
987 arg_prop_copy, src.chunk_size(), src.chunk_max() * src.chunk_size());
988 mirror.resize_serial(src.extent(0));
989 if constexpr (alloc_prop_input::has_execution_space) {
990 deep_copy(Impl::get_property<Impl::ExecutionSpaceTag>(arg_prop_copy),
993 deep_copy(mirror, src);
996 #if defined(KOKKOS_COMPILER_NVCC) && KOKKOS_COMPILER_NVCC >= 1130 && \
997 !defined(KOKKOS_COMPILER_MSVC)
998 __builtin_unreachable();
1002 template <
class Space,
class T,
class... P,
1003 typename Enable = std::enable_if_t<Kokkos::is_space<Space>::value>>
1004 auto create_mirror_view_and_copy(
1006 std::string
const& name =
"") {
1007 return create_mirror_view_and_copy(
1008 Kokkos::view_alloc(
typename Space::memory_space{}, name), src);
1013 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_DYNAMICVIEW
1014 #undef KOKKOS_IMPL_PUBLIC_INCLUDE
1015 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_DYNAMICVIEW
DynamicView< typename traits::data_type, typename traits::device_type > array_type
Dynamic views are restricted to rank-one and no layout. Resize only occurs on host outside of paralle...
Can AccessSpace access MemorySpace ?
Kokkos::Device< typename traits::device_type::execution_space, Kokkos::AnonymousSpace > uniform_device
DynamicView< typename traits::const_data_type, typename traits::device_type > const_type
DynamicView< typename traits::non_const_data_type, typename traits::device_type > non_const_type
void resize_serial(IntType const &n)
Execution policy for work over a range of an integral type.
Access relationship between DstMemorySpace and SrcMemorySpace.