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 ,
119 typedef View<
typename traits::const_data_type ,
122 Arg3Type > t_dev_const ;
129 typedef View<
typename traits::const_data_type ,
130 typename traits::array_layout ,
131 typename traits::device_type ,
132 Kokkos::MemoryTraits<Kokkos::RandomAccess> > t_dev_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;
164 typedef View<
typename t_host::const_data_type ,
165 typename t_host::array_layout ,
166 typename t_host::device_type ,
167 Kokkos::MemoryTraits<Kokkos::Unmanaged|Kokkos::RandomAccess> > t_dev_const_randomread_um ;
185 View<unsigned int,LayoutLeft,typename t_host::execution_space> modified_device;
186 View<unsigned int,LayoutLeft,typename t_host::execution_space> modified_host;
198 modified_device (
View<unsigned int,LayoutLeft,typename t_host::execution_space> (
"DualView::modified_device")),
199 modified_host (
View<unsigned int,LayoutLeft,typename t_host::execution_space> (
"DualView::modified_host"))
211 DualView (
const std::string& label,
220 : d_view (label, n0, n1, n2, n3, n4, n5, n6, n7)
221 , h_view (create_mirror_view (d_view))
222 , modified_device (
View<unsigned int,LayoutLeft,typename t_host::execution_space> (
"DualView::modified_device"))
223 , modified_host (
View<unsigned int,LayoutLeft,typename t_host::execution_space> (
"DualView::modified_host"))
227 template<
class SS,
class LS,
class DS,
class MS>
228 DualView (
const DualView<SS,LS,DS,MS>& src) :
231 modified_device (src.modified_device),
232 modified_host (src.modified_host)
236 template<
class SD,
class S1 ,
class S2 ,
class S3
237 ,
class Arg0 ,
class ... Args >
238 DualView(
const DualView<SD,S1,S2,S3> & src
242 : d_view(
Kokkos::subview( src.d_view , arg0 , args ... ) )
243 , h_view(
Kokkos::subview( src.h_view , arg0 , args ... ) )
244 , modified_device (src.modified_device)
245 , modified_host (src.modified_host)
258 DualView (
const t_dev& d_view_,
const t_host& h_view_) :
261 modified_device (
View<unsigned int,LayoutLeft,typename t_host::execution_space> (
"DualView::modified_device")),
262 modified_host (
View<unsigned int,LayoutLeft,typename t_host::execution_space> (
"DualView::modified_host"))
264 if (
int(d_view.rank) !=
int(h_view.rank) ||
265 d_view.dimension_0() != h_view.dimension_0() ||
266 d_view.dimension_1() != h_view.dimension_1() ||
267 d_view.dimension_2() != h_view.dimension_2() ||
268 d_view.dimension_3() != h_view.dimension_3() ||
269 d_view.dimension_4() != h_view.dimension_4() ||
270 d_view.dimension_5() != h_view.dimension_5() ||
271 d_view.dimension_6() != h_view.dimension_6() ||
272 d_view.dimension_7() != h_view.dimension_7() ||
273 d_view.stride_0() != h_view.stride_0() ||
274 d_view.stride_1() != h_view.stride_1() ||
275 d_view.stride_2() != h_view.stride_2() ||
276 d_view.stride_3() != h_view.stride_3() ||
277 d_view.stride_4() != h_view.stride_4() ||
278 d_view.stride_5() != h_view.stride_5() ||
279 d_view.stride_6() != h_view.stride_6() ||
280 d_view.stride_7() != h_view.stride_7() ||
281 d_view.span() != h_view.span() ) {
282 Kokkos::Impl::throw_runtime_exception(
"DualView constructed with incompatible views");
311 template<
class Device >
312 KOKKOS_INLINE_FUNCTION
313 const typename Impl::if_c<
314 std::is_same<
typename t_dev::memory_space,
315 typename Device::memory_space>::value,
317 t_host>::type& view ()
const 321 typename t_dev::memory_space,
322 typename Device::memory_space>::value,
324 t_host >::select (d_view , h_view);
344 template<
class Device>
345 void sync(
const typename Impl::enable_if<
346 ( std::is_same< typename traits::data_type , typename traits::non_const_data_type>::value) ||
347 ( std::is_same< Device , int>::value)
350 const unsigned int dev =
353 typename t_dev::memory_space,
354 typename Device::memory_space>::value ,
356 unsigned int>::select (1, 0);
359 if ((modified_host () > 0) && (modified_host () >= modified_device ())) {
361 modified_host() = modified_device() = 0;
364 if ((modified_device () > 0) && (modified_device () >= modified_host ())) {
366 modified_host() = modified_device() = 0;
369 if(std::is_same<typename t_host::memory_space,typename t_dev::memory_space>::value) {
370 t_dev::execution_space::fence();
371 t_host::execution_space::fence();
375 template<
class Device>
376 void sync (
const typename Impl::enable_if<
377 ( ! std::is_same< typename traits::data_type , typename traits::non_const_data_type>::value ) ||
378 ( std::is_same< Device , int>::value)
381 const unsigned int dev =
384 typename t_dev::memory_space,
385 typename Device::memory_space>::value,
387 unsigned int>::select (1, 0);
389 if ((modified_host () > 0) && (modified_host () >= modified_device ())) {
390 Impl::throw_runtime_exception(
"Calling sync on a DualView with a const datatype.");
393 if ((modified_device () > 0) && (modified_device () >= modified_host ())) {
394 Impl::throw_runtime_exception(
"Calling sync on a DualView with a const datatype.");
399 template<
class Device>
400 bool need_sync()
const 402 const unsigned int dev =
405 typename t_dev::memory_space,
406 typename Device::memory_space>::value ,
408 unsigned int>::select (1, 0);
411 if ((modified_host () > 0) && (modified_host () >= modified_device ())) {
415 if ((modified_device () > 0) && (modified_device () >= modified_host ())) {
426 template<
class Device>
428 const unsigned int dev =
431 typename t_dev::memory_space,
432 typename Device::memory_space>::value,
434 unsigned int>::select (1, 0);
438 modified_device () = (modified_device () > modified_host () ?
439 modified_device () : modified_host ()) + 1;
442 modified_host () = (modified_device () > modified_host () ?
443 modified_device () : modified_host ()) + 1;
456 void realloc(
const size_t n0 = 0 ,
457 const size_t n1 = 0 ,
458 const size_t n2 = 0 ,
459 const size_t n3 = 0 ,
460 const size_t n4 = 0 ,
461 const size_t n5 = 0 ,
462 const size_t n6 = 0 ,
463 const size_t n7 = 0 ) {
464 ::Kokkos::realloc(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
465 h_view = create_mirror_view( d_view );
468 modified_device() = modified_host() = 0;
475 void resize(
const size_t n0 = 0 ,
476 const size_t n1 = 0 ,
477 const size_t n2 = 0 ,
478 const size_t n3 = 0 ,
479 const size_t n4 = 0 ,
480 const size_t n5 = 0 ,
481 const size_t n6 = 0 ,
482 const size_t n7 = 0 ) {
483 if(modified_device() >= modified_host()) {
485 ::Kokkos::resize(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
486 h_view = create_mirror_view( d_view );
489 modified_device() = modified_device()+1;
494 ::Kokkos::realloc(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
495 t_host temp_view = create_mirror_view( d_view );
503 modified_host() = modified_host()+1;
512 size_t capacity()
const {
513 return d_view.span();
517 template<
typename iType>
518 void stride(iType* stride_)
const {
519 d_view.stride(stride_);
523 size_t dimension_0()
const {
return d_view.dimension_0();}
525 size_t dimension_1()
const {
return d_view.dimension_1();}
527 size_t dimension_2()
const {
return d_view.dimension_2();}
529 size_t dimension_3()
const {
return d_view.dimension_3();}
531 size_t dimension_4()
const {
return d_view.dimension_4();}
533 size_t dimension_5()
const {
return d_view.dimension_5();}
535 size_t dimension_6()
const {
return d_view.dimension_6();}
537 size_t dimension_7()
const {
return d_view.dimension_7();}
553 template<
class D,
class A1,
class A2,
class A3,
class ... Args >
554 struct DualViewSubview {
556 typedef typename Kokkos::Experimental::Impl::ViewMapping
560 >::traits_type dst_traits ;
562 typedef Kokkos::DualView
563 <
typename dst_traits::data_type
564 ,
typename dst_traits::array_layout
565 ,
typename dst_traits::device_type
566 ,
typename dst_traits::memory_traits
573 template<
class D ,
class A1 ,
class A2 ,
class A3 ,
class ... Args >
574 typename Impl::DualViewSubview<D,A1,A2,A3,Args...>::type
575 subview(
const DualView<D,A1,A2,A3> & src , Args ... args )
578 Impl::DualViewSubview<D,A1,A2,A3,Args...>::type( src , args ... );
592 template<
class DT ,
class DL ,
class DD ,
class DM ,
593 class ST ,
class SL ,
class SD ,
class SM >
596 const DualView<ST,SL,SD,SM>& src )
598 if (src.modified_device () >= src.modified_host ()) {
600 dst.template modify<typename DualView<DT,DL,DD,DM>::device_type> ();
603 dst.template modify<typename DualView<DT,DL,DD,DM>::host_mirror_space> ();
607 template<
class ExecutionSpace ,
608 class DT ,
class DL ,
class DD ,
class DM ,
609 class ST ,
class SL ,
class SD ,
class SM >
612 DualView<DT,DL,DD,DM> dst,
613 const DualView<ST,SL,SD,SM>& src )
615 if (src.modified_device () >= src.modified_host ()) {
616 deep_copy (exec, dst.d_view, src.d_view);
617 dst.template modify<typename DualView<DT,DL,DD,DM>::device_type> ();
619 deep_copy (exec, dst.h_view, src.h_view);
620 dst.template modify<typename DualView<DT,DL,DD,DM>::host_mirror_space> ();
std::enable_if< std::is_same< typename Kokkos::View< T, P... >::array_layout, Kokkos::LayoutLeft >::value||std::is_same< typename Kokkos::View< T, P... >::array_layout, Kokkos::LayoutRight >::value >::type resize(Kokkos::View< T, P... > &v, const size_t n0=0, 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.
std::enable_if< std::is_same< typename Kokkos::View< T, P... >::array_layout, Kokkos::LayoutLeft >::value||std::is_same< typename Kokkos::View< T, P... >::array_layout, Kokkos::LayoutRight >::value >::type realloc(Kokkos::View< T, P... > &v, const size_t n0=0, 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 discarding old data.
void deep_copy(const View< DT, DP... > &dst, typename ViewTraits< DT, DP... >::const_value_type &value, typename std::enable_if< std::is_same< typename ViewTraits< DT, DP... >::specialize, void >::value >::type *=0)
Deep copy a value from Host memory into a view.
View< typename traits::non_const_data_type, typename traits::array_layout, typename traits::host_mirror_space > HostMirror
Compatible HostMirror view.
Traits class for accessing attributes of a View.