Kokkos Core Kernels Package  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
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
456 typename Kokkos::Experimental::DynamicView<T,P...>::HostMirror
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.
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.
Memory management for host memory.
DynamicView HostMirror
Must be accessible everywhere.
Implementation of the ParallelFor operator that has a partial specialization for the device...
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.