Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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 Christian R. Trott (crtrott@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 template< class , class , class , class > friend class DualView ;
100 public:
102 
103  typedef ViewTraits< DataType , Arg1Type , Arg2Type, Arg3Type > traits ;
104 
106  typedef typename traits::host_mirror_space host_mirror_space ;
107 
109  typedef View< typename traits::data_type ,
110  Arg1Type ,
111  Arg2Type ,
112  Arg3Type > t_dev ;
113 
116  typedef typename t_dev::HostMirror t_host ;
117 
120  typedef View< typename traits::const_data_type ,
121  Arg1Type ,
122  Arg2Type ,
123  Arg3Type > t_dev_const ;
124 
127  typedef typename t_dev_const::HostMirror t_host_const;
128 
130  typedef View< typename traits::const_data_type ,
131  typename traits::array_layout ,
132  typename traits::device_type ,
133  Kokkos::MemoryTraits<Kokkos::RandomAccess> > t_dev_const_randomread ;
134 
138  typedef typename t_dev_const_randomread::HostMirror t_host_const_randomread;
139 
141  typedef View< typename traits::data_type ,
142  typename traits::array_layout ,
143  typename traits::device_type ,
144  MemoryUnmanaged> t_dev_um;
145 
147  typedef View< typename t_host::data_type ,
148  typename t_host::array_layout ,
149  typename t_host::device_type ,
150  MemoryUnmanaged> t_host_um;
151 
153  typedef View< typename traits::const_data_type ,
154  typename traits::array_layout ,
155  typename traits::device_type ,
156  MemoryUnmanaged> t_dev_const_um;
157 
159  typedef View<typename t_host::const_data_type,
160  typename t_host::array_layout,
161  typename t_host::device_type,
162  MemoryUnmanaged> t_host_const_um;
163 
165  typedef View< typename t_host::const_data_type ,
166  typename t_host::array_layout ,
167  typename t_host::device_type ,
168  Kokkos::MemoryTraits<Kokkos::Unmanaged|Kokkos::RandomAccess> > t_dev_const_randomread_um ;
169 
173  typedef typename t_dev_const_randomread::HostMirror t_host_const_randomread_um;
174 
176 
178 
179  t_dev d_view;
180  t_host h_view;
181 
183 
185 
186 #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
187 protected:
188  // modified_flags[0] -> host
189  // modified_flags[1] -> device
190  typedef View<unsigned int[2],LayoutLeft,Kokkos::HostSpace> t_modified_flags;
191  t_modified_flags modified_flags;
192 
193 public:
194 #else
195  typedef View<unsigned int[2],LayoutLeft,typename t_host::execution_space> t_modified_flags;
196  typedef View<unsigned int,LayoutLeft,typename t_host::execution_space> t_modified_flag;
197  t_modified_flags modified_flags;
198  t_modified_flag modified_host,modified_device;
199 #endif
200 
202 
204 
210 #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
211  DualView () = default;
212 #else
213  DualView ():modified_flags (t_modified_flags("DualView::modified_flags")) {
214  modified_host = t_modified_flag(modified_flags,0);
215  modified_device = t_modified_flag(modified_flags,1);
216  }
217 #endif
218 
228  DualView (const std::string& label,
229  const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
230  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
231  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
232  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
233  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
234  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
235  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG,
236  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG)
237  : d_view (label, n0, n1, n2, n3, n4, n5, n6, n7)
238  , h_view (create_mirror_view (d_view)) // without UVM, host View mirrors
239  , modified_flags (t_modified_flags("DualView::modified_flags"))
240  {
241 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
242  modified_host = t_modified_flag(modified_flags,0);
243  modified_device = t_modified_flag(modified_flags,1);
244 #endif
245  }
246 
248  template<class SS, class LS, class DS, class MS>
249  DualView (const DualView<SS,LS,DS,MS>& src) :
250  d_view (src.d_view),
251  h_view (src.h_view),
252  modified_flags (src.modified_flags)
253 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
254  , modified_host(src.modified_host)
255  , modified_device(src.modified_device)
256 #endif
257  {}
258 
260  template< class SD, class S1 , class S2 , class S3
261  , class Arg0 , class ... Args >
262  DualView( const DualView<SD,S1,S2,S3> & src
263  , const Arg0 & arg0
264  , Args ... args
265  )
266  : d_view( Kokkos::subview( src.d_view , arg0 , args ... ) )
267  , h_view( Kokkos::subview( src.h_view , arg0 , args ... ) )
268  , modified_flags (src.modified_flags)
269 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
270  , modified_host(src.modified_host)
271  , modified_device(src.modified_device)
272 #endif
273  {}
274 
285  DualView (const t_dev& d_view_, const t_host& h_view_) :
286  d_view (d_view_),
287  h_view (h_view_),
288  modified_flags (t_modified_flags("DualView::modified_flags"))
289  {
290  if ( int(d_view.rank) != int(h_view.rank) ||
291  d_view.extent(0) != h_view.extent(0) ||
292  d_view.extent(1) != h_view.extent(1) ||
293  d_view.extent(2) != h_view.extent(2) ||
294  d_view.extent(3) != h_view.extent(3) ||
295  d_view.extent(4) != h_view.extent(4) ||
296  d_view.extent(5) != h_view.extent(5) ||
297  d_view.extent(6) != h_view.extent(6) ||
298  d_view.extent(7) != h_view.extent(7) ||
299  d_view.stride_0() != h_view.stride_0() ||
300  d_view.stride_1() != h_view.stride_1() ||
301  d_view.stride_2() != h_view.stride_2() ||
302  d_view.stride_3() != h_view.stride_3() ||
303  d_view.stride_4() != h_view.stride_4() ||
304  d_view.stride_5() != h_view.stride_5() ||
305  d_view.stride_6() != h_view.stride_6() ||
306  d_view.stride_7() != h_view.stride_7() ||
307  d_view.span() != h_view.span() ) {
308  Kokkos::Impl::throw_runtime_exception("DualView constructed with incompatible views");
309  }
310 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
311  modified_host = t_modified_flag(modified_flags,0);
312  modified_device = t_modified_flag(modified_flags,1);
313 #endif
314  }
315 
317 
319 
341  template< class Device >
342  KOKKOS_INLINE_FUNCTION
343  const typename Impl::if_c<
344  std::is_same<typename t_dev::memory_space,
345  typename Device::memory_space>::value,
346  t_dev,
347  t_host>::type& view () const
348  {
349  #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
350  constexpr bool device_is_memspace = std::is_same<Device,typename Device::memory_space>::value;
351  constexpr bool device_is_execspace = std::is_same<Device,typename Device::execution_space>::value;
352  constexpr bool device_exec_is_t_dev_exec = std::is_same<typename Device::execution_space,typename t_dev::execution_space>::value;
353  constexpr bool device_mem_is_t_dev_mem = std::is_same<typename Device::memory_space,typename t_dev::memory_space>::value;
354  constexpr bool device_exec_is_t_host_exec = std::is_same<typename Device::execution_space,typename t_host::execution_space>::value;
355  constexpr bool device_mem_is_t_host_mem = std::is_same<typename Device::memory_space,typename t_host::memory_space>::value;
356  constexpr bool device_is_t_host_device = std::is_same<typename Device::execution_space,typename t_host::device_type>::value;
357  constexpr bool device_is_t_dev_device = std::is_same<typename Device::memory_space,typename t_host::device_type>::value;
358 
359  static_assert(
360  device_is_t_dev_device || device_is_t_host_device ||
361  (device_is_memspace && (device_mem_is_t_dev_mem || device_mem_is_t_host_mem) ) ||
362  (device_is_execspace && (device_exec_is_t_dev_exec || device_exec_is_t_host_exec) ) ||
363  (
364  (!device_is_execspace && !device_is_memspace) && (
365  (device_mem_is_t_dev_mem || device_mem_is_t_host_mem) ||
366  (device_exec_is_t_dev_exec || device_exec_is_t_host_exec)
367  )
368  )
369  ,
370  "Template parameter to .view() must exactly match one of the DualView's device types or one of the execution or memory spaces");
371  #endif
372 
373  return Impl::if_c<
374  std::is_same<
375  typename t_dev::memory_space,
376  typename Device::memory_space>::value,
377  t_dev,
378  t_host >::select (d_view , h_view);
379  }
380 
381  KOKKOS_INLINE_FUNCTION
382  t_host view_host() const {
383  return h_view;
384  }
385 
386  KOKKOS_INLINE_FUNCTION
387  t_dev view_device() const {
388  return d_view;
389  }
390 
391  template<class Device>
392  static int get_device_side() {
393  constexpr bool device_is_memspace = std::is_same<Device,typename Device::memory_space>::value;
394  constexpr bool device_is_execspace = std::is_same<Device,typename Device::execution_space>::value;
395  constexpr bool device_exec_is_t_dev_exec = std::is_same<typename Device::execution_space,typename t_dev::execution_space>::value;
396  constexpr bool device_mem_is_t_dev_mem = std::is_same<typename Device::memory_space,typename t_dev::memory_space>::value;
397  constexpr bool device_exec_is_t_host_exec = std::is_same<typename Device::execution_space,typename t_host::execution_space>::value;
398  constexpr bool device_mem_is_t_host_mem = std::is_same<typename Device::memory_space,typename t_host::memory_space>::value;
399  constexpr bool device_is_t_host_device = std::is_same<typename Device::execution_space,typename t_host::device_type>::value;
400  constexpr bool device_is_t_dev_device = std::is_same<typename Device::memory_space,typename t_host::device_type>::value;
401 
402  #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
403  static_assert(
404  device_is_t_dev_device || device_is_t_host_device ||
405  (device_is_memspace && (device_mem_is_t_dev_mem || device_mem_is_t_host_mem) ) ||
406  (device_is_execspace && (device_exec_is_t_dev_exec || device_exec_is_t_host_exec) ) ||
407  (
408  (!device_is_execspace && !device_is_memspace) && (
409  (device_mem_is_t_dev_mem || device_mem_is_t_host_mem) ||
410  (device_exec_is_t_dev_exec || device_exec_is_t_host_exec)
411  )
412  )
413  ,
414  "Template parameter to .sync() must exactly match one of the DualView's device types or one of the execution or memory spaces");
415  #endif
416 
417  #ifndef KOKKOS_ENABLE_DEPRECATED_CODE
418  int dev = -1;
419  #else
420  int dev = 0;
421  #endif
422  if(device_is_t_dev_device) dev = 1;
423  else if(device_is_t_host_device) dev = 0;
424  else {
425  if(device_is_memspace) {
426  if(device_mem_is_t_dev_mem) dev = 1;
427  if(device_mem_is_t_host_mem) dev = 0;
428  if(device_mem_is_t_host_mem && device_mem_is_t_dev_mem) dev = -1;
429  }
430  if(device_is_execspace) {
431  if(device_exec_is_t_dev_exec) dev = 1;
432  if(device_exec_is_t_host_exec) dev = 0;
433  if(device_exec_is_t_host_exec && device_exec_is_t_dev_exec) dev = -1;
434  }
435  if(!device_is_execspace && !device_is_memspace) {
436  if(device_mem_is_t_dev_mem) dev = 1;
437  if(device_mem_is_t_host_mem) dev = 0;
438  if(device_mem_is_t_host_mem && device_mem_is_t_dev_mem) dev = -1;
439  if(device_exec_is_t_dev_exec) dev = 1;
440  if(device_exec_is_t_host_exec) dev = 0;
441  if(device_exec_is_t_host_exec && device_exec_is_t_dev_exec) dev = -1;
442  }
443  }
444  return dev;
445  }
446 
464  template<class Device>
465  void sync( const typename Impl::enable_if<
466  ( std::is_same< typename traits::data_type , typename traits::non_const_data_type>::value) ||
467  ( std::is_same< Device , int>::value)
468  , int >::type& = 0)
469  {
470  if(modified_flags.data()==NULL) return;
471 
472  int dev = get_device_side<Device>();
473 
474  if (dev == 1) { // if Device is the same as DualView's device type
475  if ((modified_flags(0) > 0) && (modified_flags(0) >= modified_flags(1))) {
476  deep_copy (d_view, h_view);
477  modified_flags(0) = modified_flags(1) = 0;
478  }
479  }
480  if (dev == 0) { // hopefully Device is the same as DualView's host type
481  if ((modified_flags(1) > 0) && (modified_flags(1) >= modified_flags(0))) {
482  deep_copy (h_view, d_view);
483  modified_flags(0) = modified_flags(1) = 0;
484  }
485  }
486  if(std::is_same<typename t_host::memory_space,typename t_dev::memory_space>::value) {
487  t_dev::execution_space::fence();
488  t_host::execution_space::fence();
489  }
490  }
491 
492  template<class Device>
493  void sync ( const typename Impl::enable_if<
494  ( ! std::is_same< typename traits::data_type , typename traits::non_const_data_type>::value ) ||
495  ( std::is_same< Device , int>::value)
496  , int >::type& = 0 )
497  {
498  if(modified_flags.data()==NULL) return;
499 
500  int dev = get_device_side<Device>();
501 
502  if (dev == 1) { // if Device is the same as DualView's device type
503  if ((modified_flags(0) > 0) && (modified_flags(0) >= modified_flags(1))) {
504  Impl::throw_runtime_exception("Calling sync on a DualView with a const datatype.");
505  }
506  }
507  if (dev == 0){ // hopefully Device is the same as DualView's host type
508  if ((modified_flags(1) > 0) && (modified_flags(1) >= modified_flags(0))) {
509  Impl::throw_runtime_exception("Calling sync on a DualView with a const datatype.");
510  }
511  }
512  }
513 
514  void sync_host() {
515  if( ! std::is_same< typename traits::data_type , typename traits::non_const_data_type>::value )
516  Impl::throw_runtime_exception("Calling sync_host on a DualView with a const datatype.");
517  if(modified_flags.data()==NULL) return;
518  if(modified_flags(1) > modified_flags(0)) {
519  deep_copy (h_view, d_view);
520  modified_flags(1) = modified_flags(0) = 0;
521  }
522  }
523 
524  void sync_device() {
525  if( ! std::is_same< typename traits::data_type , typename traits::non_const_data_type>::value )
526  Impl::throw_runtime_exception("Calling sync_device on a DualView with a const datatype.");
527  if(modified_flags.data()==NULL) return;
528  if(modified_flags(0) > modified_flags(1)) {
529  deep_copy (d_view, h_view);
530  modified_flags(1) = modified_flags(0) = 0;
531  }
532  }
533 
534  template<class Device>
535  bool need_sync() const
536  {
537  if(modified_flags.data()==NULL) return false;
538  int dev = get_device_side<Device>();
539 
540  if (dev == 1) { // if Device is the same as DualView's device type
541  if ((modified_flags(0) > 0) && (modified_flags(0) >= modified_flags(1))) {
542  return true;
543  }
544  }
545  if (dev == 0){ // hopefully Device is the same as DualView's host type
546  if ((modified_flags(1) > 0) && (modified_flags(1) >= modified_flags(0))) {
547  return true;
548  }
549  }
550  return false;
551  }
552 
553  inline bool need_sync_host() const {
554  if(modified_flags.data()==NULL) return false;
555  return modified_flags(0)<modified_flags(1);
556  }
557 
558  inline bool need_sync_device() const {
559  if(modified_flags.data()==NULL) return false;
560  return modified_flags(1)<modified_flags(0);
561  }
562 
568  template<class Device>
569  void modify () {
570  if(modified_flags.data()==NULL) return;
571  int dev = get_device_side<Device>();
572 
573  if (dev == 1) { // if Device is the same as DualView's device type
574  // Increment the device's modified count.
575  modified_flags(1) = (modified_flags(1) > modified_flags(0) ?
576  modified_flags(1) : modified_flags(0)) + 1;
577  }
578  if (dev == 0) { // hopefully Device is the same as DualView's host type
579  // Increment the host's modified count.
580  modified_flags(0) = (modified_flags(1) > modified_flags(0) ?
581  modified_flags(1) : modified_flags(0)) + 1;
582  }
583 
584 #ifdef KOKKOS_ENABLE_DEBUG_DUALVIEW_MODIFY_CHECK
585  if (modified_flags(0) && modified_flags(1)) {
586  std::string msg = "Kokkos::DualView::modify ERROR: ";
587  msg += "Concurrent modification of host and device views ";
588  msg += "in DualView \"";
589  msg += d_view.label();
590  msg += "\"\n";
591  Kokkos::abort(msg.c_str());
592  }
593 #endif
594  }
595 
596  inline void modify_host() {
597  if(modified_flags.data()!=NULL) {
598  modified_flags(0) = (modified_flags(1) > modified_flags(0) ?
599  modified_flags(1) : modified_flags(0)) + 1;
600  #ifdef KOKKOS_ENABLE_DEBUG_DUALVIEW_MODIFY_CHECK
601  if (modified_flags(0) && modified_flags(1)) {
602  std::string msg = "Kokkos::DualView::modify_host ERROR: ";
603  msg += "Concurrent modification of host and device views ";
604  msg += "in DualView \"";
605  msg += d_view.label();
606  msg += "\"\n";
607  Kokkos::abort(msg.c_str());
608  }
609  #endif
610  }
611  }
612 
613  inline void modify_device() {
614  if(modified_flags.data()!=NULL) {
615  modified_flags(1) = (modified_flags(1) > modified_flags(0) ?
616  modified_flags(1) : modified_flags(0)) + 1;
617  #ifdef KOKKOS_ENABLE_DEBUG_DUALVIEW_MODIFY_CHECK
618  if (modified_flags(0) && modified_flags(1)) {
619  std::string msg = "Kokkos::DualView::modify_device ERROR: ";
620  msg += "Concurrent modification of host and device views ";
621  msg += "in DualView \"";
622  msg += d_view.label();
623  msg += "\"\n";
624  Kokkos::abort(msg.c_str());
625  }
626  #endif
627  }
628  }
629 
630  inline void clear_sync_state() {
631  if(modified_flags.data()!=NULL)
632  modified_flags(1) = modified_flags(0) = 0;
633  }
634 
636 
638 
644  void realloc( const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
645  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
646  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
647  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
648  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
649  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
650  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
651  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ) {
652  ::Kokkos::realloc(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
653  h_view = create_mirror_view( d_view );
654 
655  /* Reset dirty flags */
656  if(modified_flags.data()==NULL) {
657  modified_flags = t_modified_flags("DualView::modified_flags");
658  } else
659  modified_flags(1) = modified_flags(0) = 0;
660  }
661 
666  void resize( const size_t n0 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
667  const size_t n1 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
668  const size_t n2 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
669  const size_t n3 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
670  const size_t n4 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
671  const size_t n5 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
672  const size_t n6 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ,
673  const size_t n7 = KOKKOS_IMPL_CTOR_DEFAULT_ARG ) {
674  if(modified_flags.data()==NULL) {
675  modified_flags = t_modified_flags("DualView::modified_flags");
676  }
677  if(modified_flags(1) >= modified_flags(0)) {
678  /* Resize on Device */
679  ::Kokkos::resize(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
680  h_view = create_mirror_view( d_view );
681 
682  /* Mark Device copy as modified */
683  modified_flags(1) = modified_flags(1)+1;
684 
685  } else {
686  /* Realloc on Device */
687 
688  ::Kokkos::realloc(d_view,n0,n1,n2,n3,n4,n5,n6,n7);
689 
690  const bool sizeMismatch = ( h_view.extent(0) != n0 ) ||
691  ( h_view.extent(1) != n1 ) ||
692  ( h_view.extent(2) != n2 ) ||
693  ( h_view.extent(3) != n3 ) ||
694  ( h_view.extent(4) != n4 ) ||
695  ( h_view.extent(5) != n5 ) ||
696  ( h_view.extent(6) != n6 ) ||
697  ( h_view.extent(7) != n7 );
698  if ( sizeMismatch )
699  ::Kokkos::resize(h_view,n0,n1,n2,n3,n4,n5,n6,n7);
700 
701  t_host temp_view = create_mirror_view( d_view );
702 
703  /* Remap on Host */
704  Kokkos::deep_copy( temp_view , h_view );
705 
706  h_view = temp_view;
707 
708  d_view = create_mirror_view( typename t_dev::execution_space(), h_view );
709 
710  /* Mark Host copy as modified */
711  modified_flags(0) = modified_flags(0)+1;
712  }
713  }
714 
716 
718 
719 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
720  size_t capacity() const {
722  return d_view.span();
723  }
724 #endif
725 
727  KOKKOS_INLINE_FUNCTION constexpr size_t span() const {
728  return d_view.span();
729  }
730 
731  KOKKOS_INLINE_FUNCTION bool span_is_contiguous() const {
732  return d_view.span_is_contiguous();
733  }
734 
736  template< typename iType>
737  void stride(iType* stride_) const {
738  d_view.stride(stride_);
739  }
740 
741  template< typename iType >
742  KOKKOS_INLINE_FUNCTION constexpr
743  typename std::enable_if< std::is_integral<iType>::value , size_t >::type
744  extent( const iType & r ) const
745  { return d_view.extent(r); }
746 
747  template< typename iType >
748  KOKKOS_INLINE_FUNCTION constexpr
749  typename std::enable_if< std::is_integral<iType>::value , int >::type
750  extent_int( const iType & r ) const
751  { return static_cast<int>(d_view.extent(r)); }
752 
753 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
754  /* Deprecate all 'dimension' functions in favor of
755  * ISO/C++ vocabulary 'extent'.
756  */
757 
758  /* \brief return size of dimension 0 */
759  size_t dimension_0() const {return d_view.extent(0);}
760  /* \brief return size of dimension 1 */
761  size_t dimension_1() const {return d_view.extent(1);}
762  /* \brief return size of dimension 2 */
763  size_t dimension_2() const {return d_view.extent(2);}
764  /* \brief return size of dimension 3 */
765  size_t dimension_3() const {return d_view.extent(3);}
766  /* \brief return size of dimension 4 */
767  size_t dimension_4() const {return d_view.extent(4);}
768  /* \brief return size of dimension 5 */
769  size_t dimension_5() const {return d_view.extent(5);}
770  /* \brief return size of dimension 6 */
771  size_t dimension_6() const {return d_view.extent(6);}
772  /* \brief return size of dimension 7 */
773  size_t dimension_7() const {return d_view.extent(7);}
774 #endif
775 
777 };
778 
779 } // namespace Kokkos
780 
781 //----------------------------------------------------------------------------
782 //----------------------------------------------------------------------------
783 //
784 // Partial specializations of Kokkos::subview() for DualView objects.
785 //
786 
787 namespace Kokkos {
788 namespace Impl {
789 
790 template< class D, class A1, class A2, class A3, class ... Args >
791 struct DualViewSubview {
792 
793  typedef typename Kokkos::Impl::ViewMapping
794  < void
796  , Args ...
797  >::traits_type dst_traits ;
798 
799  typedef Kokkos::DualView
800  < typename dst_traits::data_type
801  , typename dst_traits::array_layout
802  , typename dst_traits::device_type
803  , typename dst_traits::memory_traits
804  > type ;
805 };
806 
807 } /* namespace Impl */
808 
809 
810 template< class D , class A1 , class A2 , class A3 , class ... Args >
811 typename Impl::DualViewSubview<D,A1,A2,A3,Args...>::type
812 subview( const DualView<D,A1,A2,A3> & src , Args ... args )
813 {
814  return typename
815  Impl::DualViewSubview<D,A1,A2,A3,Args...>::type( src , args ... );
816 }
817 
818 } /* namespace Kokkos */
819 
820 //----------------------------------------------------------------------------
821 //----------------------------------------------------------------------------
822 
823 namespace Kokkos {
824 
825 //
826 // Partial specialization of Kokkos::deep_copy() for DualView objects.
827 //
828 
829 template< class DT , class DL , class DD , class DM ,
830  class ST , class SL , class SD , class SM >
831 void
832 deep_copy (DualView<DT,DL,DD,DM> dst, // trust me, this must not be a reference
833  const DualView<ST,SL,SD,SM>& src )
834 {
835  if ( src.need_sync_device() ) {
836  deep_copy (dst.h_view, src.h_view);
837  dst.modify_host();
838  }
839  else {
840  deep_copy (dst.d_view, src.d_view);
841  dst.modify_device();
842  }
843 }
844 
845 template< class ExecutionSpace ,
846  class DT , class DL , class DD , class DM ,
847  class ST , class SL , class SD , class SM >
848 void
849 deep_copy (const ExecutionSpace& exec ,
850  DualView<DT,DL,DD,DM> dst, // trust me, this must not be a reference
851  const DualView<ST,SL,SD,SM>& src )
852 {
853  if ( src.need_sync_device() ) {
854  deep_copy (exec, dst.h_view, src.h_view);
855  dst.modify_host();
856  } else {
857  deep_copy (exec, dst.d_view, src.d_view);
858  dst.modify_device();
859  }
860 }
861 
862 } // namespace Kokkos
863 
864 #endif
865 
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=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n1=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n2=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n3=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n4=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n5=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n6=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n7=KOKKOS_IMPL_CTOR_DEFAULT_ARG)
Resize a view with copying old data to new data at the corresponding indices.
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.
void resize(DynRankView< T, P...> &v, const size_t n0=KOKKOS_INVALID_INDEX, const size_t n1=KOKKOS_INVALID_INDEX, const size_t n2=KOKKOS_INVALID_INDEX, const size_t n3=KOKKOS_INVALID_INDEX, const size_t n4=KOKKOS_INVALID_INDEX, const size_t n5=KOKKOS_INVALID_INDEX, const size_t n6=KOKKOS_INVALID_INDEX, const size_t n7=KOKKOS_INVALID_INDEX)
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=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n1=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n2=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n3=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n4=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n5=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n6=KOKKOS_IMPL_CTOR_DEFAULT_ARG, const size_t n7=KOKKOS_IMPL_CTOR_DEFAULT_ARG)
Resize a view with discarding old data.
void realloc(DynRankView< T, P...> &v, const size_t n0=KOKKOS_INVALID_INDEX, const size_t n1=KOKKOS_INVALID_INDEX, const size_t n2=KOKKOS_INVALID_INDEX, const size_t n3=KOKKOS_INVALID_INDEX, const size_t n4=KOKKOS_INVALID_INDEX, const size_t n5=KOKKOS_INVALID_INDEX, const size_t n6=KOKKOS_INVALID_INDEX, const size_t n7=KOKKOS_INVALID_INDEX)
Resize a view with copying old data to new data at the corresponding indices.
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.