44 #ifndef KOKKOS_DYNAMIC_VIEW_HPP 45 #define KOKKOS_DYNAMIC_VIEW_HPP 49 #include <Kokkos_Core.hpp> 50 #include <impl/Kokkos_Error.hpp> 58 template<
typename DataType ,
typename ... P >
67 template< class ,
class ... >
friend class DynamicView ;
69 typedef Kokkos::Experimental::Impl::SharedAllocationTracker track_type ;
71 static_assert( traits::rank == 1 && traits::rank_dynamic == 1
72 ,
"DynamicView must be rank-one" );
74 static_assert( std::is_trivial< typename traits::value_type >::value &&
75 std::is_same< typename traits::specialize , void >::value
76 ,
"DynamicView must have trivial data type" );
79 template< class Space , bool = Kokkos::Impl::MemorySpaceAccess< Space , typename traits::memory_space >::accessible >
struct verify_space
80 { KOKKOS_FORCEINLINE_FUNCTION
static void check() {} };
82 template<
class Space >
struct verify_space<Space,false>
83 { KOKKOS_FORCEINLINE_FUNCTION
static void check()
84 { Kokkos::abort(
"Kokkos::DynamicView ERROR: attempt to access inaccessible memory space"); };
89 typedef Kokkos::MemoryPool< typename traits::device_type > memory_pool ;
95 typename traits::value_type ** m_chunks ;
96 unsigned m_chunk_shift ;
97 unsigned m_chunk_mask ;
98 unsigned m_chunk_max ;
110 typedef DynamicView<
typename traits::const_data_type ,
115 typedef DynamicView<
typename traits::non_const_data_type ,
126 KOKKOS_INLINE_FUNCTION
127 size_t size()
const noexcept
132 < Kokkos::Impl::ActiveExecutionMemorySpace
133 ,
typename traits::memory_space
135 n = *
reinterpret_cast<const uintptr_t*
>( m_chunks + m_chunk_max );
137 #if defined( KOKKOS_ACTIVE_EXECUTION_MEMORY_SPACE_HOST ) 140 ,
typename traits::memory_space
141 , Kokkos::HostSpace::execution_space >
143 ,
reinterpret_cast<const uintptr_t*
>( m_chunks + m_chunk_max )
144 ,
sizeof(uintptr_t) );
147 return n << m_chunk_shift ;
150 template<
typename iType >
151 KOKKOS_INLINE_FUNCTION
152 size_t extent(
const iType & r )
const 153 {
return r == 0 ? size() : 1 ; }
155 template<
typename iType >
156 KOKKOS_INLINE_FUNCTION
157 size_t extent_int(
const iType & r )
const 158 {
return r == 0 ? size() : 1 ; }
160 KOKKOS_INLINE_FUNCTION
size_t dimension_0()
const {
return size(); }
161 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_1()
const {
return 1 ; }
162 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_2()
const {
return 1 ; }
163 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_3()
const {
return 1 ; }
164 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_4()
const {
return 1 ; }
165 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_5()
const {
return 1 ; }
166 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_6()
const {
return 1 ; }
167 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_7()
const {
return 1 ; }
169 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_0()
const {
return 0 ; }
170 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_1()
const {
return 0 ; }
171 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_2()
const {
return 0 ; }
172 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_3()
const {
return 0 ; }
173 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_4()
const {
return 0 ; }
174 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_5()
const {
return 0 ; }
175 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_6()
const {
return 0 ; }
176 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_7()
const {
return 0 ; }
178 template<
typename iType >
179 KOKKOS_INLINE_FUNCTION
void stride( iType *
const s )
const { *s = 0 ; }
184 typedef typename traits::value_type & reference_type ;
185 typedef typename traits::value_type * pointer_type ;
187 enum { reference_type_is_lvalue_reference = std::is_lvalue_reference< reference_type >::value };
189 KOKKOS_INLINE_FUNCTION constexpr
bool span_is_contiguous()
const {
return false ; }
190 KOKKOS_INLINE_FUNCTION constexpr
size_t span()
const {
return 0 ; }
191 KOKKOS_INLINE_FUNCTION constexpr pointer_type data()
const {
return 0 ; }
195 template<
typename I0 ,
class ... Args >
196 KOKKOS_INLINE_FUNCTION
197 reference_type operator()(
const I0 & i0 ,
const Args & ... args )
const 199 static_assert( Kokkos::Impl::are_integral<I0,Args...>::value
200 ,
"Indices must be integral type" );
202 DynamicView::template verify_space< Kokkos::Impl::ActiveExecutionMemorySpace >::check();
205 const uintptr_t ic = uintptr_t( i0 >> m_chunk_shift );
207 typename traits::value_type *
volatile *
const ch = m_chunks + ic ;
212 #if ! defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK ) 220 *
reinterpret_cast<uintptr_t
volatile *
>( m_chunks + m_chunk_max );
223 Kokkos::abort(
"Kokkos::DynamicView array bounds error");
231 return (*ch)[ i0 & m_chunk_mask ];
238 KOKKOS_INLINE_FUNCTION
241 typedef typename traits::value_type value_type ;
243 DynamicView::template verify_space< Kokkos::Impl::ActiveExecutionMemorySpace >::check();
245 const uintptr_t NC = ( n + m_chunk_mask ) >> m_chunk_shift ;
247 if ( m_chunk_max < NC ) {
248 #if defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK ) 249 printf(
"DynamicView::resize_parallel(%lu) m_chunk_max(%u) NC(%lu)\n" 250 , n , m_chunk_max , NC );
252 Kokkos::abort(
"DynamicView::resize_parallel exceeded maximum size");
255 typename traits::value_type *
volatile *
const ch = m_chunks ;
258 uintptr_t
volatile *
const pc =
259 reinterpret_cast<uintptr_t volatile*
>( m_chunks + m_chunk_max );
263 for ( uintptr_t jc = *pc ; jc < NC ; ) {
267 const uintptr_t jc_try = jc ;
271 jc = atomic_compare_exchange( pc , jc_try , jc_try + 1 );
273 if ( jc_try == jc ) {
275 ch[jc_try] =
reinterpret_cast<value_type*
>(
276 m_pool.allocate(
sizeof(value_type) << m_chunk_shift ));
278 if ( 0 == ch[jc_try] ) {
279 Kokkos::abort(
"DynamicView::resize_parallel exhausted memory pool");
282 Kokkos::memory_fence();
288 template<
typename IntType >
290 typename std::enable_if
291 < std::is_integral<IntType>::value &&
293 ,
typename traits::memory_space
298 typedef typename traits::value_type value_type ;
299 typedef value_type * pointer_type ;
301 const uintptr_t NC = ( n + m_chunk_mask ) >> m_chunk_shift ;
303 if ( m_chunk_max < NC ) {
304 Kokkos::abort(
"DynamicView::resize_serial exceeded maximum size");
307 uintptr_t *
const pc =
308 reinterpret_cast<uintptr_t*
>( m_chunks + m_chunk_max );
312 m_chunks[*pc] =
reinterpret_cast<pointer_type
> 313 ( m_pool.allocate(
sizeof(value_type) << m_chunk_shift ) );
318 while ( NC + 1 <= *pc ) {
320 m_pool.deallocate( m_chunks[*pc]
321 ,
sizeof(value_type) << m_chunk_shift );
329 struct ResizeSerial {
331 typename traits::value_type ** m_chunks ;
334 unsigned m_chunk_shift ;
336 KOKKOS_INLINE_FUNCTION
337 void operator()(
int )
const 339 typedef typename traits::value_type value_type ;
340 typedef value_type * pointer_type ;
342 if ( *m_pc < m_nc ) {
343 while ( *m_pc < m_nc ) {
344 m_chunks[*m_pc] =
reinterpret_cast<pointer_type
> 345 ( m_pool.allocate(
sizeof(value_type) << m_chunk_shift ) );
350 while ( m_nc + 1 <= *m_pc ) {
352 m_pool.deallocate( m_chunks[*m_pc]
353 ,
sizeof(value_type) << m_chunk_shift );
354 m_chunks[*m_pc] = 0 ;
359 ResizeSerial( memory_pool
const & arg_pool
360 ,
typename traits::value_type ** arg_chunks
363 ,
unsigned arg_chunk_shift
366 , m_chunks( arg_chunks )
369 , m_chunk_shift( arg_chunk_shift )
373 template<
typename IntType >
375 typename std::enable_if
376 < std::is_integral<IntType>::value &&
378 ,
typename traits::memory_space
383 const uintptr_t NC = ( n + m_chunk_mask ) >> m_chunk_shift ;
385 if ( m_chunk_max < NC ) {
386 Kokkos::abort(
"DynamicView::resize_serial exceeded maximum size");
393 uintptr_t *
const pc =
394 reinterpret_cast<uintptr_t*
>( m_chunks + m_chunk_max );
397 closure( ResizeSerial( m_pool, m_chunks, pc, NC, m_chunk_shift )
402 traits::execution_space::fence();
414 template<
class RT ,
class ... RP >
416 : m_pool( rhs.m_pool )
417 , m_track( rhs.m_track )
418 , m_chunks( (
typename traits::value_type **) rhs.m_chunks )
419 , m_chunk_shift( rhs.m_chunk_shift )
420 , m_chunk_mask( rhs.m_chunk_mask )
421 , m_chunk_max( rhs.m_chunk_max )
423 typedef typename DynamicView<RT,RP...>
::traits SrcTraits ;
424 typedef Kokkos::Impl::ViewMapping< traits , SrcTraits , void > Mapping ;
425 static_assert( Mapping::is_assignable ,
"Incompatible DynamicView copy construction" );
432 typename traits::value_type ** m_chunks ;
433 unsigned m_chunk_max ;
439 KOKKOS_INLINE_FUNCTION
440 void operator()(
unsigned i )
const 442 if ( m_destroy && i < m_chunk_max && 0 != m_chunks[i] ) {
443 m_pool.deallocate( m_chunks[i] , m_pool.min_block_size() );
448 void execute(
bool arg_destroy )
452 m_destroy = arg_destroy ;
455 closure( *
this , Range(0, m_chunk_max + 1) );
459 traits::execution_space::fence();
462 void construct_shared_allocation()
463 { execute(
false ); }
465 void destroy_shared_allocation()
468 Destroy() = default ;
469 Destroy( Destroy && ) = default ;
470 Destroy(
const Destroy & ) = default ;
471 Destroy & operator = ( Destroy && ) = default ;
472 Destroy & operator = (
const Destroy & ) = default ;
474 Destroy(
const memory_pool & arg_pool
475 ,
typename traits::value_type ** arg_chunk
476 ,
const unsigned arg_chunk_max )
478 , m_chunks( arg_chunk )
479 , m_chunk_max( arg_chunk_max )
494 ,
const memory_pool & arg_pool
495 ,
const size_t arg_size_max )
501 Kokkos::Impl::integral_power_of_two(
502 m_pool.min_block_size()/sizeof(typename
traits::value_type)) )
503 , m_chunk_mask( ( 1 << m_chunk_shift ) - 1 )
504 , m_chunk_max( ( arg_size_max + m_chunk_mask ) >> m_chunk_shift )
508 typedef typename traits::memory_space memory_space ;
509 typedef Kokkos::Experimental::Impl::SharedAllocationRecord< memory_space , Destroy > record_type ;
512 record_type *
const record =
513 record_type::allocate( memory_space()
515 , (
sizeof(pointer_type) * ( m_chunk_max + 1 ) ) );
517 m_chunks =
reinterpret_cast<pointer_type*
>( record->data() );
519 record->m_destroy = Destroy( m_pool , m_chunks , m_chunk_max );
523 record->m_destroy.construct_shared_allocation();
525 m_track.assign_allocated_record_to_uninitialized( record );
535 template<
class T ,
class ... P >
543 template<
class T ,
class ... DP ,
class ... SP >
549 typedef View<T,DP...> dst_type ;
552 typedef typename ViewTraits<T,DP...>::execution_space dst_execution_space ;
553 typedef typename ViewTraits<T,SP...>::memory_space src_memory_space ;
555 enum { DstExecCanAccessSrc =
558 if ( DstExecCanAccessSrc ) {
560 Kokkos::Experimental::Impl::ViewRemap< dst_type , src_type >( dst , src );
563 Kokkos::Impl::throw_runtime_exception(
"deep_copy given views that would require a temporary allocation");
567 template<
class T ,
class ... DP ,
class ... SP >
574 typedef View<T,DP...> src_type ;
576 typedef typename ViewTraits<T,DP...>::execution_space dst_execution_space ;
577 typedef typename ViewTraits<T,SP...>::memory_space src_memory_space ;
579 enum { DstExecCanAccessSrc =
582 if ( DstExecCanAccessSrc ) {
584 Kokkos::Experimental::Impl::ViewRemap< dst_type , src_type >( dst , src );
587 Kokkos::Impl::throw_runtime_exception(
"deep_copy given views that would require a temporary allocation");
DynamicView< typename traits::data_type, typename traits::device_type > array_type
Compatible view of array of scalar types.
Dynamic views are restricted to rank-one and no layout. Subviews are not allowed. ...
DynamicView(const std::string &arg_label, const memory_pool &arg_pool, const size_t arg_size_max)
Allocation constructor.
std::enable_if< std::is_integral< IntType >::value &&Kokkos::Impl::MemorySpaceAccess< Kokkos::HostSpace, typename traits::memory_space >::accessible >::type resize_serial(IntType const &n)
Resizing in serial can grow or shrink the array size,.
DynamicView< typename traits::const_data_type, typename traits::device_type > const_type
Compatible view of const data type.
KOKKOS_INLINE_FUNCTION void resize_parallel(size_t n) const
Resizing in parallel only increases the array size, never decrease.
View to an array of data.
Can AccessSpace access MemorySpace ?
Memory space for main process and CPU execution spaces.
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.
Traits class for accessing attributes of a View.
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.