51 #ifndef KOKKOS_DUALVIEW_HPP 52 #define KOKKOS_DUALVIEW_HPP 54 #include <Kokkos_Core.hpp> 55 #include <impl/Kokkos_Error.hpp> 97 #ifdef KOKKOS_ENABLE_CUDA 99 inline const Kokkos::Cuda& get_cuda_space(
const Kokkos::Cuda& in) {
return in; }
101 inline const Kokkos::Cuda& get_cuda_space() {
102 return *Kokkos::Impl::cuda_get_deep_copy_space();
105 template <
typename NonCudaExecSpace>
106 inline const Kokkos::Cuda& get_cuda_space(
const NonCudaExecSpace&) {
107 return get_cuda_space();
110 #endif // KOKKOS_ENABLE_CUDA 113 template <
class DataType,
class Arg1Type = void,
class Arg2Type = void,
114 class Arg3Type =
void>
115 class DualView :
public ViewTraits<DataType, Arg1Type, Arg2Type, Arg3Type> {
116 template <
class,
class,
class,
class>
117 friend class DualView;
122 using traits = ViewTraits<DataType, Arg1Type, Arg2Type, Arg3Type>;
125 using host_mirror_space =
typename traits::host_mirror_space;
128 using t_dev = View<typename traits::data_type, Arg1Type, Arg2Type, Arg3Type>;
137 View<typename traits::const_data_type, Arg1Type, Arg2Type, Arg3Type>;
144 using t_dev_const_randomread =
145 View<
typename traits::const_data_type,
typename traits::array_layout,
146 typename traits::device_type,
147 Kokkos::MemoryTraits<Kokkos::RandomAccess> >;
156 View<
typename traits::data_type,
typename traits::array_layout,
157 typename traits::device_type, MemoryUnmanaged>;
161 View<
typename t_host::data_type,
typename t_host::array_layout,
162 typename t_host::device_type, MemoryUnmanaged>;
165 using t_dev_const_um =
166 View<
typename traits::const_data_type,
typename traits::array_layout,
167 typename traits::device_type, MemoryUnmanaged>;
170 using t_host_const_um =
171 View<
typename t_host::const_data_type,
typename t_host::array_layout,
172 typename t_host::device_type, MemoryUnmanaged>;
175 using t_dev_const_randomread_um =
176 View<
typename t_host::const_data_type,
typename t_host::array_layout,
177 typename t_host::device_type,
178 Kokkos::MemoryTraits<Kokkos::Unmanaged | Kokkos::RandomAccess> >;
183 using t_host_const_randomread_um =
193 using t_modified_flags = View<unsigned int[2], LayoutLeft, Kokkos::HostSpace>;
194 t_modified_flags modified_flags;
215 DualView() =
default;
226 DualView(
const std::string& label,
227 const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
228 const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
229 const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
230 const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
231 const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
232 const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
233 const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
234 const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
235 : modified_flags(t_modified_flags(
"DualView::modified_flags")),
236 d_view(label, n0, n1, n2, n3, n4, n5, n6, n7),
237 h_view(create_mirror_view(d_view))
250 template <
class... P>
251 DualView(
const Impl::ViewCtorProp<P...>& arg_prop,
252 typename std::enable_if<!Impl::ViewCtorProp<P...>::has_pointer,
253 size_t>::type
const n0 =
254 KOKKOS_IMPL_CTOR_DEFAULT_ARG,
255 const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
256 const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
257 const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
258 const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
259 const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
260 const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
261 const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
262 : modified_flags(t_modified_flags(
"DualView::modified_flags")),
263 d_view(arg_prop, n0, n1, n2, n3, n4, n5, n6, n7),
264 h_view(create_mirror_view(d_view))
268 template <
class SS,
class LS,
class DS,
class MS>
269 DualView(
const DualView<SS, LS, DS, MS>& src)
270 : modified_flags(src.modified_flags),
272 h_view(src.h_view) {}
275 template <
class SD,
class S1,
class S2,
class S3,
class Arg0,
class... Args>
276 DualView(
const DualView<SD, S1, S2, S3>& src,
const Arg0& arg0, Args... args)
277 : modified_flags(src.modified_flags),
278 d_view(
Kokkos::subview(src.d_view, arg0, args...)),
279 h_view(
Kokkos::subview(src.h_view, arg0, args...)) {}
291 DualView(
const t_dev& d_view_,
const t_host& h_view_)
292 : modified_flags(t_modified_flags(
"DualView::modified_flags")),
295 if (
int(d_view.rank) !=
int(h_view.rank) ||
296 d_view.extent(0) != h_view.extent(0) ||
297 d_view.extent(1) != h_view.extent(1) ||
298 d_view.extent(2) != h_view.extent(2) ||
299 d_view.extent(3) != h_view.extent(3) ||
300 d_view.extent(4) != h_view.extent(4) ||
301 d_view.extent(5) != h_view.extent(5) ||
302 d_view.extent(6) != h_view.extent(6) ||
303 d_view.extent(7) != h_view.extent(7) ||
304 d_view.stride_0() != h_view.stride_0() ||
305 d_view.stride_1() != h_view.stride_1() ||
306 d_view.stride_2() != h_view.stride_2() ||
307 d_view.stride_3() != h_view.stride_3() ||
308 d_view.stride_4() != h_view.stride_4() ||
309 d_view.stride_5() != h_view.stride_5() ||
310 d_view.stride_6() != h_view.stride_6() ||
311 d_view.stride_7() != h_view.stride_7() ||
312 d_view.span() != h_view.span()) {
313 Kokkos::Impl::throw_runtime_exception(
314 "DualView constructed with incompatible views");
318 struct impl_dualview_is_single_device {
320 value = std::is_same<
typename t_dev::device_type,
321 typename t_host::device_type>::value
326 template <
typename Device>
327 struct impl_device_matches_tdev_device {
329 value = std::is_same<typename t_dev::device_type, Device>::value
333 template <
typename Device>
334 struct impl_device_matches_thost_device {
336 value = std::is_same<typename t_host::device_type, Device>::value
341 template <
typename Device>
342 struct impl_device_matches_thost_exec {
344 value = std::is_same<typename t_host::execution_space, Device>::value
349 template <
typename Device>
350 struct impl_device_matches_tdev_exec {
352 value = std::is_same<typename t_dev::execution_space, Device>::value
357 template <
typename Device>
358 struct impl_device_matches_tdev_memory_space {
360 value = std::is_same<
typename t_dev::memory_space,
361 typename Device::memory_space>::value
391 template <
class Device>
392 KOKKOS_INLINE_FUNCTION
const typename std::conditional_t<
393 impl_device_matches_tdev_device<Device>::value, t_dev,
394 typename std::conditional_t<
395 impl_device_matches_thost_device<Device>::value, t_host,
396 typename std::conditional_t<
397 impl_device_matches_thost_exec<Device>::value, t_host,
398 typename std::conditional_t<
399 impl_device_matches_tdev_exec<Device>::value, t_dev,
400 typename std::conditional_t<
401 impl_device_matches_tdev_memory_space<Device>::value,
402 t_dev, t_host> > > > >
404 constexpr
bool device_is_memspace =
405 std::is_same<Device, typename Device::memory_space>::value;
406 constexpr
bool device_is_execspace =
407 std::is_same<Device, typename Device::execution_space>::value;
408 constexpr
bool device_exec_is_t_dev_exec =
409 std::is_same<
typename Device::execution_space,
410 typename t_dev::execution_space>::value;
411 constexpr
bool device_mem_is_t_dev_mem =
412 std::is_same<
typename Device::memory_space,
413 typename t_dev::memory_space>::value;
414 constexpr
bool device_exec_is_t_host_exec =
415 std::is_same<
typename Device::execution_space,
416 typename t_host::execution_space>::value;
417 constexpr
bool device_mem_is_t_host_mem =
418 std::is_same<
typename Device::memory_space,
419 typename t_host::memory_space>::value;
420 constexpr
bool device_is_t_host_device =
421 std::is_same<
typename Device::execution_space,
422 typename t_host::device_type>::value;
423 constexpr
bool device_is_t_dev_device =
424 std::is_same<
typename Device::memory_space,
425 typename t_host::device_type>::value;
428 device_is_t_dev_device || device_is_t_host_device ||
429 (device_is_memspace &&
430 (device_mem_is_t_dev_mem || device_mem_is_t_host_mem)) ||
431 (device_is_execspace &&
432 (device_exec_is_t_dev_exec || device_exec_is_t_host_exec)) ||
433 ((!device_is_execspace && !device_is_memspace) &&
434 ((device_mem_is_t_dev_mem || device_mem_is_t_host_mem) ||
435 (device_exec_is_t_dev_exec || device_exec_is_t_host_exec))),
436 "Template parameter to .view() must exactly match one of the " 437 "DualView's device types or one of the execution or memory spaces");
439 return Impl::if_c<std::is_same<
typename t_dev::memory_space,
440 typename Device::memory_space>::value,
441 t_dev, t_host>::select(d_view, h_view);
444 KOKKOS_INLINE_FUNCTION
445 t_host view_host()
const {
return h_view; }
447 KOKKOS_INLINE_FUNCTION
448 t_dev view_device()
const {
return d_view; }
450 KOKKOS_INLINE_FUNCTION constexpr
bool is_allocated()
const {
451 return (d_view.is_allocated() && h_view.is_allocated());
454 template <
class Device>
455 static int get_device_side() {
456 constexpr
bool device_is_memspace =
457 std::is_same<Device, typename Device::memory_space>::value;
458 constexpr
bool device_is_execspace =
459 std::is_same<Device, typename Device::execution_space>::value;
460 constexpr
bool device_exec_is_t_dev_exec =
461 std::is_same<
typename Device::execution_space,
462 typename t_dev::execution_space>::value;
463 constexpr
bool device_mem_is_t_dev_mem =
464 std::is_same<
typename Device::memory_space,
465 typename t_dev::memory_space>::value;
466 constexpr
bool device_exec_is_t_host_exec =
467 std::is_same<
typename Device::execution_space,
468 typename t_host::execution_space>::value;
469 constexpr
bool device_mem_is_t_host_mem =
470 std::is_same<
typename Device::memory_space,
471 typename t_host::memory_space>::value;
472 constexpr
bool device_is_t_host_device =
473 std::is_same<
typename Device::execution_space,
474 typename t_host::device_type>::value;
475 constexpr
bool device_is_t_dev_device =
476 std::is_same<
typename Device::memory_space,
477 typename t_host::device_type>::value;
480 device_is_t_dev_device || device_is_t_host_device ||
481 (device_is_memspace &&
482 (device_mem_is_t_dev_mem || device_mem_is_t_host_mem)) ||
483 (device_is_execspace &&
484 (device_exec_is_t_dev_exec || device_exec_is_t_host_exec)) ||
485 ((!device_is_execspace && !device_is_memspace) &&
486 ((device_mem_is_t_dev_mem || device_mem_is_t_host_mem) ||
487 (device_exec_is_t_dev_exec || device_exec_is_t_host_exec))),
488 "Template parameter to .sync() must exactly match one of the " 489 "DualView's device types or one of the execution or memory spaces");
492 if (device_is_t_dev_device)
494 else if (device_is_t_host_device)
497 if (device_is_memspace) {
498 if (device_mem_is_t_dev_mem) dev = 1;
499 if (device_mem_is_t_host_mem) dev = 0;
500 if (device_mem_is_t_host_mem && device_mem_is_t_dev_mem) dev = -1;
502 if (device_is_execspace) {
503 if (device_exec_is_t_dev_exec) dev = 1;
504 if (device_exec_is_t_host_exec) dev = 0;
505 if (device_exec_is_t_host_exec && device_exec_is_t_dev_exec) dev = -1;
507 if (!device_is_execspace && !device_is_memspace) {
508 if (device_mem_is_t_dev_mem) dev = 1;
509 if (device_mem_is_t_host_mem) dev = 0;
510 if (device_mem_is_t_host_mem && device_mem_is_t_dev_mem) dev = -1;
511 if (device_exec_is_t_dev_exec) dev = 1;
512 if (device_exec_is_t_host_exec) dev = 0;
513 if (device_exec_is_t_host_exec && device_exec_is_t_dev_exec) dev = -1;
518 static constexpr
const int view_header_size = 128;
519 void impl_report_host_sync() const noexcept {
520 if (Kokkos::Tools::Experimental::get_callbacks().sync_dual_view !=
522 Kokkos::Tools::syncDualView(
524 reinterpret_cast<void*
>(
reinterpret_cast<uintptr_t
>(h_view.data()) -
529 void impl_report_device_sync() const noexcept {
530 if (Kokkos::Tools::Experimental::get_callbacks().sync_dual_view !=
532 Kokkos::Tools::syncDualView(
534 reinterpret_cast<void*
>(
reinterpret_cast<uintptr_t
>(d_view.data()) -
558 template <
class Device,
class... Args>
559 void sync_impl(std::true_type, Args
const&... args) {
560 if (modified_flags.data() ==
nullptr)
return;
562 int dev = get_device_side<Device>();
565 if ((modified_flags(0) > 0) && (modified_flags(0) >= modified_flags(1))) {
566 #ifdef KOKKOS_ENABLE_CUDA 567 if (std::is_same<
typename t_dev::memory_space,
568 Kokkos::CudaUVMSpace>::value) {
569 if (d_view.data() == h_view.data())
570 Kokkos::Impl::cuda_prefetch_pointer(
571 Impl::get_cuda_space(args...), d_view.data(),
572 sizeof(
typename t_dev::value_type) * d_view.span(),
true);
576 deep_copy(args..., d_view, h_view);
577 modified_flags(0) = modified_flags(1) = 0;
578 impl_report_device_sync();
582 if ((modified_flags(1) > 0) && (modified_flags(1) >= modified_flags(0))) {
583 #ifdef KOKKOS_ENABLE_CUDA 584 if (std::is_same<
typename t_dev::memory_space,
585 Kokkos::CudaUVMSpace>::value) {
586 if (d_view.data() == h_view.data())
587 Kokkos::Impl::cuda_prefetch_pointer(
588 Impl::get_cuda_space(args...), d_view.data(),
589 sizeof(
typename t_dev::value_type) * d_view.span(),
false);
593 deep_copy(args..., h_view, d_view);
594 modified_flags(0) = modified_flags(1) = 0;
595 impl_report_host_sync();
598 if (std::is_same<
typename t_host::memory_space,
599 typename t_dev::memory_space>::value) {
600 typename t_dev::execution_space().fence();
601 typename t_host::execution_space().fence();
605 template <
class Device>
606 void sync(
const typename std::enable_if<
607 (std::is_same<
typename traits::data_type,
608 typename traits::non_const_data_type>::value) ||
609 (std::is_same<Device, int>::value),
611 sync_impl<Device>(std::true_type{});
614 template <
class Device,
class ExecutionSpace>
615 void sync(
const ExecutionSpace& exec,
616 const typename std::enable_if<
617 (std::is_same<
typename traits::data_type,
618 typename traits::non_const_data_type>::value) ||
619 (std::is_same<Device, int>::value),
621 sync_impl<Device>(std::true_type{}, exec);
625 template <
class Device,
class... Args>
626 void sync_impl(std::false_type, Args
const&...) {
627 if (modified_flags.data() ==
nullptr)
return;
629 int dev = get_device_side<Device>();
632 if ((modified_flags(0) > 0) && (modified_flags(0) >= modified_flags(1))) {
633 Impl::throw_runtime_exception(
634 "Calling sync on a DualView with a const datatype.");
636 impl_report_device_sync();
639 if ((modified_flags(1) > 0) && (modified_flags(1) >= modified_flags(0))) {
640 Impl::throw_runtime_exception(
641 "Calling sync on a DualView with a const datatype.");
643 impl_report_host_sync();
647 template <
class Device>
648 void sync(
const typename std::enable_if<
649 (!std::is_same<
typename traits::data_type,
650 typename traits::non_const_data_type>::value) ||
651 (std::is_same<Device, int>::value),
653 sync_impl<Device>(std::false_type{});
655 template <
class Device,
class ExecutionSpace>
656 void sync(
const ExecutionSpace& exec,
657 const typename std::enable_if<
658 (!std::is_same<
typename traits::data_type,
659 typename traits::non_const_data_type>::value) ||
660 (std::is_same<Device, int>::value),
662 sync_impl<Device>(std::false_type{}, exec);
666 template <
typename... Args>
667 void sync_host_impl(Args
const&... args) {
668 if (!std::is_same<
typename traits::data_type,
669 typename traits::non_const_data_type>::value)
670 Impl::throw_runtime_exception(
671 "Calling sync_host on a DualView with a const datatype.");
672 if (modified_flags.data() ==
nullptr)
return;
673 if (modified_flags(1) > modified_flags(0)) {
674 #ifdef KOKKOS_ENABLE_CUDA 675 if (std::is_same<
typename t_dev::memory_space,
676 Kokkos::CudaUVMSpace>::value) {
677 if (d_view.data() == h_view.data())
678 Kokkos::Impl::cuda_prefetch_pointer(
679 Impl::get_cuda_space(args...), d_view.data(),
680 sizeof(
typename t_dev::value_type) * d_view.span(),
false);
684 deep_copy(args..., h_view, d_view);
685 modified_flags(1) = modified_flags(0) = 0;
686 impl_report_host_sync();
690 template <
class ExecSpace>
691 void sync_host(
const ExecSpace& exec) {
692 sync_host_impl(exec);
694 void sync_host() { sync_host_impl(); }
697 template <
typename... Args>
698 void sync_device_impl(Args
const&... args) {
699 if (!std::is_same<
typename traits::data_type,
700 typename traits::non_const_data_type>::value)
701 Impl::throw_runtime_exception(
702 "Calling sync_device on a DualView with a const datatype.");
703 if (modified_flags.data() ==
nullptr)
return;
704 if (modified_flags(0) > modified_flags(1)) {
705 #ifdef KOKKOS_ENABLE_CUDA 706 if (std::is_same<
typename t_dev::memory_space,
707 Kokkos::CudaUVMSpace>::value) {
708 if (d_view.data() == h_view.data())
709 Kokkos::Impl::cuda_prefetch_pointer(
710 Impl::get_cuda_space(args...), d_view.data(),
711 sizeof(
typename t_dev::value_type) * d_view.span(),
true);
715 deep_copy(args..., d_view, h_view);
716 modified_flags(1) = modified_flags(0) = 0;
717 impl_report_device_sync();
721 template <
class ExecSpace>
722 void sync_device(
const ExecSpace& exec) {
723 sync_device_impl(exec);
725 void sync_device() { sync_device_impl(); }
727 template <
class Device>
728 bool need_sync()
const {
729 if (modified_flags.data() ==
nullptr)
return false;
730 int dev = get_device_side<Device>();
733 if ((modified_flags(0) > 0) && (modified_flags(0) >= modified_flags(1))) {
738 if ((modified_flags(1) > 0) && (modified_flags(1) >= modified_flags(0))) {
745 inline bool need_sync_host()
const {
746 if (modified_flags.data() ==
nullptr)
return false;
747 return modified_flags(0) < modified_flags(1);
750 inline bool need_sync_device()
const {
751 if (modified_flags.data() ==
nullptr)
return false;
752 return modified_flags(1) < modified_flags(0);
754 void impl_report_device_modification() {
755 if (Kokkos::Tools::Experimental::get_callbacks().modify_dual_view !=
757 Kokkos::Tools::modifyDualView(
759 reinterpret_cast<void*
>(
reinterpret_cast<uintptr_t
>(d_view.data()) -
764 void impl_report_host_modification() {
765 if (Kokkos::Tools::Experimental::get_callbacks().modify_dual_view !=
767 Kokkos::Tools::modifyDualView(
769 reinterpret_cast<void*
>(
reinterpret_cast<uintptr_t
>(h_view.data()) -
779 template <
class Device>
781 if (modified_flags.data() ==
nullptr)
return;
782 if (impl_dualview_is_single_device::value)
return;
783 int dev = get_device_side<Device>();
788 (modified_flags(1) > modified_flags(0) ? modified_flags(1)
789 : modified_flags(0)) +
791 impl_report_device_modification();
796 (modified_flags(1) > modified_flags(0) ? modified_flags(1)
797 : modified_flags(0)) +
799 impl_report_host_modification();
802 #ifdef KOKKOS_ENABLE_DEBUG_DUALVIEW_MODIFY_CHECK 803 if (modified_flags(0) && modified_flags(1)) {
804 std::string msg =
"Kokkos::DualView::modify ERROR: ";
805 msg +=
"Concurrent modification of host and device views ";
806 msg +=
"in DualView \"";
807 msg += d_view.label();
809 Kokkos::abort(msg.c_str());
814 inline void modify_host() {
815 if (impl_dualview_is_single_device::value)
return;
816 if (modified_flags.data() !=
nullptr) {
818 (modified_flags(1) > modified_flags(0) ? modified_flags(1)
819 : modified_flags(0)) +
821 impl_report_host_modification();
822 #ifdef KOKKOS_ENABLE_DEBUG_DUALVIEW_MODIFY_CHECK 823 if (modified_flags(0) && modified_flags(1)) {
824 std::string msg =
"Kokkos::DualView::modify_host ERROR: ";
825 msg +=
"Concurrent modification of host and device views ";
826 msg +=
"in DualView \"";
827 msg += d_view.label();
829 Kokkos::abort(msg.c_str());
835 inline void modify_device() {
836 if (impl_dualview_is_single_device::value)
return;
837 if (modified_flags.data() !=
nullptr) {
839 (modified_flags(1) > modified_flags(0) ? modified_flags(1)
840 : modified_flags(0)) +
842 impl_report_device_modification();
843 #ifdef KOKKOS_ENABLE_DEBUG_DUALVIEW_MODIFY_CHECK 844 if (modified_flags(0) && modified_flags(1)) {
845 std::string msg =
"Kokkos::DualView::modify_device ERROR: ";
846 msg +=
"Concurrent modification of host and device views ";
847 msg +=
"in DualView \"";
848 msg += d_view.label();
850 Kokkos::abort(msg.c_str());
856 inline void clear_sync_state() {
857 if (modified_flags.data() !=
nullptr)
858 modified_flags(1) = modified_flags(0) = 0;
870 void realloc(
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
871 const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
872 const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
873 const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
874 const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
875 const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
876 const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
877 const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
878 ::Kokkos::realloc(d_view, n0, n1, n2, n3, n4, n5, n6, n7);
879 h_view = create_mirror_view(d_view);
882 if (modified_flags.data() ==
nullptr) {
883 modified_flags = t_modified_flags(
"DualView::modified_flags");
885 modified_flags(1) = modified_flags(0) = 0;
892 void resize(
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
893 const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
894 const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
895 const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
896 const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
897 const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
898 const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
899 const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
900 if (modified_flags.data() ==
nullptr) {
901 modified_flags = t_modified_flags(
"DualView::modified_flags");
903 if (modified_flags(1) >= modified_flags(0)) {
905 ::Kokkos::resize(d_view, n0, n1, n2, n3, n4, n5, n6, n7);
906 h_view = create_mirror_view(d_view);
909 modified_flags(1) = modified_flags(1) + 1;
914 ::Kokkos::realloc(d_view, n0, n1, n2, n3, n4, n5, n6, n7);
916 const bool sizeMismatch =
917 (h_view.extent(0) != n0) || (h_view.extent(1) != n1) ||
918 (h_view.extent(2) != n2) || (h_view.extent(3) != n3) ||
919 (h_view.extent(4) != n4) || (h_view.extent(5) != n5) ||
920 (h_view.extent(6) != n6) || (h_view.extent(7) != n7);
922 ::Kokkos::resize(h_view, n0, n1, n2, n3, n4, n5, n6, n7);
924 t_host temp_view = create_mirror_view(d_view);
927 Kokkos::deep_copy(temp_view, h_view);
931 d_view = create_mirror_view(
typename t_dev::execution_space(), h_view);
934 modified_flags(0) = modified_flags(0) + 1;
943 KOKKOS_INLINE_FUNCTION constexpr
size_t span()
const {
return d_view.span(); }
945 KOKKOS_INLINE_FUNCTION
bool span_is_contiguous()
const {
946 return d_view.span_is_contiguous();
950 template <
typename iType>
951 void stride(iType* stride_)
const {
952 d_view.stride(stride_);
955 template <
typename iType>
956 KOKKOS_INLINE_FUNCTION constexpr
957 typename std::enable_if<std::is_integral<iType>::value,
size_t>::type
958 extent(
const iType& r)
const {
959 return d_view.extent(r);
962 template <
typename iType>
963 KOKKOS_INLINE_FUNCTION constexpr
964 typename std::enable_if<std::is_integral<iType>::value,
int>::type
965 extent_int(
const iType& r)
const {
966 return static_cast<int>(d_view.extent(r));
983 template <
class D,
class A1,
class A2,
class A3,
class... Args>
984 struct DualViewSubview {
985 using dst_traits =
typename Kokkos::Impl::ViewMapping<
988 using type = Kokkos::DualView<
989 typename dst_traits::data_type,
typename dst_traits::array_layout,
990 typename dst_traits::device_type,
typename dst_traits::memory_traits>;
995 template <
class D,
class A1,
class A2,
class A3,
class... Args>
996 typename Impl::DualViewSubview<D, A1, A2, A3, Args...>::type subview(
997 const DualView<D, A1, A2, A3>& src, Args... args) {
998 return typename Impl::DualViewSubview<D, A1, A2, A3, Args...>::type(src,
1013 template <
class DT,
class DL,
class DD,
class DM,
class ST,
class SL,
class SD,
1016 DualView<DT, DL, DD, DM> dst,
1017 const DualView<ST, SL, SD, SM>& src) {
1018 if (src.need_sync_device()) {
1019 deep_copy(dst.h_view, src.h_view);
1022 deep_copy(dst.d_view, src.d_view);
1023 dst.modify_device();
1027 template <
class ExecutionSpace,
class DT,
class DL,
class DD,
class DM,
1028 class ST,
class SL,
class SD,
class SM>
1030 const ExecutionSpace& exec,
1031 DualView<DT, DL, DD, DM> dst,
1032 const DualView<ST, SL, SD, SM>& src) {
1033 if (src.need_sync_device()) {
1034 deep_copy(exec, dst.h_view, src.h_view);
1037 deep_copy(exec, dst.d_view, src.d_view);
1038 dst.modify_device();
1053 template <
class... Properties,
class... Args>
1054 void resize(DualView<Properties...>& dv, Args&&... args) noexcept(
1055 noexcept(dv.resize(std::forward<Args>(args)...))) {
1056 dv.resize(std::forward<Args>(args)...);
1059 template <
class... Properties,
class... Args>
1060 void realloc(DualView<Properties...>& dv, Args&&... args) noexcept(
1061 noexcept(dv.realloc(std::forward<Args>(args)...))) {
1062 dv.realloc(std::forward<Args>(args)...);
View< typename traits::non_const_data_type, typename traits::array_layout, Device< DefaultHostExecutionSpace, typename traits::host_mirror_space::memory_space > > HostMirror
Compatible HostMirror view.
Traits class for accessing attributes of a View.