23 #ifndef KOKKOS_DUALVIEW_HPP 
   24 #define KOKKOS_DUALVIEW_HPP 
   25 #ifndef KOKKOS_IMPL_PUBLIC_INCLUDE 
   26 #define KOKKOS_IMPL_PUBLIC_INCLUDE 
   27 #define KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_DUALVIEW 
   30 #include <Kokkos_Core.hpp> 
   31 #include <impl/Kokkos_Error.hpp> 
   73 #ifdef KOKKOS_ENABLE_CUDA 
   75 inline const Kokkos::Cuda& get_cuda_space(
const Kokkos::Cuda& in) { 
return in; }
 
   77 inline const Kokkos::Cuda& get_cuda_space() {
 
   78   return *Kokkos::Impl::cuda_get_deep_copy_space();
 
   81 template <
typename NonCudaExecSpace>
 
   82 inline const Kokkos::Cuda& get_cuda_space(
const NonCudaExecSpace&) {
 
   83   return get_cuda_space();
 
   86 #endif  // KOKKOS_ENABLE_CUDA 
   90 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4 
   91 template <
class DataType, 
class Arg1Type = void, 
class Arg2Type = void,
 
   92           class Arg3Type = 
void>
 
   95 template <
class DataType, 
class... Properties>
 
  100 struct is_dual_view : 
public std::false_type {};
 
  102 template <
class DT, 
class... DP>
 
  103 struct is_dual_view<DualView<DT, DP...>> : 
public std::true_type {};
 
  105 template <
class DT, 
class... DP>
 
  106 struct is_dual_view<const DualView<DT, DP...>> : 
public std::true_type {};
 
  109 inline constexpr 
bool is_dual_view_v = is_dual_view<T>::value;
 
  111 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4 
  112 template <
class DataType, 
class Arg1Type, 
class Arg2Type, 
class Arg3Type>
 
  113 class DualView : 
public ViewTraits<DataType, Arg1Type, Arg2Type, Arg3Type> {
 
  114   template <
class, 
class, 
class, 
class>
 
  116 template <
class DataType, 
class... Properties>
 
  117 class DualView : 
public ViewTraits<DataType, Properties...> {
 
  118   template <
class, 
class...>
 
  120   friend class DualView;
 
  125 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4 
  126   using traits = ViewTraits<DataType, Arg1Type, Arg2Type, Arg3Type>;
 
  128   using traits      = ViewTraits<DataType, Properties...>;
 
  132   using host_mirror_space = 
typename traits::host_mirror_space;
 
  135 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4 
  136   using t_dev = View<typename traits::data_type, Arg1Type, Arg2Type, Arg3Type>;
 
  138   using t_dev       = 
View<
typename traits::data_type, Properties...>;
 
  143   using t_host = 
typename t_dev::HostMirror;
 
  147 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4 
  149       View<typename traits::const_data_type, Arg1Type, Arg2Type, Arg3Type>;
 
  151   using t_dev_const = 
View<
typename traits::const_data_type, Properties...>;
 
  156   using t_host_const = 
typename t_dev_const::HostMirror;
 
  159   using t_dev_const_randomread =
 
  160       View<
typename traits::const_data_type, 
typename traits::array_layout,
 
  161            typename traits::device_type,
 
  162            Kokkos::MemoryTraits<Kokkos::RandomAccess>>;
 
  167   using t_host_const_randomread = 
typename t_dev_const_randomread::HostMirror;
 
  171       View<
typename traits::data_type, 
typename traits::array_layout,
 
  172            typename traits::device_type, MemoryUnmanaged>;
 
  176       View<
typename t_host::data_type, 
typename t_host::array_layout,
 
  177            typename t_host::device_type, MemoryUnmanaged>;
 
  180   using t_dev_const_um =
 
  181       View<
typename traits::const_data_type, 
typename traits::array_layout,
 
  182            typename traits::device_type, MemoryUnmanaged>;
 
  185   using t_host_const_um =
 
  186       View<
typename t_host::const_data_type, 
typename t_host::array_layout,
 
  187            typename t_host::device_type, MemoryUnmanaged>;
 
  190   using t_dev_const_randomread_um =
 
  191       View<
typename t_host::const_data_type, 
typename t_host::array_layout,
 
  192            typename t_host::device_type,
 
  193            Kokkos::MemoryTraits<Kokkos::Unmanaged | Kokkos::RandomAccess>>;
 
  198   using t_host_const_randomread_um =
 
  199       typename t_dev_const_randomread_um::HostMirror;
 
  208   using t_modified_flags = View<unsigned int[2], LayoutLeft, Kokkos::HostSpace>;
 
  209   t_modified_flags modified_flags;
 
  213   static constexpr 
bool impl_dualview_is_single_device =
 
  214       std::is_same_v<typename t_dev::device_type, typename t_host::device_type>;
 
  217 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4 
  239   DualView() = 
default;
 
  250   DualView(
const std::string& label,
 
  251            const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  252            const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  253            const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  254            const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  255            const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  256            const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  257            const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  258            const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
 
  260             Kokkos::view_alloc(typename t_modified_flags::execution_space{},
 
  261                                "DualView::modified_flags")),
 
  262         d_view(label, n0, n1, n2, n3, n4, n5, n6, n7),
 
  263         h_view(create_mirror_view(d_view))  
 
  276   template <
class... P>
 
  277   DualView(
const Impl::ViewCtorProp<P...>& arg_prop,
 
  278            std::enable_if_t<!Impl::ViewCtorProp<P...>::has_pointer,
 
  279                             size_t> 
const n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  280            const size_t n1                   = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  281            const size_t n2                   = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  282            const size_t n3                   = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  283            const size_t n4                   = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  284            const size_t n5                   = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  285            const size_t n6                   = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  286            const size_t n7                   = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
 
  287       : modified_flags(t_modified_flags(
"DualView::modified_flags")) {
 
  288     if constexpr (Impl::ViewCtorProp<P...>::sequential_host_init) {
 
  289       h_view = t_host(arg_prop, n0, n1, n2, n3, n4, n5, n6, n7);
 
  290       static_assert(Impl::ViewCtorProp<P...>::initialize,
 
  291                     "DualView: SequentialHostInit isn't compatible with " 
  292                     "WithoutInitializing!");
 
  293       static_assert(!Impl::ViewCtorProp<P...>::has_execution_space,
 
  294                     "DualView: SequentialHostInit isn't compatible with " 
  295                     "providing an execution space instance!");
 
  297       d_view = Kokkos::create_mirror_view_and_copy(
 
  298           typename traits::memory_space{}, h_view);
 
  300       d_view = t_dev(arg_prop, n0, n1, n2, n3, n4, n5, n6, n7);
 
  303       if constexpr (Kokkos::Impl::has_type<Impl::WithoutInitializing_t,
 
  306             Kokkos::create_mirror_view(Kokkos::WithoutInitializing, d_view);
 
  308         h_view = Kokkos::create_mirror_view(d_view);
 
  313   template <typename DT, typename... DP>
 
  314   DualView(const DualView<DT, DP...>& src)
 
  315       : modified_flags(src.modified_flags),
 
  317         h_view(src.h_view) {}
 
  320   template <
class DT, 
class... DP, 
class Arg0, 
class... Args>
 
  321   DualView(
const DualView<DT, DP...>& src, 
const Arg0& arg0, Args... args)
 
  322       : modified_flags(src.modified_flags),
 
  323         d_view(Kokkos::subview(src.d_view, arg0, args...)),
 
  324         h_view(Kokkos::subview(src.h_view, arg0, args...)) {}
 
  336   DualView(
const t_dev& d_view_, 
const t_host& h_view_)
 
  337       : modified_flags(t_modified_flags(
"DualView::modified_flags")),
 
  340     if (
int(d_view.rank) != 
int(h_view.rank) ||
 
  344           for (
size_t r = 0; r < d_view.rank(); ++r) {
 
  345             if (d_view.extent(r) != h_view.extent(r) ||
 
  346                 d_view.stride(r) != h_view.stride(r))
 
  351         d_view.span() != h_view.span()) {
 
  352       Kokkos::Impl::throw_runtime_exception(
 
  353           "DualView constructed with incompatible views");
 
  356                                    typename t_dev::memory_space>::accessible &&
 
  357         (d_view.data() != h_view.data()))
 
  359           "DualView storing one View constructed from two different Views");
 
  383   template <
class Device>
 
  384   KOKKOS_FUNCTION 
auto view()
 const {
 
  385     if constexpr (std::is_same_v<Device, typename Device::memory_space>) {
 
  386       if constexpr (std::is_same_v<
typename Device::memory_space,
 
  387                                    typename t_dev::memory_space>) {
 
  390         static_assert(std::is_same_v<
typename Device::memory_space,
 
  391                                      typename t_host::memory_space>,
 
  392                       "The template argument is a memory space but doesn't " 
  393                       "match either of DualView's memory spaces!");
 
  397       if constexpr (std::is_same_v<Device, typename Device::execution_space>) {
 
  398         if constexpr (std::is_same_v<
typename Device::execution_space,
 
  399                                      typename t_dev::execution_space>) {
 
  402           static_assert(std::is_same_v<
typename Device::execution_space,
 
  403                                        typename t_host::execution_space>,
 
  404                         "The template argument is an execution space but " 
  405                         "doesn't match either of DualView's execution spaces!");
 
  409         static_assert(std::is_same_v<Device, typename Device::device_type>,
 
  410                       "The template argument is neither a memory space, " 
  411                       "execution space, or device!");
 
  412         if constexpr (std::is_same_v<Device, typename t_dev::device_type>)
 
  415           static_assert(std::is_same_v<Device, typename t_host::device_type>,
 
  416                         "The template argument is a device but " 
  417                         "doesn't match either of DualView's devices!");
 
  424 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE_4 
  425   KOKKOS_INLINE_FUNCTION
 
  426   t_host view_host()
 const { 
return h_view; }
 
  428   KOKKOS_INLINE_FUNCTION
 
  429   t_dev view_device()
 const { 
return d_view; }
 
  431   KOKKOS_INLINE_FUNCTION
 
  432   const t_host& view_host()
 const { 
return h_view; }
 
  434   KOKKOS_INLINE_FUNCTION
 
  435   const t_dev& view_device()
 const { 
return d_view; }
 
  438   KOKKOS_INLINE_FUNCTION constexpr 
bool is_allocated()
 const {
 
  439     return (d_view.is_allocated() && h_view.is_allocated());
 
  442   template <
class Device>
 
  443   static int get_device_side() {
 
  444     constexpr 
bool device_is_memspace =
 
  445         std::is_same_v<Device, typename Device::memory_space>;
 
  446     constexpr 
bool device_is_execspace =
 
  447         std::is_same_v<Device, typename Device::execution_space>;
 
  448     constexpr 
bool device_exec_is_t_dev_exec =
 
  449         std::is_same_v<
typename Device::execution_space,
 
  450                        typename t_dev::execution_space>;
 
  451     constexpr 
bool device_mem_is_t_dev_mem =
 
  452         std::is_same_v<
typename Device::memory_space,
 
  453                        typename t_dev::memory_space>;
 
  454     constexpr 
bool device_exec_is_t_host_exec =
 
  455         std::is_same_v<
typename Device::execution_space,
 
  456                        typename t_host::execution_space>;
 
  457     constexpr 
bool device_mem_is_t_host_mem =
 
  458         std::is_same_v<
typename Device::memory_space,
 
  459                        typename t_host::memory_space>;
 
  460     constexpr 
bool device_is_t_host_device =
 
  461         std::is_same_v<
typename Device::execution_space,
 
  462                        typename t_host::device_type>;
 
  463     constexpr 
bool device_is_t_dev_device =
 
  464         std::is_same_v<
typename Device::memory_space,
 
  465                        typename t_host::device_type>;
 
  468         device_is_t_dev_device || device_is_t_host_device ||
 
  469             (device_is_memspace &&
 
  470              (device_mem_is_t_dev_mem || device_mem_is_t_host_mem)) ||
 
  471             (device_is_execspace &&
 
  472              (device_exec_is_t_dev_exec || device_exec_is_t_host_exec)) ||
 
  473             ((!device_is_execspace && !device_is_memspace) &&
 
  474              ((device_mem_is_t_dev_mem || device_mem_is_t_host_mem) ||
 
  475               (device_exec_is_t_dev_exec || device_exec_is_t_host_exec))),
 
  476         "Template parameter to .sync() must exactly match one of the " 
  477         "DualView's device types or one of the execution or memory spaces");
 
  480     if (device_is_t_dev_device)
 
  482     else if (device_is_t_host_device)
 
  485       if (device_is_memspace) {
 
  486         if (device_mem_is_t_dev_mem) dev = 1;
 
  487         if (device_mem_is_t_host_mem) dev = 0;
 
  488         if (device_mem_is_t_host_mem && device_mem_is_t_dev_mem) dev = -1;
 
  490       if (device_is_execspace) {
 
  491         if (device_exec_is_t_dev_exec) dev = 1;
 
  492         if (device_exec_is_t_host_exec) dev = 0;
 
  493         if (device_exec_is_t_host_exec && device_exec_is_t_dev_exec) dev = -1;
 
  495       if (!device_is_execspace && !device_is_memspace) {
 
  496         if (device_mem_is_t_dev_mem) dev = 1;
 
  497         if (device_mem_is_t_host_mem) dev = 0;
 
  498         if (device_mem_is_t_host_mem && device_mem_is_t_dev_mem) dev = -1;
 
  499         if (device_exec_is_t_dev_exec) dev = 1;
 
  500         if (device_exec_is_t_host_exec) dev = 0;
 
  501         if (device_exec_is_t_host_exec && device_exec_is_t_dev_exec) dev = -1;
 
  506   static constexpr 
const int view_header_size = 128;
 
  507   void impl_report_host_sync() const noexcept {
 
  508     if (Kokkos::Tools::Experimental::get_callbacks().sync_dual_view !=
 
  510       Kokkos::Tools::syncDualView(
 
  512           reinterpret_cast<void*
>(
reinterpret_cast<uintptr_t
>(h_view.data()) -
 
  517   void impl_report_device_sync() const noexcept {
 
  518     if (Kokkos::Tools::Experimental::get_callbacks().sync_dual_view !=
 
  520       Kokkos::Tools::syncDualView(
 
  522           reinterpret_cast<void*
>(
reinterpret_cast<uintptr_t
>(d_view.data()) -
 
  546   template <
class Device, 
class... Args>
 
  547   void sync_impl(std::true_type, Args 
const&... args) {
 
  548     if (modified_flags.data() == 
nullptr) 
return;
 
  550     int dev = get_device_side<Device>();
 
  553       if ((modified_flags(0) > 0) && (modified_flags(0) >= modified_flags(1))) {
 
  554 #ifdef KOKKOS_ENABLE_CUDA 
  555         if (std::is_same<
typename t_dev::memory_space,
 
  556                          Kokkos::CudaUVMSpace>::value) {
 
  557           if (d_view.data() == h_view.data())
 
  558             Kokkos::Impl::cuda_prefetch_pointer(
 
  559                 Impl::get_cuda_space(args...), d_view.data(),
 
  560                 sizeof(
typename t_dev::value_type) * d_view.span(), 
true);
 
  564         deep_copy(args..., d_view, h_view);
 
  565         modified_flags(0) = modified_flags(1) = 0;
 
  566         impl_report_device_sync();
 
  570       if ((modified_flags(1) > 0) && (modified_flags(1) >= modified_flags(0))) {
 
  571 #ifdef KOKKOS_ENABLE_CUDA 
  572         if (std::is_same<
typename t_dev::memory_space,
 
  573                          Kokkos::CudaUVMSpace>::value) {
 
  574           if (d_view.data() == h_view.data())
 
  575             Kokkos::Impl::cuda_prefetch_pointer(
 
  576                 Impl::get_cuda_space(args...), d_view.data(),
 
  577                 sizeof(
typename t_dev::value_type) * d_view.span(), 
false);
 
  581         deep_copy(args..., h_view, d_view);
 
  582         modified_flags(0) = modified_flags(1) = 0;
 
  583         impl_report_host_sync();
 
  586     if constexpr (std::is_same_v<
typename t_host::memory_space,
 
  587                                  typename t_dev::memory_space>) {
 
  588       typename t_dev::execution_space().fence(
 
  589           "Kokkos::DualView<>::sync: fence after syncing DualView");
 
  590       typename t_host::execution_space().fence(
 
  591           "Kokkos::DualView<>::sync: fence after syncing DualView");
 
  595   template <
class Device>
 
  597     if constexpr (impl_dualview_is_single_device) {
 
  605           typename std::is_same<
typename traits::data_type,
 
  606                                 typename traits::non_const_data_type>::type{});
 
  610   template <
class Device, 
class ExecutionSpace>
 
  611   void sync([[maybe_unused]] 
const ExecutionSpace& exec) {
 
  612     if constexpr (impl_dualview_is_single_device)
 
  616           typename std::is_same<
typename traits::data_type,
 
  617                                 typename traits::non_const_data_type>::type{},
 
  623   template <
class Device, 
class... Args>
 
  624   void sync_impl(std::false_type, Args 
const&...) {
 
  625     if (modified_flags.data() == 
nullptr) 
return;
 
  627     int dev = get_device_side<Device>();
 
  630       if ((modified_flags(0) > 0) && (modified_flags(0) >= modified_flags(1))) {
 
  631         Impl::throw_runtime_exception(
 
  632             "Calling sync on a DualView with a const datatype.");
 
  634       impl_report_device_sync();
 
  637       if ((modified_flags(1) > 0) && (modified_flags(1) >= modified_flags(0))) {
 
  638         Impl::throw_runtime_exception(
 
  639             "Calling sync on a DualView with a const datatype.");
 
  641       impl_report_host_sync();
 
  646   template <
typename... Args>
 
  647   void sync_host_impl(Args 
const&... args) {
 
  648     if (!std::is_same_v<
typename traits::data_type,
 
  649                         typename traits::non_const_data_type>)
 
  650       Impl::throw_runtime_exception(
 
  651           "Calling sync_host on a DualView with a const datatype.");
 
  652     if (modified_flags.data() == 
nullptr) 
return;
 
  653     if (modified_flags(1) > modified_flags(0)) {
 
  654 #ifdef KOKKOS_ENABLE_CUDA 
  655       if (std::is_same<
typename t_dev::memory_space,
 
  656                        Kokkos::CudaUVMSpace>::value) {
 
  657         if (d_view.data() == h_view.data())
 
  658           Kokkos::Impl::cuda_prefetch_pointer(
 
  659               Impl::get_cuda_space(args...), d_view.data(),
 
  660               sizeof(
typename t_dev::value_type) * d_view.span(), 
false);
 
  664       deep_copy(args..., h_view, d_view);
 
  665       modified_flags(1) = modified_flags(0) = 0;
 
  666       impl_report_host_sync();
 
  670   template <
class ExecSpace>
 
  671   void sync_host([[maybe_unused]] 
const ExecSpace& exec) {
 
  672     if constexpr (impl_dualview_is_single_device)
 
  675       sync_host_impl(exec);
 
  678     if constexpr (impl_dualview_is_single_device) {
 
  689   template <
typename... Args>
 
  690   void sync_device_impl(Args 
const&... args) {
 
  691     if (!std::is_same_v<
typename traits::data_type,
 
  692                         typename traits::non_const_data_type>)
 
  693       Impl::throw_runtime_exception(
 
  694           "Calling sync_device on a DualView with a const datatype.");
 
  695     if (modified_flags.data() == 
nullptr) 
return;
 
  696     if (modified_flags(0) > modified_flags(1)) {
 
  697 #ifdef KOKKOS_ENABLE_CUDA 
  698       if (std::is_same<
typename t_dev::memory_space,
 
  699                        Kokkos::CudaUVMSpace>::value) {
 
  700         if (d_view.data() == h_view.data())
 
  701           Kokkos::Impl::cuda_prefetch_pointer(
 
  702               Impl::get_cuda_space(args...), d_view.data(),
 
  703               sizeof(
typename t_dev::value_type) * d_view.span(), 
true);
 
  707       deep_copy(args..., d_view, h_view);
 
  708       modified_flags(1) = modified_flags(0) = 0;
 
  709       impl_report_device_sync();
 
  713   template <
class ExecSpace>
 
  714   void sync_device([[maybe_unused]] 
const ExecSpace& exec) {
 
  715     if constexpr (impl_dualview_is_single_device)
 
  718       sync_device_impl(exec);
 
  721     if constexpr (impl_dualview_is_single_device) {
 
  731   template <
class Device>
 
  732   bool need_sync()
 const {
 
  733     if (modified_flags.data() == 
nullptr) 
return false;
 
  734     int dev = get_device_side<Device>();
 
  737       if ((modified_flags(0) > 0) && (modified_flags(0) >= modified_flags(1))) {
 
  742       if ((modified_flags(1) > 0) && (modified_flags(1) >= modified_flags(0))) {
 
  749   inline bool need_sync_host()
 const {
 
  750     if (modified_flags.data() == 
nullptr) 
return false;
 
  751     return modified_flags(0) < modified_flags(1);
 
  754   inline bool need_sync_device()
 const {
 
  755     if (modified_flags.data() == 
nullptr) 
return false;
 
  756     return modified_flags(1) < modified_flags(0);
 
  758   void impl_report_device_modification() {
 
  759     if (Kokkos::Tools::Experimental::get_callbacks().modify_dual_view !=
 
  761       Kokkos::Tools::modifyDualView(
 
  763           reinterpret_cast<void*
>(
reinterpret_cast<uintptr_t
>(d_view.data()) -
 
  768   void impl_report_host_modification() {
 
  769     if (Kokkos::Tools::Experimental::get_callbacks().modify_dual_view !=
 
  771       Kokkos::Tools::modifyDualView(
 
  773           reinterpret_cast<void*
>(
reinterpret_cast<uintptr_t
>(h_view.data()) -
 
  783   template <
class Device>
 
  785     if constexpr (impl_dualview_is_single_device) {
 
  788       if (modified_flags.data() == 
nullptr) 
return;
 
  790       int dev = get_device_side<Device>();
 
  795             (modified_flags(1) > modified_flags(0) ? modified_flags(1)
 
  796                                                    : modified_flags(0)) +
 
  798         impl_report_device_modification();
 
  803             (modified_flags(1) > modified_flags(0) ? modified_flags(1)
 
  804                                                    : modified_flags(0)) +
 
  806         impl_report_host_modification();
 
  809       if (modified_flags(0) && modified_flags(1)) {
 
  810         std::string msg = 
"Kokkos::DualView::modify ERROR: ";
 
  811         msg += 
"Concurrent modification of host and device views ";
 
  812         msg += 
"in DualView \"";
 
  813         msg += d_view.label();
 
  815         Kokkos::abort(msg.c_str());
 
  820   inline void modify_host() {
 
  821     if constexpr (impl_dualview_is_single_device) {
 
  824       if (modified_flags.data() != 
nullptr) {
 
  826             (modified_flags(1) > modified_flags(0) ? modified_flags(1)
 
  827                                                    : modified_flags(0)) +
 
  829         impl_report_host_modification();
 
  830         if (modified_flags(0) && modified_flags(1)) {
 
  831           std::string msg = 
"Kokkos::DualView::modify_host ERROR: ";
 
  832           msg += 
"Concurrent modification of host and device views ";
 
  833           msg += 
"in DualView \"";
 
  834           msg += d_view.label();
 
  836           Kokkos::abort(msg.c_str());
 
  842   inline void modify_device() {
 
  843     if constexpr (impl_dualview_is_single_device) {
 
  846       if (modified_flags.data() != 
nullptr) {
 
  848             (modified_flags(1) > modified_flags(0) ? modified_flags(1)
 
  849                                                    : modified_flags(0)) +
 
  851         impl_report_device_modification();
 
  852         if (modified_flags(0) && modified_flags(1)) {
 
  853           std::string msg = 
"Kokkos::DualView::modify_device ERROR: ";
 
  854           msg += 
"Concurrent modification of host and device views ";
 
  855           msg += 
"in DualView \"";
 
  856           msg += d_view.label();
 
  858           Kokkos::abort(msg.c_str());
 
  864   inline void clear_sync_state() {
 
  865     if (modified_flags.data() != 
nullptr)
 
  866       modified_flags(1) = modified_flags(0) = 0;
 
  878   template <
class... ViewCtorArgs>
 
  879   void impl_realloc(
const size_t n0, 
const size_t n1, 
const size_t n2,
 
  880                     const size_t n3, 
const size_t n4, 
const size_t n5,
 
  881                     const size_t n6, 
const size_t n7,
 
  882                     const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop) {
 
  883     using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
 
  885     static_assert(!alloc_prop_input::has_label,
 
  886                   "The view constructor arguments passed to Kokkos::realloc " 
  887                   "must not include a label!");
 
  889         !alloc_prop_input::has_pointer,
 
  890         "The view constructor arguments passed to Kokkos::realloc must " 
  891         "not include a pointer!");
 
  893         !alloc_prop_input::has_memory_space,
 
  894         "The view constructor arguments passed to Kokkos::realloc must " 
  895         "not include a memory space instance!");
 
  897     const size_t new_extents[8] = {n0, n1, n2, n3, n4, n5, n6, n7};
 
  898     const bool sizeMismatch =
 
  899         Impl::size_mismatch(h_view, h_view.rank_dynamic, new_extents);
 
  902       if constexpr (alloc_prop_input::sequential_host_init) {
 
  903         static_assert(alloc_prop_input::initialize,
 
  904                       "DualView: SequentialHostInit isn't compatible with " 
  905                       "WithoutInitializing!");
 
  906         ::Kokkos::realloc(arg_prop, h_view, n0, n1, n2, n3, n4, n5, n6, n7);
 
  908             create_mirror_view_and_copy(
typename t_dev::memory_space(), h_view);
 
  910         ::Kokkos::realloc(arg_prop, d_view, n0, n1, n2, n3, n4, n5, n6, n7);
 
  911         if constexpr (alloc_prop_input::initialize) {
 
  912           h_view = create_mirror_view(
typename t_host::memory_space(), d_view);
 
  914           h_view = create_mirror_view(Kokkos::WithoutInitializing,
 
  915                                       typename t_host::memory_space(), d_view);
 
  918     } 
else if constexpr (alloc_prop_input::initialize) {
 
  919       if constexpr (alloc_prop_input::has_execution_space) {
 
  920         const auto& exec_space =
 
  921             Impl::get_property<Impl::ExecutionSpaceTag>(arg_prop);
 
  922         ::Kokkos::deep_copy(exec_space, d_view, 
typename t_dev::value_type{});
 
  924         ::Kokkos::deep_copy(d_view, 
typename t_dev::value_type{});
 
  928     if (modified_flags.data() == 
nullptr) {
 
  929       modified_flags = t_modified_flags(
"DualView::modified_flags");
 
  931       modified_flags(1) = modified_flags(0) = 0;
 
  934   template <
class... ViewCtorArgs>
 
  935   void realloc(
const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
 
  936                const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  937                const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  938                const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  939                const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  940                const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  941                const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  942                const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  943                const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
  944     impl_realloc(n0, n1, n2, n3, n4, n5, n6, n7, arg_prop);
 
  947   void realloc(
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  948                const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  949                const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  950                const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  951                const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  952                const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  953                const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  954                const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
  955     impl_realloc(n0, n1, n2, n3, n4, n5, n6, n7, Impl::ViewCtorProp<>{});
 
  958   template <
typename I>
 
  959   std::enable_if_t<Impl::is_view_ctor_property<I>::value> realloc(
 
  960       const I& arg_prop, 
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  961       const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  962       const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  963       const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  964       const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  965       const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  966       const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
  967       const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
  968     impl_realloc(n0, n1, n2, n3, n4, n5, n6, n7, Kokkos::view_alloc(arg_prop));
 
  975   template <
class... ViewCtorArgs>
 
  976   void impl_resize(
const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
 
  977                    const size_t n0, 
const size_t n1, 
const size_t n2,
 
  978                    const size_t n3, 
const size_t n4, 
const size_t n5,
 
  979                    const size_t n6, 
const size_t n7) {
 
  980     using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
 
  982     static_assert(!alloc_prop_input::has_label,
 
  983                   "The view constructor arguments passed to Kokkos::resize " 
  984                   "must not include a label!");
 
  986         !alloc_prop_input::has_pointer,
 
  987         "The view constructor arguments passed to Kokkos::resize must " 
  988         "not include a pointer!");
 
  990         !alloc_prop_input::has_memory_space,
 
  991         "The view constructor arguments passed to Kokkos::resize must " 
  992         "not include a memory space instance!");
 
  994     const size_t new_extents[8] = {n0, n1, n2, n3, n4, n5, n6, n7};
 
  995     const bool sizeMismatch =
 
  996         Impl::size_mismatch(h_view, h_view.rank_dynamic, new_extents);
 
  998     if (modified_flags.data() == 
nullptr) {
 
  999       modified_flags = t_modified_flags(
"DualView::modified_flags");
 
 1002     [[maybe_unused]] 
auto resize_on_device = [&](
const auto& properties) {
 
 1005         ::Kokkos::resize(properties, d_view, n0, n1, n2, n3, n4, n5, n6, n7);
 
 1009         resync_host(properties);
 
 1012         ++modified_flags(1);
 
 1016     [[maybe_unused]] 
auto resize_on_host = [&](
const auto& properties) {
 
 1019         ::Kokkos::resize(properties, h_view, n0, n1, n2, n3, n4, n5, n6, n7);
 
 1023         resync_device(properties);
 
 1026         ++modified_flags(0);
 
 1030     if constexpr (alloc_prop_input::sequential_host_init) {
 
 1031       static_assert(alloc_prop_input::initialize,
 
 1032                     "DualView: SequentialHostInit isn't compatible with " 
 1033                     "WithoutInitializing!");
 
 1034       static_assert(!alloc_prop_input::has_execution_space,
 
 1035                     "DualView: SequentialHostInit isn't compatible with " 
 1036                     "providing an execution space instance!");
 
 1039         sync<typename t_host::memory_space>();
 
 1040         ::Kokkos::resize(arg_prop, h_view, n0, n1, n2, n3, n4, n5, n6, n7);
 
 1042             create_mirror_view_and_copy(
typename t_dev::memory_space(), h_view);
 
 1045     } 
else if constexpr (alloc_prop_input::has_execution_space) {
 
 1046       using ExecSpace = 
typename alloc_prop_input::execution_space;
 
 1047       const auto& exec_space =
 
 1048           Impl::get_property<Impl::ExecutionSpaceTag>(arg_prop);
 
 1049       constexpr 
bool exec_space_can_access_device =
 
 1050           SpaceAccessibility<ExecSpace,
 
 1051                              typename t_dev::memory_space>::accessible;
 
 1052       constexpr 
bool exec_space_can_access_host =
 
 1053           SpaceAccessibility<ExecSpace,
 
 1054                              typename t_host::memory_space>::accessible;
 
 1055       static_assert(exec_space_can_access_device || exec_space_can_access_host);
 
 1056       if constexpr (exec_space_can_access_device) {
 
 1057         sync<typename t_dev::memory_space>(exec_space);
 
 1058         resize_on_device(arg_prop);
 
 1061       if constexpr (exec_space_can_access_host) {
 
 1062         sync<typename t_host::memory_space>(exec_space);
 
 1063         resize_on_host(arg_prop);
 
 1067       if (modified_flags(1) >= modified_flags(0)) {
 
 1068         resize_on_device(arg_prop);
 
 1070         resize_on_host(arg_prop);
 
 1079   template <
class... ViewCtorArgs>
 
 1080   inline void resync_host(Impl::ViewCtorProp<ViewCtorArgs...> 
const&) {
 
 1081     using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
 
 1083     if constexpr (alloc_prop_input::initialize) {
 
 1084       h_view = create_mirror_view(
typename t_host::memory_space(), d_view);
 
 1086       h_view = create_mirror_view(Kokkos::WithoutInitializing,
 
 1087                                   typename t_host::memory_space(), d_view);
 
 1094   template <
class... ViewCtorArgs>
 
 1095   inline void resync_device(Impl::ViewCtorProp<ViewCtorArgs...> 
const&) {
 
 1096     using alloc_prop_input = Impl::ViewCtorProp<ViewCtorArgs...>;
 
 1098     if constexpr (alloc_prop_input::initialize) {
 
 1099       d_view = create_mirror_view(
typename t_dev::memory_space(), h_view);
 
 1102       d_view = create_mirror_view(Kokkos::WithoutInitializing,
 
 1103                                   typename t_dev::memory_space(), h_view);
 
 1108   void resize(
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1109               const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1110               const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1111               const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1112               const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1113               const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1114               const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1115               const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
 1116     impl_resize(Impl::ViewCtorProp<>{}, n0, n1, n2, n3, n4, n5, n6, n7);
 
 1119   template <
class... ViewCtorArgs>
 
 1120   void resize(
const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
 
 1121               const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1122               const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1123               const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1124               const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1125               const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1126               const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1127               const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1128               const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
 1129     impl_resize(arg_prop, n0, n1, n2, n3, n4, n5, n6, n7);
 
 1133   std::enable_if_t<Impl::is_view_ctor_property<I>::value> resize(
 
 1134       const I& arg_prop, 
const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1135       const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1136       const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1137       const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1138       const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1139       const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1140       const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
 
 1141       const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG) {
 
 1142     impl_resize(Kokkos::view_alloc(arg_prop), n0, n1, n2, n3, n4, n5, n6, n7);
 
 1150   KOKKOS_INLINE_FUNCTION constexpr 
size_t span()
 const { 
return d_view.span(); }
 
 1152   KOKKOS_INLINE_FUNCTION 
bool span_is_contiguous()
 const {
 
 1153     return d_view.span_is_contiguous();
 
 1157   template <
typename iType>
 
 1158   void stride(iType* stride_)
 const {
 
 1159     d_view.stride(stride_);
 
 1162   template <
typename iType>
 
 1163   KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<std::is_integral_v<iType>,
 
 1165   extent(
const iType& r)
 const {
 
 1166     return d_view.extent(r);
 
 1169   template <
typename iType>
 
 1170   KOKKOS_INLINE_FUNCTION constexpr std::enable_if_t<std::is_integral_v<iType>,
 
 1172   extent_int(
const iType& r)
 const {
 
 1173     return static_cast<int>(d_view.extent(r));
 
 1193 template <
class D, 
class... P>
 
 1194 struct V2DV<
View<D, P...>> {
 
 1195   using type = DualView<D, P...>;
 
 1199 template <
class DataType, 
class... Properties, 
class... Args>
 
 1200 auto subview(
const DualView<DataType, Properties...>& src, Args&&... args) {
 
 1202   using deduce_subview_type =
 
 1203       decltype(subview(std::declval<View<DataType, Properties...>>(),
 
 1204                        std::forward<Args>(args)...));
 
 1206   return typename Impl::V2DV<deduce_subview_type>::type(
 
 1207       src, std::forward<Args>(args)...);
 
 1221 template <
class DT, 
class... DP, 
class ST, 
class... SP>
 
 1222 void deep_copy(DualView<DT, DP...>& dst, 
const DualView<ST, SP...>& src) {
 
 1223   if (src.need_sync_device()) {
 
 1224     deep_copy(dst.view_host(), src.view_host());
 
 1227     deep_copy(dst.view_device(), src.view_device());
 
 1228     dst.modify_device();
 
 1232 template <
class ExecutionSpace, 
class DT, 
class... DP, 
class ST, 
class... SP>
 
 1233 void deep_copy(
const ExecutionSpace& exec, DualView<DT, DP...>& dst,
 
 1234                const DualView<ST, SP...>& src) {
 
 1235   if (src.need_sync_device()) {
 
 1236     deep_copy(exec, dst.view_host(), src.view_host());
 
 1239     deep_copy(exec, dst.view_device(), src.view_device());
 
 1240     dst.modify_device();
 
 1255 template <
class... Properties, 
class... Args>
 
 1256 void resize(DualView<Properties...>& dv, Args&&... args) noexcept(
 
 1257     noexcept(dv.resize(std::forward<Args>(args)...))) {
 
 1258   dv.resize(std::forward<Args>(args)...);
 
 1261 template <
class... ViewCtorArgs, 
class... Properties, 
class... Args>
 
 1263     const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
 
 1264     DualView<Properties...>& dv,
 
 1265     Args&&... args) noexcept(noexcept(dv.resize(arg_prop,
 
 1266                                                 std::forward<Args>(args)...))) {
 
 1267   dv.resize(arg_prop, std::forward<Args>(args)...);
 
 1270 template <
class I, 
class... Properties, 
class... Args>
 
 1271 std::enable_if_t<Impl::is_view_ctor_property<I>::value> resize(
 
 1272     const I& arg_prop, DualView<Properties...>& dv,
 
 1273     Args&&... args) noexcept(noexcept(dv.resize(arg_prop,
 
 1274                                                 std::forward<Args>(args)...))) {
 
 1275   dv.resize(arg_prop, std::forward<Args>(args)...);
 
 1278 template <
class... ViewCtorArgs, 
class... Properties, 
class... Args>
 
 1279 void realloc(
const Impl::ViewCtorProp<ViewCtorArgs...>& arg_prop,
 
 1280              DualView<Properties...>& dv,
 
 1281              Args&&... args) noexcept(noexcept(dv
 
 1282                                                    .realloc(std::forward<Args>(
 
 1284   dv.realloc(arg_prop, std::forward<Args>(args)...);
 
 1287 template <
class... Properties, 
class... Args>
 
 1288 void realloc(DualView<Properties...>& dv, Args&&... args) noexcept(
 
 1289     noexcept(dv.realloc(std::forward<Args>(args)...))) {
 
 1290   dv.realloc(std::forward<Args>(args)...);
 
 1293 template <
class I, 
class... Properties, 
class... Args>
 
 1294 std::enable_if_t<Impl::is_view_ctor_property<I>::value> realloc(
 
 1295     const I& arg_prop, DualView<Properties...>& dv,
 
 1296     Args&&... args) noexcept(noexcept(dv.realloc(arg_prop,
 
 1299   dv.realloc(arg_prop, std::forward<Args>(args)...);
 
 1304 #ifdef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_DUALVIEW 
 1305 #undef KOKKOS_IMPL_PUBLIC_INCLUDE 
 1306 #undef KOKKOS_IMPL_PUBLIC_INCLUDE_NOTDEFINED_DUALVIEW 
Can AccessSpace access MemorySpace ? 
 
Memory management for host memory.