50 #ifndef KOKKOS_DUALVIEW_HPP 51 #define KOKKOS_DUALVIEW_HPP 53 #include <Kokkos_Core.hpp> 54 #include <impl/Kokkos_Error.hpp> 93 template<
class DataType ,
94 class Arg1Type = void ,
95 class Arg2Type = void ,
96 class Arg3Type =
void>
97 class DualView :
public ViewTraits< DataType , Arg1Type , Arg2Type, Arg3Type >
102 typedef ViewTraits< DataType , Arg1Type , Arg2Type, Arg3Type > traits ;
105 typedef typename traits::host_mirror_space host_mirror_space ;
108 typedef View<
typename traits::data_type ,
115 typedef typename t_dev::HostMirror t_host ;
119 typedef View<
typename traits::const_data_type ,
122 Arg3Type > t_dev_const ;
126 typedef typename t_dev_const::HostMirror t_host_const;
129 typedef View<
typename traits::const_data_type ,
130 typename traits::array_layout ,
131 typename traits::device_type ,
132 MemoryRandomAccess > t_dev_const_randomread ;
137 typedef typename t_dev_const_randomread::HostMirror t_host_const_randomread;
140 typedef View<
typename traits::data_type ,
141 typename traits::array_layout ,
142 typename traits::device_type ,
143 MemoryUnmanaged> t_dev_um;
146 typedef View<
typename t_host::data_type ,
147 typename t_host::array_layout ,
148 typename t_host::device_type ,
149 MemoryUnmanaged> t_host_um;
152 typedef View<
typename traits::const_data_type ,
153 typename traits::array_layout ,
154 typename traits::device_type ,
155 MemoryUnmanaged> t_dev_const_um;
158 typedef View<
typename t_host::const_data_type,
159 typename t_host::array_layout,
160 typename t_host::device_type,
161 MemoryUnmanaged> t_host_const_um;
174 View<unsigned int,LayoutLeft,typename t_host::execution_space> modified_device;
175 View<unsigned int,LayoutLeft,typename t_host::execution_space> modified_host;
187 modified_device (View<unsigned int,LayoutLeft,typename t_host::execution_space> (
"DualView::modified_device")),
188 modified_host (View<unsigned int,LayoutLeft,typename t_host::execution_space> (
"DualView::modified_host"))
200 DualView (
const std::string& label,
209 : d_view (label, n0, n1, n2, n3, n4, n5, n6, n7)
210 , h_view (create_mirror_view (d_view))
211 , modified_device (View<unsigned int,LayoutLeft,typename t_host::execution_space> (
"DualView::modified_device"))
212 , modified_host (View<unsigned int,LayoutLeft,typename t_host::execution_space> (
"DualView::modified_host"))
216 template<
class SS,
class LS,
class DS,
class MS>
217 DualView (
const DualView<SS,LS,DS,MS>& src) :
220 modified_device (src.modified_device),
221 modified_host (src.modified_host)
234 DualView (
const t_dev& d_view_,
const t_host& h_view_) :
237 modified_device (View<unsigned int,LayoutLeft,typename t_host::execution_space> (
"DualView::modified_device")),
238 modified_host (View<unsigned int,LayoutLeft,typename t_host::execution_space> (
"DualView::modified_host"))
240 Impl::assert_shapes_are_equal (d_view.shape (), h_view.shape ());
268 template<
class Device >
269 KOKKOS_INLINE_FUNCTION
270 const typename Impl::if_c<
271 Impl::is_same<
typename t_dev::memory_space,
272 typename Device::memory_space>::value,
274 t_host>::type& view ()
const 278 typename t_dev::memory_space,
279 typename Device::memory_space>::value,
281 t_host >::select (d_view , h_view);
301 template<
class Device>
302 void sync(
const typename Impl::enable_if<
303 ( Impl::is_same< typename traits::data_type , typename traits::non_const_data_type>::value) ||
304 ( Impl::is_same< Device , int>::value)
307 const unsigned int dev =
310 typename t_dev::memory_space,
311 typename Device::memory_space>::value ,
313 unsigned int>::select (1, 0);
316 if ((modified_host () > 0) && (modified_host () >= modified_device ())) {
318 modified_host() = modified_device() = 0;
321 if ((modified_device () > 0) && (modified_device () >= modified_host ())) {
323 modified_host() = modified_device() = 0;
326 if(Impl::is_same<typename t_host::memory_space,typename t_dev::memory_space>::value) {
327 t_dev::execution_space::fence();
328 t_host::execution_space::fence();
332 template<
class Device>
333 void sync (
const typename Impl::enable_if<
334 ( ! Impl::is_same< typename traits::data_type , typename traits::non_const_data_type>::value ) ||
335 ( Impl::is_same< Device , int>::value)
338 const unsigned int dev =
341 typename t_dev::memory_space,
342 typename Device::memory_space>::value,
344 unsigned int>::select (1, 0);
346 if ((modified_host () > 0) && (modified_host () >= modified_device ())) {
347 Impl::throw_runtime_exception(
"Calling sync on a DualView with a const datatype.");
350 if ((modified_device () > 0) && (modified_device () >= modified_host ())) {
351 Impl::throw_runtime_exception(
"Calling sync on a DualView with a const datatype.");
356 template<
class Device>
359 const unsigned int dev =
362 typename t_dev::memory_space,
363 typename Device::memory_space>::value ,
365 unsigned int>::select (1, 0);
368 if ((modified_host () > 0) && (modified_host () >= modified_device ())) {
372 if ((modified_device () > 0) && (modified_device () >= modified_host ())) {
383 template<
class Device>
385 const unsigned int dev =
388 typename t_dev::memory_space,
389 typename Device::memory_space>::value,
391 unsigned int>::select (1, 0);
395 modified_device () = (modified_device () > modified_host () ?
396 modified_device () : modified_host ()) + 1;
399 modified_host () = (modified_device () > modified_host () ?
400 modified_device () : modified_host ()) + 1;
413 void realloc(
const size_t n0 = 0 ,
414 const size_t n1 = 0 ,
415 const size_t n2 = 0 ,
416 const size_t n3 = 0 ,
417 const size_t n4 = 0 ,
418 const size_t n5 = 0 ,
419 const size_t n6 = 0 ,
420 const size_t n7 = 0 ) {
421 ::Kokkos::realloc(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
422 h_view = create_mirror_view( d_view );
425 modified_device() = modified_host() = 0;
432 void resize(
const size_t n0 = 0 ,
433 const size_t n1 = 0 ,
434 const size_t n2 = 0 ,
435 const size_t n3 = 0 ,
436 const size_t n4 = 0 ,
437 const size_t n5 = 0 ,
438 const size_t n6 = 0 ,
439 const size_t n7 = 0 ) {
440 if(modified_device() >= modified_host()) {
442 ::Kokkos::resize(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
443 h_view = create_mirror_view( d_view );
446 modified_device() = modified_device()+1;
451 ::Kokkos::realloc(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
452 t_host temp_view = create_mirror_view( d_view );
460 modified_host() = modified_host()+1;
469 size_t capacity()
const {
470 #if defined( KOKKOS_USING_EXPERIMENTAL_VIEW ) 471 return d_view.span();
473 return d_view.capacity();
478 template<
typename iType>
479 void stride(iType* stride_)
const {
480 d_view.stride(stride_);
484 size_t dimension_0()
const {
return d_view.dimension_0();}
486 size_t dimension_1()
const {
return d_view.dimension_1();}
488 size_t dimension_2()
const {
return d_view.dimension_2();}
490 size_t dimension_3()
const {
return d_view.dimension_3();}
492 size_t dimension_4()
const {
return d_view.dimension_4();}
494 size_t dimension_5()
const {
return d_view.dimension_5();}
496 size_t dimension_6()
const {
return d_view.dimension_6();}
498 size_t dimension_7()
const {
return d_view.dimension_7();}
511 template<
class SrcDataType ,
class SrcArg1Type ,
class SrcArg2Type ,
class SrcArg3Type
512 ,
class SubArg0_type ,
class SubArg1_type ,
class SubArg2_type ,
class SubArg3_type
513 ,
class SubArg4_type ,
class SubArg5_type ,
class SubArg6_type ,
class SubArg7_type
515 struct ViewSubview< DualView< SrcDataType , SrcArg1Type , SrcArg2Type , SrcArg3Type >
516 , SubArg0_type , SubArg1_type , SubArg2_type , SubArg3_type
517 , SubArg4_type , SubArg5_type , SubArg6_type , SubArg7_type >
521 typedef DualView< SrcDataType , SrcArg1Type , SrcArg2Type , SrcArg3Type > SrcViewType ;
523 enum { V0 = Impl::is_same< SubArg0_type , void >::value ? 1 : 0 };
524 enum { V1 = Impl::is_same< SubArg1_type , void >::value ? 1 : 0 };
525 enum { V2 = Impl::is_same< SubArg2_type , void >::value ? 1 : 0 };
526 enum { V3 = Impl::is_same< SubArg3_type , void >::value ? 1 : 0 };
527 enum { V4 = Impl::is_same< SubArg4_type , void >::value ? 1 : 0 };
528 enum { V5 = Impl::is_same< SubArg5_type , void >::value ? 1 : 0 };
529 enum { V6 = Impl::is_same< SubArg6_type , void >::value ? 1 : 0 };
530 enum { V7 = Impl::is_same< SubArg7_type , void >::value ? 1 : 0 };
535 Impl::StaticAssert<( SrcViewType::rank ==
543 V7 ? 7 : 8 ))))))) ))
545 ( SrcViewType::rank ==
546 ( 8 - ( V0 + V1 + V2 + V3 + V4 + V5 + V6 + V7 ) ) )
547 >::value ? SrcViewType::rank : 0 };
549 enum { R0 = Impl::ViewOffsetRange< SubArg0_type >::is_range ? 1 : 0 };
550 enum { R1 = Impl::ViewOffsetRange< SubArg1_type >::is_range ? 1 : 0 };
551 enum { R2 = Impl::ViewOffsetRange< SubArg2_type >::is_range ? 1 : 0 };
552 enum { R3 = Impl::ViewOffsetRange< SubArg3_type >::is_range ? 1 : 0 };
553 enum { R4 = Impl::ViewOffsetRange< SubArg4_type >::is_range ? 1 : 0 };
554 enum { R5 = Impl::ViewOffsetRange< SubArg5_type >::is_range ? 1 : 0 };
555 enum { R6 = Impl::ViewOffsetRange< SubArg6_type >::is_range ? 1 : 0 };
556 enum { R7 = Impl::ViewOffsetRange< SubArg7_type >::is_range ? 1 : 0 };
558 enum { OutputRank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3)
559 + unsigned(R4) + unsigned(R5) + unsigned(R6) + unsigned(R7) };
562 enum { R0_rev = 0 == InputRank ? 0u : (
563 1 == InputRank ? unsigned(R0) : (
564 2 == InputRank ? unsigned(R1) : (
565 3 == InputRank ? unsigned(R2) : (
566 4 == InputRank ? unsigned(R3) : (
567 5 == InputRank ? unsigned(R4) : (
568 6 == InputRank ? unsigned(R5) : (
569 7 == InputRank ? unsigned(R6) : unsigned(R7) ))))))) };
571 typedef typename SrcViewType::array_layout SrcViewLayout ;
574 typedef typename Impl::if_c<
581 ( OutputRank <= 2 && R0 && Impl::is_same<SrcViewLayout,LayoutLeft>::value )
585 ( OutputRank <= 2 && R0_rev && Impl::is_same<SrcViewLayout,LayoutRight>::value )
589 typedef typename Impl::if_c< OutputRank == 0 ,
typename SrcViewType::value_type ,
590 typename Impl::if_c< OutputRank == 1 ,
typename SrcViewType::value_type *,
591 typename Impl::if_c< OutputRank == 2 ,
typename SrcViewType::value_type **,
592 typename Impl::if_c< OutputRank == 3 ,
typename SrcViewType::value_type ***,
593 typename Impl::if_c< OutputRank == 4 ,
typename SrcViewType::value_type ****,
594 typename Impl::if_c< OutputRank == 5 ,
typename SrcViewType::value_type *****,
595 typename Impl::if_c< OutputRank == 6 ,
typename SrcViewType::value_type ******,
596 typename Impl::if_c< OutputRank == 7 ,
typename SrcViewType::value_type *******,
597 typename SrcViewType::value_type ********
598 >::type >::type >::type >::type >::type >::type >::type >::type OutputData ;
604 typedef typename Impl::if_c< Impl::is_space< SrcArg1Type >::value , SrcArg1Type ,
605 typename Impl::if_c< Impl::is_space< SrcArg2Type >::value , SrcArg2Type ,
typename SrcViewType::execution_space
606 >::type >::type OutputSpace ;
613 Impl::if_c< Impl::is_same< SrcViewLayout , OutputViewLayout >::value
614 , Kokkos::DualView< OutputData , SrcArg1Type , SrcArg2Type , SrcArg3Type >
615 , Kokkos::DualView< OutputData , OutputViewLayout , OutputSpace
616 ,
typename SrcViewType::memory_traits >
625 template<
class D ,
class A1 ,
class A2 ,
class A3 ,
627 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
628 , ArgType0 , void , void , void
629 , void , void , void ,
void 631 subview(
const DualView<D,A1,A2,A3> & src ,
632 const ArgType0 & arg0 )
635 Impl::ViewSubview< DualView<D,A1,A2,A3>
636 , ArgType0 , void , void , void
637 , void , void , void ,
void 640 DstViewType sub_view;
641 sub_view.d_view = subview(src.d_view,arg0);
642 sub_view.h_view = subview(src.h_view,arg0);
643 sub_view.modified_device = src.modified_device;
644 sub_view.modified_host = src.modified_host;
649 template<
class D ,
class A1 ,
class A2 ,
class A3 ,
650 class ArgType0 ,
class ArgType1 >
651 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
652 , ArgType0 , ArgType1 , void , void
653 , void , void , void ,
void 655 subview(
const DualView<D,A1,A2,A3> & src ,
656 const ArgType0 & arg0 ,
657 const ArgType1 & arg1 )
660 Impl::ViewSubview< DualView<D,A1,A2,A3>
661 , ArgType0 , ArgType1 , void , void
662 , void , void , void ,
void 665 DstViewType sub_view;
666 sub_view.d_view = subview(src.d_view,arg0,arg1);
667 sub_view.h_view = subview(src.h_view,arg0,arg1);
668 sub_view.modified_device = src.modified_device;
669 sub_view.modified_host = src.modified_host;
673 template<
class D ,
class A1 ,
class A2 ,
class A3 ,
674 class ArgType0 ,
class ArgType1 ,
class ArgType2 >
675 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
676 , ArgType0 , ArgType1 , ArgType2 , void
677 , void , void , void ,
void 679 subview(
const DualView<D,A1,A2,A3> & src ,
680 const ArgType0 & arg0 ,
681 const ArgType1 & arg1 ,
682 const ArgType2 & arg2 )
685 Impl::ViewSubview< DualView<D,A1,A2,A3>
686 , ArgType0 , ArgType1 , ArgType2 , void
687 , void , void , void ,
void 690 DstViewType sub_view;
691 sub_view.d_view = subview(src.d_view,arg0,arg1,arg2);
692 sub_view.h_view = subview(src.h_view,arg0,arg1,arg2);
693 sub_view.modified_device = src.modified_device;
694 sub_view.modified_host = src.modified_host;
698 template<
class D ,
class A1 ,
class A2 ,
class A3 ,
699 class ArgType0 ,
class ArgType1 ,
class ArgType2 ,
class ArgType3 >
700 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
701 , ArgType0 , ArgType1 , ArgType2 , ArgType3
702 , void , void , void ,
void 704 subview(
const DualView<D,A1,A2,A3> & src ,
705 const ArgType0 & arg0 ,
706 const ArgType1 & arg1 ,
707 const ArgType2 & arg2 ,
708 const ArgType3 & arg3 )
711 Impl::ViewSubview< DualView<D,A1,A2,A3>
712 , ArgType0 , ArgType1 , ArgType2 , ArgType3
713 , void , void , void ,
void 716 DstViewType sub_view;
717 sub_view.d_view = subview(src.d_view,arg0,arg1,arg2,arg3);
718 sub_view.h_view = subview(src.h_view,arg0,arg1,arg2,arg3);
719 sub_view.modified_device = src.modified_device;
720 sub_view.modified_host = src.modified_host;
724 template<
class D ,
class A1 ,
class A2 ,
class A3 ,
725 class ArgType0 ,
class ArgType1 ,
class ArgType2 ,
class ArgType3 ,
727 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
728 , ArgType0 , ArgType1 , ArgType2 , ArgType3
729 , ArgType4 , void , void ,
void 731 subview(
const DualView<D,A1,A2,A3> & src ,
732 const ArgType0 & arg0 ,
733 const ArgType1 & arg1 ,
734 const ArgType2 & arg2 ,
735 const ArgType3 & arg3 ,
736 const ArgType4 & arg4 )
739 Impl::ViewSubview< DualView<D,A1,A2,A3>
740 , ArgType0 , ArgType1 , ArgType2 , ArgType3
741 , ArgType4 , void , void ,
void 744 DstViewType sub_view;
745 sub_view.d_view = subview(src.d_view,arg0,arg1,arg2,arg3,arg4);
746 sub_view.h_view = subview(src.h_view,arg0,arg1,arg2,arg3,arg4);
747 sub_view.modified_device = src.modified_device;
748 sub_view.modified_host = src.modified_host;
752 template<
class D ,
class A1 ,
class A2 ,
class A3 ,
753 class ArgType0 ,
class ArgType1 ,
class ArgType2 ,
class ArgType3 ,
754 class ArgType4 ,
class ArgType5 >
755 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
756 , ArgType0 , ArgType1 , ArgType2 , ArgType3
757 , ArgType4 , ArgType5 , void ,
void 759 subview(
const DualView<D,A1,A2,A3> & src ,
760 const ArgType0 & arg0 ,
761 const ArgType1 & arg1 ,
762 const ArgType2 & arg2 ,
763 const ArgType3 & arg3 ,
764 const ArgType4 & arg4 ,
765 const ArgType5 & arg5 )
768 Impl::ViewSubview< DualView<D,A1,A2,A3>
769 , ArgType0 , ArgType1 , ArgType2 , ArgType3
770 , ArgType4 , ArgType5 , void ,
void 773 DstViewType sub_view;
774 sub_view.d_view = subview(src.d_view,arg0,arg1,arg2,arg3,arg4,arg5);
775 sub_view.h_view = subview(src.h_view,arg0,arg1,arg2,arg3,arg4,arg5);
776 sub_view.modified_device = src.modified_device;
777 sub_view.modified_host = src.modified_host;
781 template<
class D ,
class A1 ,
class A2 ,
class A3 ,
782 class ArgType0 ,
class ArgType1 ,
class ArgType2 ,
class ArgType3 ,
783 class ArgType4 ,
class ArgType5 ,
class ArgType6 >
784 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
785 , ArgType0 , ArgType1 , ArgType2 , ArgType3
786 , ArgType4 , ArgType5 , ArgType6 ,
void 788 subview(
const DualView<D,A1,A2,A3> & src ,
789 const ArgType0 & arg0 ,
790 const ArgType1 & arg1 ,
791 const ArgType2 & arg2 ,
792 const ArgType3 & arg3 ,
793 const ArgType4 & arg4 ,
794 const ArgType5 & arg5 ,
795 const ArgType6 & arg6 )
798 Impl::ViewSubview< DualView<D,A1,A2,A3>
799 , ArgType0 , ArgType1 , ArgType2 , ArgType3
800 , ArgType4 , ArgType5 , ArgType6 ,
void 803 DstViewType sub_view;
804 sub_view.d_view = subview(src.d_view,arg0,arg1,arg2,arg3,arg4,arg5,arg6);
805 sub_view.h_view = subview(src.h_view,arg0,arg1,arg2,arg3,arg4,arg5,arg6);
806 sub_view.modified_device = src.modified_device;
807 sub_view.modified_host = src.modified_host;
811 template<
class D ,
class A1 ,
class A2 ,
class A3 ,
812 class ArgType0 ,
class ArgType1 ,
class ArgType2 ,
class ArgType3 ,
813 class ArgType4 ,
class ArgType5 ,
class ArgType6 ,
class ArgType7 >
814 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
815 , ArgType0 , ArgType1 , ArgType2 , ArgType3
816 , ArgType4 , ArgType5 , ArgType6 , ArgType7
818 subview(
const DualView<D,A1,A2,A3> & src ,
819 const ArgType0 & arg0 ,
820 const ArgType1 & arg1 ,
821 const ArgType2 & arg2 ,
822 const ArgType3 & arg3 ,
823 const ArgType4 & arg4 ,
824 const ArgType5 & arg5 ,
825 const ArgType6 & arg6 ,
826 const ArgType7 & arg7 )
829 Impl::ViewSubview< DualView<D,A1,A2,A3>
830 , ArgType0 , ArgType1 , ArgType2 , ArgType3
831 , ArgType4 , ArgType5 , ArgType6 , ArgType7
834 DstViewType sub_view;
835 sub_view.d_view = subview(src.d_view,arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7);
836 sub_view.h_view = subview(src.h_view,arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7);
837 sub_view.modified_device = src.modified_device;
838 sub_view.modified_host = src.modified_host;
846 template<
class DT ,
class DL ,
class DD ,
class DM ,
847 class ST ,
class SL ,
class SD ,
class SM >
850 const DualView<ST,SL,SD,SM>& src )
852 if (src.modified_device () >= src.modified_host ()) {
854 dst.template modify<typename DualView<DT,DL,DD,DM>::device_type> ();
857 dst.template modify<typename DualView<DT,DL,DD,DM>::host_mirror_space> ();
861 template<
class ExecutionSpace ,
862 class DT ,
class DL ,
class DD ,
class DM ,
863 class ST ,
class SL ,
class SD ,
class SM >
866 DualView<DT,DL,DD,DM> dst,
867 const DualView<ST,SL,SD,SM>& src )
869 if (src.modified_device () >= src.modified_host ()) {
870 deep_copy (exec, dst.d_view, src.d_view);
871 dst.template modify<typename DualView<DT,DL,DD,DM>::device_type> ();
873 deep_copy (exec, dst.h_view, src.h_view);
874 dst.template modify<typename DualView<DT,DL,DD,DM>::host_mirror_space> ();
void deep_copy(const View< DT, DL, DD, DM, DS > &dst, typename Impl::enable_if<(Impl::is_same< typename ViewTraits< DT, DL, DD, DM >::non_const_value_type, typename ViewTraits< DT, DL, DD, DM >::value_type >::value), typename ViewTraits< DT, DL, DD, DM >::const_value_type >::type &value)
Deep copy a value into a view.
Memory layout tag indicated arbitrarily strided multi-index mapping into contiguous memory...
void resize(View< T, L, D, M, S > &v, const typename Impl::enable_if< ViewTraits< T, L, D, M >::is_managed, size_t >::type n0, const size_t n1=0, const size_t n2=0, const size_t n3=0, const size_t n4=0, const size_t n5=0, const size_t n6=0, const size_t n7=0)
Resize a view with copying old data to new data at the corresponding indices.
void realloc(View< T, L, D, M, S > &v, const typename Impl::enable_if< ViewTraits< T, L, D, M >::is_managed, size_t >::type n0, const size_t n1=0, const size_t n2=0, const size_t n3=0, const size_t n4=0, const size_t n5=0, const size_t n6=0, const size_t n7=0)
Reallocate a view without copying old data to new data.