44 #ifndef KOKKOS_DYNAMIC_VIEW_HPP 45 #define KOKKOS_DYNAMIC_VIEW_HPP 49 #include <Kokkos_Core.hpp> 50 #include <impl/Kokkos_Error.hpp> 61 template <
class MemSpace >
62 struct ChunkArraySpace {
63 using memory_space = MemSpace;
66 #ifdef KOKKOS_ENABLE_CUDA 68 struct ChunkArraySpace<
Kokkos::CudaSpace > {
69 using memory_space =
typename Kokkos::CudaUVMSpace;
72 #ifdef KOKKOS_ENABLE_ROCM 74 struct ChunkArraySpace<
Kokkos::Experimental::ROCmSpace > {
75 using memory_space =
typename Kokkos::Experimental::ROCmHostPinnedSpace;
84 template<
typename DataType ,
typename ... P >
93 template< class ,
class ... >
friend class DynamicView ;
95 typedef Kokkos::Impl::SharedAllocationTracker track_type ;
97 static_assert( traits::rank == 1 && traits::rank_dynamic == 1
98 ,
"DynamicView must be rank-one" );
102 static_assert( std::is_same< typename traits::specialize , void >::value
103 ,
"DynamicView only implemented for non-specialized View type");
106 template< class Space , bool = Kokkos::Impl::MemorySpaceAccess< Space , typename traits::memory_space >::accessible >
struct verify_space
107 { KOKKOS_FORCEINLINE_FUNCTION
static void check() {} };
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"); };
117 typename traits::value_type ** m_chunks ;
118 unsigned m_chunk_shift ;
119 unsigned m_chunk_mask ;
120 unsigned m_chunk_max ;
121 unsigned m_chunk_size ;
129 typename traits::device_type >
133 typedef DynamicView<
typename traits::const_data_type ,
134 typename traits::device_type >
138 typedef DynamicView<
typename traits::non_const_data_type ,
139 typename traits::device_type >
146 typedef Kokkos::Device<typename traits::device_type::execution_space, Kokkos::AnonymousSpace>
uniform_device;
160 KOKKOS_INLINE_FUNCTION
161 size_t allocation_extent()
const noexcept
163 uintptr_t n = *
reinterpret_cast<const uintptr_t*
>( m_chunks + m_chunk_max );
164 return (n << m_chunk_shift);
167 KOKKOS_INLINE_FUNCTION
168 size_t chunk_size()
const noexcept
173 KOKKOS_INLINE_FUNCTION
174 size_t size()
const noexcept
176 size_t extent_0 = *
reinterpret_cast<const size_t*
>( m_chunks + m_chunk_max +1 );
180 template<
typename iType >
181 KOKKOS_INLINE_FUNCTION
182 size_t extent(
const iType & r )
const 183 {
return r == 0 ? size() : 1 ; }
185 template<
typename iType >
186 KOKKOS_INLINE_FUNCTION
187 size_t extent_int(
const iType & r )
const 188 {
return r == 0 ? size() : 1 ; }
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 ; }
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 ; }
210 template<
typename iType >
211 KOKKOS_INLINE_FUNCTION
void stride( iType *
const s )
const { *s = 0 ; }
216 KOKKOS_INLINE_FUNCTION
217 int use_count()
const 218 {
return m_track.use_count(); }
221 const std::string label()
const 222 {
return m_track.template get_label< typename traits::memory_space >(); }
227 typedef typename traits::value_type & reference_type ;
228 typedef typename traits::value_type * pointer_type ;
230 enum { reference_type_is_lvalue_reference = std::is_lvalue_reference< reference_type >::value };
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 ; }
238 template<
typename I0 ,
class ... Args >
239 KOKKOS_INLINE_FUNCTION
240 reference_type operator()(
const I0 & i0 ,
const Args & ... args )
const 242 static_assert( Kokkos::Impl::are_integral<I0,Args...>::value
243 ,
"Indices must be integral type" );
245 DynamicView::template verify_space< Kokkos::Impl::ActiveExecutionMemorySpace >::check();
248 const uintptr_t ic = uintptr_t( i0 >> m_chunk_shift );
250 typename traits::value_type *
volatile *
const ch = m_chunks + ic ;
255 #if ! defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK ) 263 *
reinterpret_cast<uintptr_t
volatile *
>( m_chunks + m_chunk_max );
266 Kokkos::abort(
"Kokkos::DynamicView array bounds error");
274 return (*ch)[ i0 & m_chunk_mask ];
281 template<
typename IntType >
283 typename std::enable_if
284 < std::is_integral<IntType>::value &&
286 ,
typename Impl::ChunkArraySpace< typename traits::memory_space >::memory_space
291 typedef typename traits::value_type value_type ;
292 typedef value_type * value_pointer_type ;
294 const uintptr_t NC = ( n + m_chunk_mask ) >> m_chunk_shift ;
296 if ( m_chunk_max < NC ) {
297 Kokkos::abort(
"DynamicView::resize_serial exceeded maximum size");
301 uintptr_t *
const pc =
302 reinterpret_cast<uintptr_t*
>( m_chunks + m_chunk_max );
306 m_chunks[*pc] =
reinterpret_cast<value_pointer_type
> 308 typename traits::memory_space().allocate(
sizeof(value_type) << m_chunk_shift )
314 while ( NC + 1 <= *pc ) {
316 typename traits::memory_space().deallocate( m_chunks[*pc]
317 ,
sizeof(value_type) << m_chunk_shift );
334 template<
class RT ,
class ... RP >
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 )
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" );
351 typename traits::value_type ** m_chunks ;
352 unsigned m_chunk_max ;
354 unsigned m_chunk_size ;
359 void operator()(
unsigned i )
const 361 if ( m_destroy && i < m_chunk_max && 0 != m_chunks[i] ) {
362 typename traits::memory_space().deallocate( m_chunks[i], m_chunk_size );
367 void execute(
bool arg_destroy )
372 m_destroy = arg_destroy ;
375 closure( *
this , Range(0, m_chunk_max + 2) );
379 traits::execution_space::fence();
383 void construct_shared_allocation()
384 { execute(
false ); }
386 void destroy_shared_allocation()
389 Destroy() = default ;
390 Destroy( Destroy && ) = default ;
391 Destroy(
const Destroy & ) = default ;
392 Destroy & operator = ( Destroy && ) = default ;
393 Destroy & operator = (
const Destroy & ) = default ;
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 )
401 , m_chunk_size( arg_chunk_size )
414 ,
const unsigned min_chunk_size
415 ,
const unsigned max_extent )
420 Kokkos::Impl::integral_power_of_two_that_contains( min_chunk_size ) )
421 , m_chunk_mask( ( 1 << m_chunk_shift ) - 1 )
422 , m_chunk_max( ( max_extent + m_chunk_mask ) >> m_chunk_shift )
423 , m_chunk_size ( 2 << (m_chunk_shift - 1) )
425 typedef typename Impl::ChunkArraySpace< typename traits::memory_space >::memory_space chunk_array_memory_space;
427 typedef Kokkos::Impl::SharedAllocationRecord< chunk_array_memory_space , Destroy > record_type ;
430 record_type *
const record =
431 record_type::allocate( chunk_array_memory_space()
433 , (
sizeof(pointer_type) * ( m_chunk_max + 2 ) ) );
437 m_chunks =
reinterpret_cast<pointer_type*
>( record->data() );
439 record->m_destroy = Destroy( m_chunks , m_chunk_max, m_chunk_size );
442 record->m_destroy.construct_shared_allocation();
444 m_track.assign_allocated_record_to_uninitialized( record );
454 template<
class T ,
class ... P >
462 template<
class T ,
class ... DP ,
class ... SP >
468 typedef View<T,DP...> dst_type ;
471 typedef typename ViewTraits<T,DP...>::execution_space dst_execution_space ;
472 typedef typename ViewTraits<T,SP...>::memory_space src_memory_space ;
474 enum { DstExecCanAccessSrc =
477 if ( DstExecCanAccessSrc ) {
479 Kokkos::Impl::ViewRemap< dst_type , src_type >( dst , src );
482 Kokkos::Impl::throw_runtime_exception(
"deep_copy given views that would require a temporary allocation");
486 template<
class T ,
class ... DP ,
class ... SP >
493 typedef View<T,DP...> src_type ;
495 typedef typename ViewTraits<T,DP...>::execution_space dst_execution_space ;
496 typedef typename ViewTraits<T,SP...>::memory_space src_memory_space ;
498 enum { DstExecCanAccessSrc =
501 if ( DstExecCanAccessSrc ) {
503 Kokkos::Impl::ViewRemap< dst_type , src_type >( dst , src );
506 Kokkos::Impl::throw_runtime_exception(
"deep_copy given views that would require a temporary allocation");
511 template<
class Arg0,
class ... DP ,
class ... SP>
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) {}
523 template<
class ...DP,
class SrcType,
class Arg0>
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) {}
534 template<
class DstType,
class ...SP,
class Arg0>
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) {}
545 template<
class ...DP,
class ViewTypeB,
class Layout,
class ExecSpace,
typename iType>
554 policy_type(0,b.extent(0)),*
this);
557 KOKKOS_INLINE_FUNCTION
558 void operator() (
const iType& i0)
const {
563 template<
class ...DP,
class ...SP,
class Layout,
class ExecSpace,
typename iType>
573 const iType n = std::min(a.extent(0),b.extent(0));
575 policy_type(0,n),*
this);
578 KOKKOS_INLINE_FUNCTION
579 void operator() (
const iType& i0)
const {
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.