Kokkos Core Kernels Package  Version of the Day
Kokkos_DynamicView.hpp
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 
44 #ifndef KOKKOS_DYNAMIC_VIEW_HPP
45 #define KOKKOS_DYNAMIC_VIEW_HPP
46 
47 #include <cstdio>
48 
49 #include <Kokkos_Core.hpp>
50 #include <impl/Kokkos_Error.hpp>
51 
52 namespace Kokkos {
53 namespace Experimental {
54 
55 // Simple metafunction for choosing memory space
56 // In the current implementation, if memory_space == CudaSpace,
57 // use CudaUVMSpace for the chunk 'array' allocation, which
58 // contains will contain pointers to chunks of memory allocated
59 // in CudaSpace
60 namespace Impl {
61 template < class MemSpace >
62 struct ChunkArraySpace {
63  using memory_space = MemSpace;
64 };
65 
66 #ifdef KOKKOS_ENABLE_CUDA
67 template <>
68 struct ChunkArraySpace< Kokkos::CudaSpace > {
69  using memory_space = typename Kokkos::CudaUVMSpace;
70 };
71 #endif
72 #ifdef KOKKOS_ENABLE_ROCM
73 template <>
74 struct ChunkArraySpace< Kokkos::Experimental::ROCmSpace > {
75  using memory_space = typename Kokkos::Experimental::ROCmHostPinnedSpace;
76 };
77 #endif
78 } // end namespace Impl
79 
84 template< typename DataType , typename ... P >
85 class DynamicView : public Kokkos::ViewTraits< DataType , P ... >
86 {
87 public:
88 
89  typedef Kokkos::ViewTraits< DataType , P ... > traits ;
90 
91 private:
92 
93  template< class , class ... > friend class DynamicView ;
94 
95  typedef Kokkos::Impl::SharedAllocationTracker track_type ;
96 
97  static_assert( traits::rank == 1 && traits::rank_dynamic == 1
98  , "DynamicView must be rank-one" );
99 
100  // It is assumed that the value_type is trivially copyable;
101  // when this is not the case, potential problems can occur.
102  static_assert( std::is_same< typename traits::specialize , void >::value
103  , "DynamicView only implemented for non-specialized View type");
104 
105 
106  template< class Space , bool = Kokkos::Impl::MemorySpaceAccess< Space , typename traits::memory_space >::accessible > struct verify_space
107  { KOKKOS_FORCEINLINE_FUNCTION static void check() {} };
108 
109  template< class Space > struct verify_space<Space,false>
110  { KOKKOS_FORCEINLINE_FUNCTION static void check()
111  { Kokkos::abort("Kokkos::DynamicView ERROR: attempt to access inaccessible memory space"); };
112  };
113 
114 private:
115 
116  track_type m_track ;
117  typename traits::value_type ** m_chunks ; // array of pointers to 'chunks' of memory
118  unsigned m_chunk_shift ; // ceil(log2(m_chunk_size))
119  unsigned m_chunk_mask ; // m_chunk_size - 1
120  unsigned m_chunk_max ; // number of entries in the chunk array - each pointing to a chunk of extent == m_chunk_size entries
121  unsigned m_chunk_size ; // 2 << (m_chunk_shift - 1)
122 
123 public:
124 
125  //----------------------------------------------------------------------
126 
128  typedef DynamicView< typename traits::data_type ,
129  typename traits::device_type >
131 
133  typedef DynamicView< typename traits::const_data_type ,
134  typename traits::device_type >
136 
138  typedef DynamicView< typename traits::non_const_data_type ,
139  typename traits::device_type >
141 
144 
146  typedef Kokkos::Device<typename traits::device_type::execution_space, Kokkos::AnonymousSpace> uniform_device;
147  typedef array_type uniform_type;
155 
156  //----------------------------------------------------------------------
157 
158  enum { Rank = 1 };
159 
160  KOKKOS_INLINE_FUNCTION
161  size_t allocation_extent() const noexcept
162  {
163  uintptr_t n = *reinterpret_cast<const uintptr_t*>( m_chunks + m_chunk_max );
164  return (n << m_chunk_shift);
165  }
166 
167  KOKKOS_INLINE_FUNCTION
168  size_t chunk_size() const noexcept
169  {
170  return m_chunk_size;
171  }
172 
173  KOKKOS_INLINE_FUNCTION
174  size_t size() const noexcept
175  {
176  size_t extent_0 = *reinterpret_cast<const size_t*>( m_chunks + m_chunk_max +1 );
177  return extent_0;
178  }
179 
180  template< typename iType >
181  KOKKOS_INLINE_FUNCTION
182  size_t extent( const iType & r ) const
183  { return r == 0 ? size() : 1 ; }
184 
185  template< typename iType >
186  KOKKOS_INLINE_FUNCTION
187  size_t extent_int( const iType & r ) const
188  { return r == 0 ? size() : 1 ; }
189 
190 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
191  KOKKOS_INLINE_FUNCTION size_t dimension_0() const { return size(); }
192  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_1() const { return 1 ; }
193  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_2() const { return 1 ; }
194  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_3() const { return 1 ; }
195  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_4() const { return 1 ; }
196  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_5() const { return 1 ; }
197  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_6() const { return 1 ; }
198  KOKKOS_INLINE_FUNCTION constexpr size_t dimension_7() const { return 1 ; }
199 #endif
200 
201  KOKKOS_INLINE_FUNCTION constexpr size_t stride_0() const { return 0 ; }
202  KOKKOS_INLINE_FUNCTION constexpr size_t stride_1() const { return 0 ; }
203  KOKKOS_INLINE_FUNCTION constexpr size_t stride_2() const { return 0 ; }
204  KOKKOS_INLINE_FUNCTION constexpr size_t stride_3() const { return 0 ; }
205  KOKKOS_INLINE_FUNCTION constexpr size_t stride_4() const { return 0 ; }
206  KOKKOS_INLINE_FUNCTION constexpr size_t stride_5() const { return 0 ; }
207  KOKKOS_INLINE_FUNCTION constexpr size_t stride_6() const { return 0 ; }
208  KOKKOS_INLINE_FUNCTION constexpr size_t stride_7() const { return 0 ; }
209 
210  template< typename iType >
211  KOKKOS_INLINE_FUNCTION void stride( iType * const s ) const { *s = 0 ; }
212 
213  //----------------------------------------
214  // Allocation tracking properties
215 
216  KOKKOS_INLINE_FUNCTION
217  int use_count() const
218  { return m_track.use_count(); }
219 
220  inline
221  const std::string label() const
222  { return m_track.template get_label< typename traits::memory_space >(); }
223 
224  //----------------------------------------------------------------------
225  // Range span is the span which contains all members.
226 
227  typedef typename traits::value_type & reference_type ;
228  typedef typename traits::value_type * pointer_type ;
229 
230  enum { reference_type_is_lvalue_reference = std::is_lvalue_reference< reference_type >::value };
231 
232  KOKKOS_INLINE_FUNCTION constexpr bool span_is_contiguous() const { return false ; }
233  KOKKOS_INLINE_FUNCTION constexpr size_t span() const { return 0 ; }
234  KOKKOS_INLINE_FUNCTION constexpr pointer_type data() const { return 0 ; }
235 
236  //----------------------------------------
237 
238  template< typename I0 , class ... Args >
239  KOKKOS_INLINE_FUNCTION
240  reference_type operator()( const I0 & i0 , const Args & ... args ) const
241  {
242  static_assert( Kokkos::Impl::are_integral<I0,Args...>::value
243  , "Indices must be integral type" );
244 
245  DynamicView::template verify_space< Kokkos::Impl::ActiveExecutionMemorySpace >::check();
246 
247  // Which chunk is being indexed.
248  const uintptr_t ic = uintptr_t( i0 >> m_chunk_shift );
249 
250  typename traits::value_type * volatile * const ch = m_chunks + ic ;
251 
252  // Do bounds checking if enabled or if the chunk pointer is zero.
253  // If not bounds checking then we assume a non-zero pointer is valid.
254 
255 #if ! defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK )
256  if ( 0 == *ch )
257 #endif
258  {
259  // Verify that allocation of the requested chunk in in progress.
260 
261  // The allocated chunk counter is m_chunks[ m_chunk_max ]
262  const uintptr_t n =
263  *reinterpret_cast<uintptr_t volatile *>( m_chunks + m_chunk_max );
264 
265  if ( n <= ic ) {
266  Kokkos::abort("Kokkos::DynamicView array bounds error");
267  }
268 
269  // Allocation of this chunk is in progress
270  // so wait for allocation to complete.
271  while ( 0 == *ch );
272  }
273 
274  return (*ch)[ i0 & m_chunk_mask ];
275  }
276 
277  //----------------------------------------
281  template< typename IntType >
282  inline
283  typename std::enable_if
284  < std::is_integral<IntType>::value &&
286  , typename Impl::ChunkArraySpace< typename traits::memory_space >::memory_space
287  >::accessible
288  >::type
289  resize_serial( IntType const & n )
290  {
291  typedef typename traits::value_type value_type ;
292  typedef value_type * value_pointer_type ;
293 
294  const uintptr_t NC = ( n + m_chunk_mask ) >> m_chunk_shift ; // New total number of chunks needed for resize
295 
296  if ( m_chunk_max < NC ) {
297  Kokkos::abort("DynamicView::resize_serial exceeded maximum size");
298  }
299 
300  // *m_chunks[m_chunk_max] stores the current number of chunks being used
301  uintptr_t * const pc =
302  reinterpret_cast<uintptr_t*>( m_chunks + m_chunk_max );
303 
304  if ( *pc < NC ) {
305  while ( *pc < NC ) {
306  m_chunks[*pc] = reinterpret_cast<value_pointer_type>
307  (
308  typename traits::memory_space().allocate( sizeof(value_type) << m_chunk_shift )
309  );
310  ++*pc ;
311  }
312  }
313  else {
314  while ( NC + 1 <= *pc ) {
315  --*pc ;
316  typename traits::memory_space().deallocate( m_chunks[*pc]
317  , sizeof(value_type) << m_chunk_shift );
318  m_chunks[*pc] = 0 ;
319  }
320  }
321  // *m_chunks[m_chunk_max+1] stores the 'extent' requested by resize
322  *(pc+1) = n;
323  }
324 
325  //----------------------------------------------------------------------
326 
327  ~DynamicView() = default ;
328  DynamicView() = default ;
329  DynamicView( DynamicView && ) = default ;
330  DynamicView( const DynamicView & ) = default ;
331  DynamicView & operator = ( DynamicView && ) = default ;
332  DynamicView & operator = ( const DynamicView & ) = default ;
333 
334  template< class RT , class ... RP >
335  DynamicView( const DynamicView<RT,RP...> & rhs )
336  : m_track( rhs.m_track )
337  , m_chunks( (typename traits::value_type **) rhs.m_chunks )
338  , m_chunk_shift( rhs.m_chunk_shift )
339  , m_chunk_mask( rhs.m_chunk_mask )
340  , m_chunk_max( rhs.m_chunk_max )
341  , m_chunk_size( rhs.m_chunk_size )
342  {
343  typedef typename DynamicView<RT,RP...>::traits SrcTraits ;
344  typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
345  static_assert( Mapping::is_assignable , "Incompatible DynamicView copy construction" );
346  }
347 
348  //----------------------------------------------------------------------
349 
350  struct Destroy {
351  typename traits::value_type ** m_chunks ;
352  unsigned m_chunk_max ;
353  bool m_destroy ;
354  unsigned m_chunk_size ;
355 
356  // Initialize or destroy array of chunk pointers.
357  // Two entries beyond the max chunks are allocation counters.
358  inline
359  void operator()( unsigned i ) const
360  {
361  if ( m_destroy && i < m_chunk_max && 0 != m_chunks[i] ) {
362  typename traits::memory_space().deallocate( m_chunks[i], m_chunk_size );
363  }
364  m_chunks[i] = 0 ;
365  }
366 
367  void execute( bool arg_destroy )
368  {
370  //typedef Kokkos::RangePolicy< typename Impl::ChunkArraySpace< typename traits::memory_space >::memory_space::execution_space > Range ;
371 
372  m_destroy = arg_destroy ;
373 
375  closure( *this , Range(0, m_chunk_max + 2) ); // Add 2 to 'destroy' extra slots storing num_chunks and extent; previously + 1
376 
377  closure.execute();
378 
379  traits::execution_space::fence();
380  //Impl::ChunkArraySpace< typename traits::memory_space >::memory_space::execution_space::fence();
381  }
382 
383  void construct_shared_allocation()
384  { execute( false ); }
385 
386  void destroy_shared_allocation()
387  { execute( true ); }
388 
389  Destroy() = default ;
390  Destroy( Destroy && ) = default ;
391  Destroy( const Destroy & ) = default ;
392  Destroy & operator = ( Destroy && ) = default ;
393  Destroy & operator = ( const Destroy & ) = default ;
394 
395  Destroy( typename traits::value_type ** arg_chunk
396  , const unsigned arg_chunk_max
397  , const unsigned arg_chunk_size )
398  : m_chunks( arg_chunk )
399  , m_chunk_max( arg_chunk_max )
400  , m_destroy( false )
401  , m_chunk_size( arg_chunk_size )
402  {}
403  };
404 
405 
412  explicit inline
413  DynamicView( const std::string & arg_label
414  , const unsigned min_chunk_size
415  , const unsigned max_extent )
416  : m_track()
417  , m_chunks(0)
418  // The chunk size is guaranteed to be a power of two
419  , m_chunk_shift(
420  Kokkos::Impl::integral_power_of_two_that_contains( min_chunk_size ) ) // div ceil(log2(min_chunk_size))
421  , m_chunk_mask( ( 1 << m_chunk_shift ) - 1 ) // mod
422  , m_chunk_max( ( max_extent + m_chunk_mask ) >> m_chunk_shift ) // max num pointers-to-chunks in array
423  , m_chunk_size ( 2 << (m_chunk_shift - 1) )
424  {
425  typedef typename Impl::ChunkArraySpace< typename traits::memory_space >::memory_space chunk_array_memory_space;
426  // A functor to deallocate all of the chunks upon final destruction
427  typedef Kokkos::Impl::SharedAllocationRecord< chunk_array_memory_space , Destroy > record_type ;
428 
429  // Allocate chunk pointers and allocation counter
430  record_type * const record =
431  record_type::allocate( chunk_array_memory_space()
432  , arg_label
433  , ( sizeof(pointer_type) * ( m_chunk_max + 2 ) ) );
434  // Allocate + 2 extra slots so that *m_chunk[m_chunk_max] == num_chunks_alloc and *m_chunk[m_chunk_max+1] == extent
435  // This must match in Destroy's execute(...) method
436 
437  m_chunks = reinterpret_cast<pointer_type*>( record->data() );
438 
439  record->m_destroy = Destroy( m_chunks , m_chunk_max, m_chunk_size );
440 
441  // Initialize to zero
442  record->m_destroy.construct_shared_allocation();
443 
444  m_track.assign_allocated_record_to_uninitialized( record );
445  }
446 
447 };
448 
449 } // namespace Experimental
450 } // namespace Kokkos
451 
452 namespace Kokkos {
453 
454 template< class T , class ... P >
455 inline
457 create_mirror_view( const Kokkos::Experimental::DynamicView<T,P...> & src )
458 {
459  return src ;
460 }
461 
462 template< class T , class ... DP , class ... SP >
463 inline
464 void deep_copy( const View<T,DP...> & dst
466  )
467 {
468  typedef View<T,DP...> dst_type ;
469  typedef Kokkos::Experimental::DynamicView<T,SP...> src_type ;
470 
471  typedef typename ViewTraits<T,DP...>::execution_space dst_execution_space ;
472  typedef typename ViewTraits<T,SP...>::memory_space src_memory_space ;
473 
474  enum { DstExecCanAccessSrc =
476 
477  if ( DstExecCanAccessSrc ) {
478  // Copying data between views in accessible memory spaces and either non-contiguous or incompatible shape.
479  Kokkos::Impl::ViewRemap< dst_type , src_type >( dst , src );
480  }
481  else {
482  Kokkos::Impl::throw_runtime_exception("deep_copy given views that would require a temporary allocation");
483  }
484 }
485 
486 template< class T , class ... DP , class ... SP >
487 inline
489  , const View<T,SP...> & src
490  )
491 {
492  typedef Kokkos::Experimental::DynamicView<T,SP...> dst_type ;
493  typedef View<T,DP...> src_type ;
494 
495  typedef typename ViewTraits<T,DP...>::execution_space dst_execution_space ;
496  typedef typename ViewTraits<T,SP...>::memory_space src_memory_space ;
497 
498  enum { DstExecCanAccessSrc =
500 
501  if ( DstExecCanAccessSrc ) {
502  // Copying data between views in accessible memory spaces and either non-contiguous or incompatible shape.
503  Kokkos::Impl::ViewRemap< dst_type , src_type >( dst , src );
504  }
505  else {
506  Kokkos::Impl::throw_runtime_exception("deep_copy given views that would require a temporary allocation");
507  }
508 }
509 
510 namespace Impl {
511 template<class Arg0, class ... DP , class ... SP>
512 struct CommonSubview<Kokkos::Experimental::DynamicView<DP...>,Kokkos::Experimental::DynamicView<SP...>,1,Arg0> {
513  typedef Kokkos::Experimental::DynamicView<DP...> DstType;
514  typedef Kokkos::Experimental::DynamicView<SP...> SrcType;
515  typedef DstType dst_subview_type;
516  typedef SrcType src_subview_type;
517  dst_subview_type dst_sub;
518  src_subview_type src_sub;
519  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0):
520  dst_sub(dst),src_sub(src) {}
521 };
522 
523 template<class ...DP, class SrcType, class Arg0>
524 struct CommonSubview<Kokkos::Experimental::DynamicView<DP...>,SrcType,1,Arg0> {
525  typedef Kokkos::Experimental::DynamicView<DP...> DstType;
526  typedef DstType dst_subview_type;
527  typedef typename Kokkos::Subview<SrcType,Arg0> src_subview_type;
528  dst_subview_type dst_sub;
529  src_subview_type src_sub;
530  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0):
531  dst_sub(dst),src_sub(src,arg0) {}
532 };
533 
534 template<class DstType, class ...SP, class Arg0>
535 struct CommonSubview<DstType,Kokkos::Experimental::DynamicView<SP...>,1,Arg0> {
536  typedef Kokkos::Experimental::DynamicView<SP...> SrcType;
537  typedef typename Kokkos::Subview<DstType,Arg0> dst_subview_type;
538  typedef SrcType src_subview_type;
539  dst_subview_type dst_sub;
540  src_subview_type src_sub;
541  CommonSubview(const DstType& dst, const SrcType& src, const Arg0& arg0):
542  dst_sub(dst,arg0),src_sub(src) {}
543 };
544 
545 template<class ...DP,class ViewTypeB, class Layout, class ExecSpace,typename iType>
546 struct ViewCopy<Kokkos::Experimental::DynamicView<DP...>,ViewTypeB,Layout,ExecSpace,1,iType,false> {
548  ViewTypeB b;
549 
551 
552  ViewCopy(const Kokkos::Experimental::DynamicView<DP...>& a_, const ViewTypeB& b_):a(a_),b(b_) {
553  Kokkos::parallel_for("Kokkos::ViewCopy-1D",
554  policy_type(0,b.extent(0)),*this);
555  }
556 
557  KOKKOS_INLINE_FUNCTION
558  void operator() (const iType& i0) const {
559  a(i0) = b(i0);
560  };
561 };
562 
563 template<class ...DP,class ...SP, class Layout, class ExecSpace,typename iType>
564 struct ViewCopy<Kokkos::Experimental::DynamicView<DP...>,
565  Kokkos::Experimental::DynamicView<SP...>,Layout,ExecSpace,1,iType,false> {
568 
570 
571  ViewCopy(const Kokkos::Experimental::DynamicView<DP...>& a_,
572  const Kokkos::Experimental::DynamicView<SP...>& b_):a(a_),b(b_) {
573  const iType n = std::min(a.extent(0),b.extent(0));
574  Kokkos::parallel_for("Kokkos::ViewCopy-1D",
575  policy_type(0,n),*this);
576  }
577 
578  KOKKOS_INLINE_FUNCTION
579  void operator() (const iType& i0) const {
580  a(i0) = b(i0);
581  };
582 };
583 
584 } // namespace Impl
585 } // namespace Kokkos
586 
587 #endif /* #ifndef KOKKOS_DYNAMIC_VIEW_HPP */
588 
DynamicView< typename traits::data_type, typename traits::device_type > array_type
Compatible view of array of scalar types.
DynamicView(const std::string &arg_label, const unsigned min_chunk_size, const unsigned max_extent)
Allocation constructor.
void parallel_for(const ExecPolicy &policy, const FunctorType &functor, const std::string &str="", typename Impl::enable_if< Kokkos::Impl::is_execution_policy< ExecPolicy >::value >::type *=0)
Execute functor in parallel according to the execution policy.
Dynamic views are restricted to rank-one and no layout. Resize only occurs on host outside of paralle...
Can AccessSpace access MemorySpace ?
DynamicView< typename traits::const_data_type, typename traits::device_type > const_type
Compatible view of const data type.
View to an array of data.
Memory management for host memory.
DynamicView HostMirror
Must be accessible everywhere.
Implementation of the ParallelFor operator that has a partial specialization for the device...
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.
Execution policy for work over a range of an integral type.
std::enable_if< std::is_integral< IntType >::value &&Kokkos::Impl::MemorySpaceAccess< Kokkos::HostSpace, typename Impl::ChunkArraySpace< typename traits::memory_space >::memory_space >::accessible >::type resize_serial(IntType const &n)
Resizing in serial can grow or shrink the array size up to the maximum number of chunks.
Traits class for accessing attributes of a View.
Kokkos::Device< typename traits::device_type::execution_space, Kokkos::AnonymousSpace > uniform_device
Unified types.
Access relationship between DstMemorySpace and SrcMemorySpace.
DynamicView< typename traits::non_const_data_type, typename traits::device_type > non_const_type
Compatible view of non-const data type.