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 
234  DualView (const t_dev& d_view_, const t_host& h_view_) :
235  d_view (d_view_),
236  h_view (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"))
239  {
240  Impl::assert_shapes_are_equal (d_view.shape (), h_view.shape ());
241  }
242 
244 
246 
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,
273  t_dev,
274  t_host>::type& view () const
275  {
276  return Impl::if_c<
277  Impl::is_same<
278  typename t_dev::memory_space,
279  typename Device::memory_space>::value,
280  t_dev,
281  t_host >::select (d_view , h_view);
282  }
283 
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)
305  , int >::type& = 0)
306  {
307  const unsigned int dev =
308  Impl::if_c<
309  Impl::is_same<
310  typename t_dev::memory_space,
311  typename Device::memory_space>::value ,
312  unsigned int,
313  unsigned int>::select (1, 0);
314 
315  if (dev) { // if Device is the same as DualView's device type
316  if ((modified_host () > 0) && (modified_host () >= modified_device ())) {
317  deep_copy (d_view, h_view);
318  modified_host() = modified_device() = 0;
319  }
320  } else { // hopefully Device is the same as DualView's host type
321  if ((modified_device () > 0) && (modified_device () >= modified_host ())) {
322  deep_copy (h_view, d_view);
323  modified_host() = modified_device() = 0;
324  }
325  }
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();
329  }
330  }
331 
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)
336  , int >::type& = 0 )
337  {
338  const unsigned int dev =
339  Impl::if_c<
340  Impl::is_same<
341  typename t_dev::memory_space,
342  typename Device::memory_space>::value,
343  unsigned int,
344  unsigned int>::select (1, 0);
345  if (dev) { // if Device is the same as DualView's device type
346  if ((modified_host () > 0) && (modified_host () >= modified_device ())) {
347  Impl::throw_runtime_exception("Calling sync on a DualView with a const datatype.");
348  }
349  } else { // hopefully Device is the same as DualView's host type
350  if ((modified_device () > 0) && (modified_device () >= modified_host ())) {
351  Impl::throw_runtime_exception("Calling sync on a DualView with a const datatype.");
352  }
353  }
354  }
355 
356  template<class Device>
357  bool need_sync()
358  {
359  const unsigned int dev =
360  Impl::if_c<
361  Impl::is_same<
362  typename t_dev::memory_space,
363  typename Device::memory_space>::value ,
364  unsigned int,
365  unsigned int>::select (1, 0);
366 
367  if (dev) { // if Device is the same as DualView's device type
368  if ((modified_host () > 0) && (modified_host () >= modified_device ())) {
369  return true;
370  }
371  } else { // hopefully Device is the same as DualView's host type
372  if ((modified_device () > 0) && (modified_device () >= modified_host ())) {
373  return true;
374  }
375  }
376  return false;
377  }
383  template<class Device>
384  void modify () {
385  const unsigned int dev =
386  Impl::if_c<
387  Impl::is_same<
388  typename t_dev::memory_space,
389  typename Device::memory_space>::value,
390  unsigned int,
391  unsigned int>::select (1, 0);
392 
393  if (dev) { // if Device is the same as DualView's device type
394  // Increment the device's modified count.
395  modified_device () = (modified_device () > modified_host () ?
396  modified_device () : modified_host ()) + 1;
397  } else { // hopefully Device is the same as DualView's host type
398  // Increment the host's modified count.
399  modified_host () = (modified_device () > modified_host () ?
400  modified_device () : modified_host ()) + 1;
401  }
402  }
403 
405 
407 
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 );
423 
424  /* Reset dirty flags */
425  modified_device() = modified_host() = 0;
426  }
427 
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()) {
441  /* Resize on Device */
442  ::Kokkos::resize(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
443  h_view = create_mirror_view( d_view );
444 
445  /* Mark Device copy as modified */
446  modified_device() = modified_device()+1;
447 
448  } else {
449  /* Realloc on Device */
450 
451  ::Kokkos::realloc(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
452  t_host temp_view = create_mirror_view( d_view );
453 
454  /* Remap on Host */
455  Kokkos::deep_copy( temp_view , h_view );
456 
457  h_view = temp_view;
458 
459  /* Mark Host copy as modified */
460  modified_host() = modified_host()+1;
461  }
462  }
463 
465 
467 
469  size_t capacity() const {
470 #if defined( KOKKOS_USING_EXPERIMENTAL_VIEW )
471  return d_view.span();
472 #else
473  return d_view.capacity();
474 #endif
475  }
476 
478  template< typename iType>
479  void stride(iType* stride_) const {
480  d_view.stride(stride_);
481  }
482 
483  /* \brief return size of dimension 0 */
484  size_t dimension_0() const {return d_view.dimension_0();}
485  /* \brief return size of dimension 1 */
486  size_t dimension_1() const {return d_view.dimension_1();}
487  /* \brief return size of dimension 2 */
488  size_t dimension_2() const {return d_view.dimension_2();}
489  /* \brief return size of dimension 3 */
490  size_t dimension_3() const {return d_view.dimension_3();}
491  /* \brief return size of dimension 4 */
492  size_t dimension_4() const {return d_view.dimension_4();}
493  /* \brief return size of dimension 5 */
494  size_t dimension_5() const {return d_view.dimension_5();}
495  /* \brief return size of dimension 6 */
496  size_t dimension_6() const {return d_view.dimension_6();}
497  /* \brief return size of dimension 7 */
498  size_t dimension_7() const {return d_view.dimension_7();}
499 
501 };
502 
503 } // namespace Kokkos
504 //
505 // Partial specializations of Kokkos::subview() for DualView objects.
506 //
507 
508 namespace Kokkos {
509 namespace Impl {
510 
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
514  >
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 >
518 {
519 private:
520 
521  typedef DualView< SrcDataType , SrcArg1Type , SrcArg2Type , SrcArg3Type > SrcViewType ;
522 
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 };
531 
532  // The source view rank must be equal to the input argument rank
533  // Once a void argument is encountered all subsequent arguments must be void.
534  enum { InputRank =
535  Impl::StaticAssert<( SrcViewType::rank ==
536  ( V0 ? 0 : (
537  V1 ? 1 : (
538  V2 ? 2 : (
539  V3 ? 3 : (
540  V4 ? 4 : (
541  V5 ? 5 : (
542  V6 ? 6 : (
543  V7 ? 7 : 8 ))))))) ))
544  &&
545  ( SrcViewType::rank ==
546  ( 8 - ( V0 + V1 + V2 + V3 + V4 + V5 + V6 + V7 ) ) )
547  >::value ? SrcViewType::rank : 0 };
548 
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 };
557 
558  enum { OutputRank = unsigned(R0) + unsigned(R1) + unsigned(R2) + unsigned(R3)
559  + unsigned(R4) + unsigned(R5) + unsigned(R6) + unsigned(R7) };
560 
561  // Reverse
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) ))))))) };
570 
571  typedef typename SrcViewType::array_layout SrcViewLayout ;
572 
573  // Choose array layout, attempting to preserve original layout if at all possible.
574  typedef typename Impl::if_c<
575  ( // Same Layout IF
576  // OutputRank 0
577  ( OutputRank == 0 )
578  ||
579  // OutputRank 1 or 2, InputLayout Left, Interval 0
580  // because single stride one or second index has a stride.
581  ( OutputRank <= 2 && R0 && Impl::is_same<SrcViewLayout,LayoutLeft>::value )
582  ||
583  // OutputRank 1 or 2, InputLayout Right, Interval [InputRank-1]
584  // because single stride one or second index has a stride.
585  ( OutputRank <= 2 && R0_rev && Impl::is_same<SrcViewLayout,LayoutRight>::value )
586  ), SrcViewLayout , Kokkos::LayoutStride >::type OutputViewLayout ;
587 
588  // Choose data type as a purely dynamic rank array to accomodate a runtime range.
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 ;
599 
600  // Choose space.
601  // If the source view's template arg1 or arg2 is a space then use it,
602  // otherwise use the source view's execution space.
603 
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 ;
607 
608 public:
609 
610  // If keeping the layout then match non-data type arguments
611  // else keep execution space and memory traits.
612  typedef typename
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 >
617  >::type type ;
618 };
619 
620 } /* namespace Impl */
621 } /* namespace Kokkos */
622 
623 namespace Kokkos {
624 
625 template< class D , class A1 , class A2 , class A3 ,
626  class ArgType0 >
627 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
628  , ArgType0 , void , void , void
629  , void , void , void , void
630  >::type
631 subview( const DualView<D,A1,A2,A3> & src ,
632  const ArgType0 & arg0 )
633 {
634  typedef typename
635  Impl::ViewSubview< DualView<D,A1,A2,A3>
636  , ArgType0 , void , void , void
637  , void , void , void , void
638  >::type
639  DstViewType ;
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;
645  return sub_view;
646 }
647 
648 
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
654  >::type
655 subview( const DualView<D,A1,A2,A3> & src ,
656  const ArgType0 & arg0 ,
657  const ArgType1 & arg1 )
658 {
659  typedef typename
660  Impl::ViewSubview< DualView<D,A1,A2,A3>
661  , ArgType0 , ArgType1 , void , void
662  , void , void , void , void
663  >::type
664  DstViewType ;
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;
670  return sub_view;
671 }
672 
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
678  >::type
679 subview( const DualView<D,A1,A2,A3> & src ,
680  const ArgType0 & arg0 ,
681  const ArgType1 & arg1 ,
682  const ArgType2 & arg2 )
683 {
684  typedef typename
685  Impl::ViewSubview< DualView<D,A1,A2,A3>
686  , ArgType0 , ArgType1 , ArgType2 , void
687  , void , void , void , void
688  >::type
689  DstViewType ;
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;
695  return sub_view;
696 }
697 
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
703  >::type
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 )
709 {
710  typedef typename
711  Impl::ViewSubview< DualView<D,A1,A2,A3>
712  , ArgType0 , ArgType1 , ArgType2 , ArgType3
713  , void , void , void , void
714  >::type
715  DstViewType ;
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;
721  return sub_view;
722 }
723 
724 template< class D , class A1 , class A2 , class A3 ,
725  class ArgType0 , class ArgType1 , class ArgType2 , class ArgType3 ,
726  class ArgType4 >
727 typename Impl::ViewSubview< DualView<D,A1,A2,A3>
728  , ArgType0 , ArgType1 , ArgType2 , ArgType3
729  , ArgType4 , void , void , void
730  >::type
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 )
737 {
738  typedef typename
739  Impl::ViewSubview< DualView<D,A1,A2,A3>
740  , ArgType0 , ArgType1 , ArgType2 , ArgType3
741  , ArgType4 , void , void ,void
742  >::type
743  DstViewType ;
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;
749  return sub_view;
750 }
751 
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
758  >::type
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 )
766 {
767  typedef typename
768  Impl::ViewSubview< DualView<D,A1,A2,A3>
769  , ArgType0 , ArgType1 , ArgType2 , ArgType3
770  , ArgType4 , ArgType5 , void , void
771  >::type
772  DstViewType ;
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;
778  return sub_view;
779 }
780 
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
787  >::type
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 )
796 {
797  typedef typename
798  Impl::ViewSubview< DualView<D,A1,A2,A3>
799  , ArgType0 , ArgType1 , ArgType2 , ArgType3
800  , ArgType4 , ArgType5 , ArgType6 , void
801  >::type
802  DstViewType ;
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;
808  return sub_view;
809 }
810 
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
817  >::type
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 )
827 {
828  typedef typename
829  Impl::ViewSubview< DualView<D,A1,A2,A3>
830  , ArgType0 , ArgType1 , ArgType2 , ArgType3
831  , ArgType4 , ArgType5 , ArgType6 , ArgType7
832  >::type
833  DstViewType ;
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;
839  return sub_view;
840 }
841 
842 //
843 // Partial specialization of Kokkos::deep_copy() for DualView objects.
844 //
845 
846 template< class DT , class DL , class DD , class DM ,
847  class ST , class SL , class SD , class SM >
848 void
849 deep_copy (DualView<DT,DL,DD,DM> dst, // trust me, this must not be a reference
850  const DualView<ST,SL,SD,SM>& src )
851 {
852  if (src.modified_device () >= src.modified_host ()) {
853  deep_copy (dst.d_view, src.d_view);
854  dst.template modify<typename DualView<DT,DL,DD,DM>::device_type> ();
855  } else {
856  deep_copy (dst.h_view, src.h_view);
857  dst.template modify<typename DualView<DT,DL,DD,DM>::host_mirror_space> ();
858  }
859 }
860 
861 template< class ExecutionSpace ,
862  class DT , class DL , class DD , class DM ,
863  class ST , class SL , class SD , class SM >
864 void
865 deep_copy (const ExecutionSpace& exec ,
866  DualView<DT,DL,DD,DM> dst, // trust me, this must not be a reference
867  const DualView<ST,SL,SD,SM>& src )
868 {
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> ();
872  } else {
873  deep_copy (exec, dst.h_view, src.h_view);
874  dst.template modify<typename DualView<DT,DL,DD,DM>::host_mirror_space> ();
875  }
876 }
877 
878 } // namespace Kokkos
879 
880 #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...
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.