Kokkos Core Kernels Package  Version of the Day
Kokkos_DualView.hpp
Go to the documentation of this file.
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 2.0
6 // Copyright (2014) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact H. Carter Edwards (hcedwar@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 */
43 
49 
50 #ifndef KOKKOS_DUALVIEW_HPP
51 #define KOKKOS_DUALVIEW_HPP
52 
53 #include <Kokkos_Core.hpp>
54 #include <impl/Kokkos_Error.hpp>
55 
56 namespace Kokkos {
57 
58 /* \class DualView
59  * \brief Container to manage mirroring a Kokkos::View that lives
60  * in device memory with a Kokkos::View that lives in host memory.
61  *
62  * This class provides capabilities to manage data which exists in two
63  * memory spaces at the same time. It keeps views of the same layout
64  * on two memory spaces as well as modified flags for both
65  * allocations. Users are responsible for setting the modified flags
66  * manually if they change the data in either memory space, by calling
67  * the sync() method templated on the device where they modified the
68  * data. Users may synchronize data by calling the modify() function,
69  * templated on the device towards which they want to synchronize
70  * (i.e., the target of the one-way copy operation).
71  *
72  * The DualView class also provides convenience methods such as
73  * realloc, resize and capacity which call the appropriate methods of
74  * the underlying Kokkos::View objects.
75  *
76  * The four template arguments are the same as those of Kokkos::View.
77  * (Please refer to that class' documentation for a detailed
78  * description.)
79  *
80  * \tparam DataType The type of the entries stored in the container.
81  *
82  * \tparam Layout The array's layout in memory.
83  *
84  * \tparam Device The Kokkos Device type. If its memory space is
85  * not the same as the host's memory space, then DualView will
86  * contain two separate Views: one in device memory, and one in
87  * host memory. Otherwise, DualView will only store one View.
88  *
89  * \tparam MemoryTraits (optional) The user's intended memory access
90  * behavior. Please see the documentation of Kokkos::View for
91  * examples. The default suffices for most users.
92  */
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 >
98 {
99 public:
101 
102  typedef ViewTraits< DataType , Arg1Type , Arg2Type, Arg3Type > traits ;
103 
105  typedef typename traits::host_mirror_space host_mirror_space ;
106 
108  typedef View< typename traits::data_type ,
109  Arg1Type ,
110  Arg2Type ,
111  Arg3Type > t_dev ;
112 
115  typedef typename t_dev::HostMirror t_host ;
116 
119  typedef View< typename traits::const_data_type ,
120  Arg1Type ,
121  Arg2Type ,
122  Arg3Type > t_dev_const ;
123 
126  typedef typename t_dev_const::HostMirror t_host_const;
127 
129  typedef View< typename traits::const_data_type ,
130  typename traits::array_layout ,
131  typename traits::device_type ,
132  MemoryRandomAccess > t_dev_const_randomread ;
133 
137  typedef typename t_dev_const_randomread::HostMirror t_host_const_randomread;
138 
140  typedef View< typename traits::data_type ,
141  typename traits::array_layout ,
142  typename traits::device_type ,
143  MemoryUnmanaged> t_dev_um;
144 
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;
150 
152  typedef View< typename traits::const_data_type ,
153  typename traits::array_layout ,
154  typename traits::device_type ,
155  MemoryUnmanaged> t_dev_const_um;
156 
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;
162 
164 
166 
167  t_dev d_view;
168  t_host h_view;
169 
171 
173 
174  View<unsigned int,LayoutLeft,typename t_host::execution_space> modified_device;
175  View<unsigned int,LayoutLeft,typename t_host::execution_space> modified_host;
176 
178 
180 
186  DualView () :
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"))
189  {}
190 
200  DualView (const std::string& label,
201  const size_t n0 = 0,
202  const size_t n1 = 0,
203  const size_t n2 = 0,
204  const size_t n3 = 0,
205  const size_t n4 = 0,
206  const size_t n5 = 0,
207  const size_t n6 = 0,
208  const size_t n7 = 0)
209  : d_view (label, n0, n1, n2, n3, n4, n5, n6, n7)
210  , h_view (create_mirror_view (d_view)) // without UVM, host View mirrors
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"))
213  {}
214 
216  template<class SS, class LS, class DS, class MS>
217  DualView (const DualView<SS,LS,DS,MS>& src) :
218  d_view (src.d_view),
219  h_view (src.h_view),
220  modified_device (src.modified_device),
221  modified_host (src.modified_host)
222  {}
223 
225  template< class SD, class S1 , class S2 , class S3
226  , class Arg0 , class ... Args >
227  DualView( const DualView<SD,S1,S2,S3> & src
228  , const Arg0 & arg0
229  , Args ... args
230  )
231  : d_view( Kokkos::subview( src.d_view , arg0 , args ... ) )
232  , h_view( Kokkos::subview( src.h_view , arg0 , args ... ) )
233  , modified_device (src.modified_device)
234  , modified_host (src.modified_host)
235  {}
236 
247  DualView (const t_dev& d_view_, const t_host& h_view_) :
248  d_view (d_view_),
249  h_view (h_view_),
250  modified_device (View<unsigned int,LayoutLeft,typename t_host::execution_space> ("DualView::modified_device")),
251  modified_host (View<unsigned int,LayoutLeft,typename t_host::execution_space> ("DualView::modified_host"))
252  {
253 #if ! defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
254  Impl::assert_shapes_are_equal (d_view.shape (), h_view.shape ());
255 #else
256  if ( d_view.rank != h_view.rank ||
257  d_view.dimension_0() != h_view.dimension_0() ||
258  d_view.dimension_1() != h_view.dimension_1() ||
259  d_view.dimension_2() != h_view.dimension_2() ||
260  d_view.dimension_3() != h_view.dimension_3() ||
261  d_view.dimension_4() != h_view.dimension_4() ||
262  d_view.dimension_5() != h_view.dimension_5() ||
263  d_view.dimension_6() != h_view.dimension_6() ||
264  d_view.dimension_7() != h_view.dimension_7() ||
265  d_view.stride_0() != h_view.stride_0() ||
266  d_view.stride_1() != h_view.stride_1() ||
267  d_view.stride_2() != h_view.stride_2() ||
268  d_view.stride_3() != h_view.stride_3() ||
269  d_view.stride_4() != h_view.stride_4() ||
270  d_view.stride_5() != h_view.stride_5() ||
271  d_view.stride_6() != h_view.stride_6() ||
272  d_view.stride_7() != h_view.stride_7() ||
273  d_view.span() != h_view.span() ) {
274  Kokkos::Impl::throw_runtime_exception("DualView constructed with incompatible views");
275  }
276 #endif
277  }
278 
280 
282 
304  template< class Device >
305  KOKKOS_INLINE_FUNCTION
306  const typename Impl::if_c<
307  Impl::is_same<typename t_dev::memory_space,
308  typename Device::memory_space>::value,
309  t_dev,
310  t_host>::type& view () const
311  {
312  return Impl::if_c<
313  Impl::is_same<
314  typename t_dev::memory_space,
315  typename Device::memory_space>::value,
316  t_dev,
317  t_host >::select (d_view , h_view);
318  }
319 
337  template<class Device>
338  void sync( const typename Impl::enable_if<
339  ( Impl::is_same< typename traits::data_type , typename traits::non_const_data_type>::value) ||
340  ( Impl::is_same< Device , int>::value)
341  , int >::type& = 0)
342  {
343  const unsigned int dev =
344  Impl::if_c<
345  Impl::is_same<
346  typename t_dev::memory_space,
347  typename Device::memory_space>::value ,
348  unsigned int,
349  unsigned int>::select (1, 0);
350 
351  if (dev) { // if Device is the same as DualView's device type
352  if ((modified_host () > 0) && (modified_host () >= modified_device ())) {
353  deep_copy (d_view, h_view);
354  modified_host() = modified_device() = 0;
355  }
356  } else { // hopefully Device is the same as DualView's host type
357  if ((modified_device () > 0) && (modified_device () >= modified_host ())) {
358  deep_copy (h_view, d_view);
359  modified_host() = modified_device() = 0;
360  }
361  }
362  if(Impl::is_same<typename t_host::memory_space,typename t_dev::memory_space>::value) {
363  t_dev::execution_space::fence();
364  t_host::execution_space::fence();
365  }
366  }
367 
368  template<class Device>
369  void sync ( const typename Impl::enable_if<
370  ( ! Impl::is_same< typename traits::data_type , typename traits::non_const_data_type>::value ) ||
371  ( Impl::is_same< Device , int>::value)
372  , int >::type& = 0 )
373  {
374  const unsigned int dev =
375  Impl::if_c<
376  Impl::is_same<
377  typename t_dev::memory_space,
378  typename Device::memory_space>::value,
379  unsigned int,
380  unsigned int>::select (1, 0);
381  if (dev) { // if Device is the same as DualView's device type
382  if ((modified_host () > 0) && (modified_host () >= modified_device ())) {
383  Impl::throw_runtime_exception("Calling sync on a DualView with a const datatype.");
384  }
385  } else { // hopefully Device is the same as DualView's host type
386  if ((modified_device () > 0) && (modified_device () >= modified_host ())) {
387  Impl::throw_runtime_exception("Calling sync on a DualView with a const datatype.");
388  }
389  }
390  }
391 
392  template<class Device>
393  bool need_sync()
394  {
395  const unsigned int dev =
396  Impl::if_c<
397  Impl::is_same<
398  typename t_dev::memory_space,
399  typename Device::memory_space>::value ,
400  unsigned int,
401  unsigned int>::select (1, 0);
402 
403  if (dev) { // if Device is the same as DualView's device type
404  if ((modified_host () > 0) && (modified_host () >= modified_device ())) {
405  return true;
406  }
407  } else { // hopefully Device is the same as DualView's host type
408  if ((modified_device () > 0) && (modified_device () >= modified_host ())) {
409  return true;
410  }
411  }
412  return false;
413  }
419  template<class Device>
420  void modify () {
421  const unsigned int dev =
422  Impl::if_c<
423  Impl::is_same<
424  typename t_dev::memory_space,
425  typename Device::memory_space>::value,
426  unsigned int,
427  unsigned int>::select (1, 0);
428 
429  if (dev) { // if Device is the same as DualView's device type
430  // Increment the device's modified count.
431  modified_device () = (modified_device () > modified_host () ?
432  modified_device () : modified_host ()) + 1;
433  } else { // hopefully Device is the same as DualView's host type
434  // Increment the host's modified count.
435  modified_host () = (modified_device () > modified_host () ?
436  modified_device () : modified_host ()) + 1;
437  }
438  }
439 
441 
443 
449  void realloc( const size_t n0 = 0 ,
450  const size_t n1 = 0 ,
451  const size_t n2 = 0 ,
452  const size_t n3 = 0 ,
453  const size_t n4 = 0 ,
454  const size_t n5 = 0 ,
455  const size_t n6 = 0 ,
456  const size_t n7 = 0 ) {
457  ::Kokkos::realloc(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
458  h_view = create_mirror_view( d_view );
459 
460  /* Reset dirty flags */
461  modified_device() = modified_host() = 0;
462  }
463 
468  void resize( const size_t n0 = 0 ,
469  const size_t n1 = 0 ,
470  const size_t n2 = 0 ,
471  const size_t n3 = 0 ,
472  const size_t n4 = 0 ,
473  const size_t n5 = 0 ,
474  const size_t n6 = 0 ,
475  const size_t n7 = 0 ) {
476  if(modified_device() >= modified_host()) {
477  /* Resize on Device */
478  ::Kokkos::resize(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
479  h_view = create_mirror_view( d_view );
480 
481  /* Mark Device copy as modified */
482  modified_device() = modified_device()+1;
483 
484  } else {
485  /* Realloc on Device */
486 
487  ::Kokkos::realloc(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
488  t_host temp_view = create_mirror_view( d_view );
489 
490  /* Remap on Host */
491  Kokkos::deep_copy( temp_view , h_view );
492 
493  h_view = temp_view;
494 
495  /* Mark Host copy as modified */
496  modified_host() = modified_host()+1;
497  }
498  }
499 
501 
503 
505  size_t capacity() const {
506 #if defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
507  return d_view.span();
508 #else
509  return d_view.capacity();
510 #endif
511  }
512 
514  template< typename iType>
515  void stride(iType* stride_) const {
516  d_view.stride(stride_);
517  }
518 
519  /* \brief return size of dimension 0 */
520  size_t dimension_0() const {return d_view.dimension_0();}
521  /* \brief return size of dimension 1 */
522  size_t dimension_1() const {return d_view.dimension_1();}
523  /* \brief return size of dimension 2 */
524  size_t dimension_2() const {return d_view.dimension_2();}
525  /* \brief return size of dimension 3 */
526  size_t dimension_3() const {return d_view.dimension_3();}
527  /* \brief return size of dimension 4 */
528  size_t dimension_4() const {return d_view.dimension_4();}
529  /* \brief return size of dimension 5 */
530  size_t dimension_5() const {return d_view.dimension_5();}
531  /* \brief return size of dimension 6 */
532  size_t dimension_6() const {return d_view.dimension_6();}
533  /* \brief return size of dimension 7 */
534  size_t dimension_7() const {return d_view.dimension_7();}
535 
537 };
538 
539 } // namespace Kokkos
540 
541 //----------------------------------------------------------------------------
542 //----------------------------------------------------------------------------
543 //
544 // Partial specializations of Kokkos::subview() for DualView objects.
545 //
546 
547 #if defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
548 
549 namespace Kokkos {
550 namespace Impl {
551 
552 template< class D, class A1, class A2, class A3, class ... Args >
553 struct DualViewSubview {
554 
555  typedef typename Kokkos::Experimental::Impl::ViewMapping
556  < void
558  , Args ...
559  >::traits_type dst_traits ;
560 
561  typedef Kokkos::DualView
562  < typename dst_traits::data_type
563  , typename dst_traits::array_layout
564  , typename dst_traits::device_type
565  , typename dst_traits::memory_traits
566  > type ;
567 };
568 
569 } /* namespace Impl */
570 
571 
572 template< class D , class A1 , class A2 , class A3 , class ... Args >
573 typename Impl::DualViewSubview<D,A1,A2,A3,Args...>::type
574 subview( const DualView<D,A1,A2,A3> & src , Args ... args )
575 {
576  return typename
577  Impl::DualViewSubview<D,A1,A2,A3,Args...>::type( src , args ... );
578 }
579 
580 } /* namespace Kokkos */
581 
582 #else
583 
584 //----------------------------------------------------------------------------
585 //----------------------------------------------------------------------------
586 //
587 // Partial specializations of Kokkos::subview() for DualView objects.
588 //
589 
590 namespace Kokkos {
591 namespace Impl {
592 
593 template< class SrcDataType , class SrcArg1Type , class SrcArg2Type , class SrcArg3Type
594  , class SubArg0_type , class SubArg1_type , class SubArg2_type , class SubArg3_type
595  , class SubArg4_type , class SubArg5_type , class SubArg6_type , class SubArg7_type
596  >
597 struct ViewSubview< DualView< SrcDataType , SrcArg1Type , SrcArg2Type , SrcArg3Type >
598  , SubArg0_type , SubArg1_type , SubArg2_type , SubArg3_type
599  , SubArg4_type , SubArg5_type , SubArg6_type , SubArg7_type >
600 {
601 private:
602 
603  typedef DualView< SrcDataType , SrcArg1Type , SrcArg2Type , SrcArg3Type > SrcViewType ;
604 
605  enum { V0 = Impl::is_same< SubArg0_type , void >::value ? 1 : 0 };
606  enum { V1 = Impl::is_same< SubArg1_type , void >::value ? 1 : 0 };
607  enum { V2 = Impl::is_same< SubArg2_type , void >::value ? 1 : 0 };
608  enum { V3 = Impl::is_same< SubArg3_type , void >::value ? 1 : 0 };
609  enum { V4 = Impl::is_same< SubArg4_type , void >::value ? 1 : 0 };
610  enum { V5 = Impl::is_same< SubArg5_type , void >::value ? 1 : 0 };
611  enum { V6 = Impl::is_same< SubArg6_type , void >::value ? 1 : 0 };
612  enum { V7 = Impl::is_same< SubArg7_type , void >::value ? 1 : 0 };
613 
614  // The source view rank must be equal to the input argument rank
615  // Once a void argument is encountered all subsequent arguments must be void.
616  enum { InputRank =
617  Impl::StaticAssert<( SrcViewType::rank ==
618  ( V0 ? 0 : (
619  V1 ? 1 : (
620  V2 ? 2 : (
621  V3 ? 3 : (
622  V4 ? 4 : (
623  V5 ? 5 : (
624  V6 ? 6 : (
625  V7 ? 7 : 8 ))))))) ))
626  &&
627  ( SrcViewType::rank ==
628  ( 8 - ( V0 + V1 + V2 + V3 + V4 + V5 + V6 + V7 ) ) )
629  >::value ? SrcViewType::rank : 0 };
630 
631  enum { R0 = Impl::ViewOffsetRange< SubArg0_type >::is_range ? 1 : 0 };
632  enum { R1 = Impl::ViewOffsetRange< SubArg1_type >::is_range ? 1 : 0 };
633  enum { R2 = Impl::ViewOffsetRange< SubArg2_type >::is_range ? 1 : 0 };
634  enum { R3 = Impl::ViewOffsetRange< SubArg3_type >::is_range ? 1 : 0 };
635  enum { R4 = Impl::ViewOffsetRange< SubArg4_type >::is_range ? 1 : 0 };
636  enum { R5 = Impl::ViewOffsetRange< SubArg5_type >::is_range ? 1 : 0 };
637  enum { R6 = Impl::ViewOffsetRange< SubArg6_type >::is_range ? 1 : 0 };
638  enum { R7 = Impl::ViewOffsetRange< SubArg7_type >::is_range ? 1 : 0 };
639 
640  enum { OutputRank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3)
641  + unsigned(R4) + unsigned(R5) + unsigned(R6) + unsigned(R7) };
642 
643  // Reverse
644  enum { R0_rev = 0 == InputRank ? 0u : (
645  1 == InputRank ? unsigned(R0) : (
646  2 == InputRank ? unsigned(R1) : (
647  3 == InputRank ? unsigned(R2) : (
648  4 == InputRank ? unsigned(R3) : (
649  5 == InputRank ? unsigned(R4) : (
650  6 == InputRank ? unsigned(R5) : (
651  7 == InputRank ? unsigned(R6) : unsigned(R7) ))))))) };
652 
653  typedef typename SrcViewType::array_layout SrcViewLayout ;
654 
655  // Choose array layout, attempting to preserve original layout if at all possible.
656  typedef typename Impl::if_c<
657  ( // Same Layout IF
658  // OutputRank 0
659  ( OutputRank == 0 )
660  ||
661  // OutputRank 1 or 2, InputLayout Left, Interval 0
662  // because single stride one or second index has a stride.
663  ( OutputRank <= 2 && R0 && Impl::is_same<SrcViewLayout,LayoutLeft>::value )
664  ||
665  // OutputRank 1 or 2, InputLayout Right, Interval [InputRank-1]
666  // because single stride one or second index has a stride.
667  ( OutputRank <= 2 && R0_rev && Impl::is_same<SrcViewLayout,LayoutRight>::value )
668  ), SrcViewLayout , Kokkos::LayoutStride >::type OutputViewLayout ;
669 
670  // Choose data type as a purely dynamic rank array to accomodate a runtime range.
671  typedef typename Impl::if_c< OutputRank == 0 , typename SrcViewType::value_type ,
672  typename Impl::if_c< OutputRank == 1 , typename SrcViewType::value_type *,
673  typename Impl::if_c< OutputRank == 2 , typename SrcViewType::value_type **,
674  typename Impl::if_c< OutputRank == 3 , typename SrcViewType::value_type ***,
675  typename Impl::if_c< OutputRank == 4 , typename SrcViewType::value_type ****,
676  typename Impl::if_c< OutputRank == 5 , typename SrcViewType::value_type *****,
677  typename Impl::if_c< OutputRank == 6 , typename SrcViewType::value_type ******,
678  typename Impl::if_c< OutputRank == 7 , typename SrcViewType::value_type *******,
679  typename SrcViewType::value_type ********
680  >::type >::type >::type >::type >::type >::type >::type >::type OutputData ;
681 
682  // Choose space.
683  // If the source view's template arg1 or arg2 is a space then use it,
684  // otherwise use the source view's execution space.
685 
686  typedef typename Impl::if_c< Impl::is_space< SrcArg1Type >::value , SrcArg1Type ,
687  typename Impl::if_c< Impl::is_space< SrcArg2Type >::value , SrcArg2Type , typename SrcViewType::execution_space
688  >::type >::type OutputSpace ;
689 
690 public:
691 
692  // If keeping the layout then match non-data type arguments
693  // else keep execution space and memory traits.
694  typedef typename
695  Impl::if_c< Impl::is_same< SrcViewLayout , OutputViewLayout >::value
696  , Kokkos::DualView< OutputData , SrcArg1Type , SrcArg2Type , SrcArg3Type >
697  , Kokkos::DualView< OutputData , OutputViewLayout , OutputSpace
698  , typename SrcViewType::memory_traits >
699  >::type type ;
700 };
701 
702 } /* namespace Impl */
703 } /* namespace Kokkos */
704 
705 namespace Kokkos {
706 
707 template< class D , class A1 , class A2 , class A3 ,
708  class ArgType0 >
709 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
710  , ArgType0 , void , void , void
711  , void , void , void , void
712  >::type
713 subview( const DualView<D,A1,A2,A3> & src ,
714  const ArgType0 & arg0 )
715 {
716  typedef typename
717  Impl::ViewSubview< DualView<D,A1,A2,A3>
718  , ArgType0 , void , void , void
719  , void , void , void , void
720  >::type
721  DstViewType ;
722  DstViewType sub_view;
723  sub_view.d_view = subview(src.d_view,arg0);
724  sub_view.h_view = subview(src.h_view,arg0);
725  sub_view.modified_device = src.modified_device;
726  sub_view.modified_host = src.modified_host;
727  return sub_view;
728 }
729 
730 
731 template< class D , class A1 , class A2 , class A3 ,
732  class ArgType0 , class ArgType1 >
733 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
734  , ArgType0 , ArgType1 , void , void
735  , void , void , void , void
736  >::type
737 subview( const DualView<D,A1,A2,A3> & src ,
738  const ArgType0 & arg0 ,
739  const ArgType1 & arg1 )
740 {
741  typedef typename
742  Impl::ViewSubview< DualView<D,A1,A2,A3>
743  , ArgType0 , ArgType1 , void , void
744  , void , void , void , void
745  >::type
746  DstViewType ;
747  DstViewType sub_view;
748  sub_view.d_view = subview(src.d_view,arg0,arg1);
749  sub_view.h_view = subview(src.h_view,arg0,arg1);
750  sub_view.modified_device = src.modified_device;
751  sub_view.modified_host = src.modified_host;
752  return sub_view;
753 }
754 
755 template< class D , class A1 , class A2 , class A3 ,
756  class ArgType0 , class ArgType1 , class ArgType2 >
757 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
758  , ArgType0 , ArgType1 , ArgType2 , void
759  , void , void , void , void
760  >::type
761 subview( const DualView<D,A1,A2,A3> & src ,
762  const ArgType0 & arg0 ,
763  const ArgType1 & arg1 ,
764  const ArgType2 & arg2 )
765 {
766  typedef typename
767  Impl::ViewSubview< DualView<D,A1,A2,A3>
768  , ArgType0 , ArgType1 , ArgType2 , void
769  , void , void , void , void
770  >::type
771  DstViewType ;
772  DstViewType sub_view;
773  sub_view.d_view = subview(src.d_view,arg0,arg1,arg2);
774  sub_view.h_view = subview(src.h_view,arg0,arg1,arg2);
775  sub_view.modified_device = src.modified_device;
776  sub_view.modified_host = src.modified_host;
777  return sub_view;
778 }
779 
780 template< class D , class A1 , class A2 , class A3 ,
781  class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 >
782 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
783  , ArgType0 , ArgType1 , ArgType2 , ArgType3
784  , void , void , void , void
785  >::type
786 subview( const DualView<D,A1,A2,A3> & src ,
787  const ArgType0 & arg0 ,
788  const ArgType1 & arg1 ,
789  const ArgType2 & arg2 ,
790  const ArgType3 & arg3 )
791 {
792  typedef typename
793  Impl::ViewSubview< DualView<D,A1,A2,A3>
794  , ArgType0 , ArgType1 , ArgType2 , ArgType3
795  , void , void , void , void
796  >::type
797  DstViewType ;
798  DstViewType sub_view;
799  sub_view.d_view = subview(src.d_view,arg0,arg1,arg2,arg3);
800  sub_view.h_view = subview(src.h_view,arg0,arg1,arg2,arg3);
801  sub_view.modified_device = src.modified_device;
802  sub_view.modified_host = src.modified_host;
803  return sub_view;
804 }
805 
806 template< class D , class A1 , class A2 , class A3 ,
807  class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
808  class ArgType4 >
809 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
810  , ArgType0 , ArgType1 , ArgType2 , ArgType3
811  , ArgType4 , void , void , void
812  >::type
813 subview( const DualView<D,A1,A2,A3> & src ,
814  const ArgType0 & arg0 ,
815  const ArgType1 & arg1 ,
816  const ArgType2 & arg2 ,
817  const ArgType3 & arg3 ,
818  const ArgType4 & arg4 )
819 {
820  typedef typename
821  Impl::ViewSubview< DualView<D,A1,A2,A3>
822  , ArgType0 , ArgType1 , ArgType2 , ArgType3
823  , ArgType4 , void , void ,void
824  >::type
825  DstViewType ;
826  DstViewType sub_view;
827  sub_view.d_view = subview(src.d_view,arg0,arg1,arg2,arg3,arg4);
828  sub_view.h_view = subview(src.h_view,arg0,arg1,arg2,arg3,arg4);
829  sub_view.modified_device = src.modified_device;
830  sub_view.modified_host = src.modified_host;
831  return sub_view;
832 }
833 
834 template< class D , class A1 , class A2 , class A3 ,
835  class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
836  class ArgType4 , class ArgType5 >
837 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
838  , ArgType0 , ArgType1 , ArgType2 , ArgType3
839  , ArgType4 , ArgType5 , void , void
840  >::type
841 subview( const DualView<D,A1,A2,A3> & src ,
842  const ArgType0 & arg0 ,
843  const ArgType1 & arg1 ,
844  const ArgType2 & arg2 ,
845  const ArgType3 & arg3 ,
846  const ArgType4 & arg4 ,
847  const ArgType5 & arg5 )
848 {
849  typedef typename
850  Impl::ViewSubview< DualView<D,A1,A2,A3>
851  , ArgType0 , ArgType1 , ArgType2 , ArgType3
852  , ArgType4 , ArgType5 , void , void
853  >::type
854  DstViewType ;
855  DstViewType sub_view;
856  sub_view.d_view = subview(src.d_view,arg0,arg1,arg2,arg3,arg4,arg5);
857  sub_view.h_view = subview(src.h_view,arg0,arg1,arg2,arg3,arg4,arg5);
858  sub_view.modified_device = src.modified_device;
859  sub_view.modified_host = src.modified_host;
860  return sub_view;
861 }
862 
863 template< class D , class A1 , class A2 , class A3 ,
864  class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
865  class ArgType4 , class ArgType5 , class ArgType6 >
866 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
867  , ArgType0 , ArgType1 , ArgType2 , ArgType3
868  , ArgType4 , ArgType5 , ArgType6 , void
869  >::type
870 subview( const DualView<D,A1,A2,A3> & src ,
871  const ArgType0 & arg0 ,
872  const ArgType1 & arg1 ,
873  const ArgType2 & arg2 ,
874  const ArgType3 & arg3 ,
875  const ArgType4 & arg4 ,
876  const ArgType5 & arg5 ,
877  const ArgType6 & arg6 )
878 {
879  typedef typename
880  Impl::ViewSubview< DualView<D,A1,A2,A3>
881  , ArgType0 , ArgType1 , ArgType2 , ArgType3
882  , ArgType4 , ArgType5 , ArgType6 , void
883  >::type
884  DstViewType ;
885  DstViewType sub_view;
886  sub_view.d_view = subview(src.d_view,arg0,arg1,arg2,arg3,arg4,arg5,arg6);
887  sub_view.h_view = subview(src.h_view,arg0,arg1,arg2,arg3,arg4,arg5,arg6);
888  sub_view.modified_device = src.modified_device;
889  sub_view.modified_host = src.modified_host;
890  return sub_view;
891 }
892 
893 template< class D , class A1 , class A2 , class A3 ,
894  class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
895  class ArgType4 , class ArgType5 , class ArgType6 , class ArgType7 >
896 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
897  , ArgType0 , ArgType1 , ArgType2 , ArgType3
898  , ArgType4 , ArgType5 , ArgType6 , ArgType7
899  >::type
900 subview( const DualView<D,A1,A2,A3> & src ,
901  const ArgType0 & arg0 ,
902  const ArgType1 & arg1 ,
903  const ArgType2 & arg2 ,
904  const ArgType3 & arg3 ,
905  const ArgType4 & arg4 ,
906  const ArgType5 & arg5 ,
907  const ArgType6 & arg6 ,
908  const ArgType7 & arg7 )
909 {
910  typedef typename
911  Impl::ViewSubview< DualView<D,A1,A2,A3>
912  , ArgType0 , ArgType1 , ArgType2 , ArgType3
913  , ArgType4 , ArgType5 , ArgType6 , ArgType7
914  >::type
915  DstViewType ;
916  DstViewType sub_view;
917  sub_view.d_view = subview(src.d_view,arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7);
918  sub_view.h_view = subview(src.h_view,arg0,arg1,arg2,arg3,arg4,arg5,arg6,arg7);
919  sub_view.modified_device = src.modified_device;
920  sub_view.modified_host = src.modified_host;
921  return sub_view;
922 }
923 
924 } // namespace Kokkos
925 
926 #endif /* defined( KOKKOS_USING_EXPERIMENTAL_VIEW ) */
927 
928 //----------------------------------------------------------------------------
929 //----------------------------------------------------------------------------
930 
931 namespace Kokkos {
932 
933 //
934 // Partial specialization of Kokkos::deep_copy() for DualView objects.
935 //
936 
937 template< class DT , class DL , class DD , class DM ,
938  class ST , class SL , class SD , class SM >
939 void
940 deep_copy (DualView<DT,DL,DD,DM> dst, // trust me, this must not be a reference
941  const DualView<ST,SL,SD,SM>& src )
942 {
943  if (src.modified_device () >= src.modified_host ()) {
944  deep_copy (dst.d_view, src.d_view);
945  dst.template modify<typename DualView<DT,DL,DD,DM>::device_type> ();
946  } else {
947  deep_copy (dst.h_view, src.h_view);
948  dst.template modify<typename DualView<DT,DL,DD,DM>::host_mirror_space> ();
949  }
950 }
951 
952 template< class ExecutionSpace ,
953  class DT , class DL , class DD , class DM ,
954  class ST , class SL , class SD , class SM >
955 void
956 deep_copy (const ExecutionSpace& exec ,
957  DualView<DT,DL,DD,DM> dst, // trust me, this must not be a reference
958  const DualView<ST,SL,SD,SM>& src )
959 {
960  if (src.modified_device () >= src.modified_host ()) {
961  deep_copy (exec, dst.d_view, src.d_view);
962  dst.template modify<typename DualView<DT,DL,DD,DM>::device_type> ();
963  } else {
964  deep_copy (exec, dst.h_view, src.h_view);
965  dst.template modify<typename DualView<DT,DL,DD,DM>::host_mirror_space> ();
966  }
967 }
968 
969 } // namespace Kokkos
970 
971 #endif
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...
Traits class for accessing attributes of a View.
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.