44 #ifndef KOKKOS_DYNAMIC_VIEW_HPP 45 #define KOKKOS_DYNAMIC_VIEW_HPP 49 #include <Kokkos_Core.hpp> 50 #include <impl/Kokkos_Error.hpp> 53 namespace Experimental {
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" );
86 typename traits::value_type ** m_chunks ;
87 unsigned m_chunk_shift ;
88 unsigned m_chunk_mask ;
89 unsigned m_chunk_max ;
101 typedef DynamicView<
typename traits::const_data_type ,
106 typedef DynamicView<
typename traits::non_const_data_type ,
117 KOKKOS_INLINE_FUNCTION constexpr
size_t size()
const 120 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace
121 < Kokkos::Impl::ActiveExecutionMemorySpace
122 ,
typename traits::memory_space
125 (*
reinterpret_cast<const uintptr_t*
>( m_chunks + m_chunk_max ))
130 template<
typename iType >
131 KOKKOS_INLINE_FUNCTION constexpr
132 size_t extent(
const iType & r )
const 133 {
return r == 0 ? size() : 1 ; }
135 template<
typename iType >
136 KOKKOS_INLINE_FUNCTION constexpr
137 size_t extent_int(
const iType & r )
const 138 {
return r == 0 ? size() : 1 ; }
140 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_0()
const {
return size(); }
141 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_1()
const {
return 1 ; }
142 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_2()
const {
return 1 ; }
143 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_3()
const {
return 1 ; }
144 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_4()
const {
return 1 ; }
145 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_5()
const {
return 1 ; }
146 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_6()
const {
return 1 ; }
147 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_7()
const {
return 1 ; }
149 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_0()
const {
return 0 ; }
150 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_1()
const {
return 0 ; }
151 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_2()
const {
return 0 ; }
152 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_3()
const {
return 0 ; }
153 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_4()
const {
return 0 ; }
154 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_5()
const {
return 0 ; }
155 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_6()
const {
return 0 ; }
156 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_7()
const {
return 0 ; }
158 template<
typename iType >
159 KOKKOS_INLINE_FUNCTION
void stride( iType *
const s )
const { *s = 0 ; }
164 typedef typename traits::value_type & reference_type ;
165 typedef typename traits::value_type * pointer_type ;
167 enum { reference_type_is_lvalue_reference = std::is_lvalue_reference< reference_type >::value };
169 KOKKOS_INLINE_FUNCTION constexpr
bool span_is_contiguous()
const {
return false ; }
170 KOKKOS_INLINE_FUNCTION constexpr
size_t span()
const {
return 0 ; }
171 KOKKOS_INLINE_FUNCTION constexpr pointer_type data()
const {
return 0 ; }
175 template<
typename I0 ,
class ... Args >
176 KOKKOS_INLINE_FUNCTION
177 reference_type operator()(
const I0 & i0 ,
const Args & ... args )
const 179 static_assert( Kokkos::Impl::are_integral<I0,Args...>::value
180 ,
"Indices must be integral type" );
182 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace
183 < Kokkos::Impl::ActiveExecutionMemorySpace
184 ,
typename traits::memory_space
188 const uintptr_t ic = uintptr_t( i0 >> m_chunk_shift );
190 typename traits::value_type *
volatile *
const ch = m_chunks + ic ;
195 #if ! defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK ) 203 *
reinterpret_cast<uintptr_t
volatile *
>( m_chunks + m_chunk_max );
206 Kokkos::abort(
"Kokkos::DynamicView array bounds error");
214 return (*ch)[ i0 & m_chunk_mask ];
221 KOKKOS_INLINE_FUNCTION
224 typedef typename traits::value_type value_type ;
226 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace
227 < Kokkos::Impl::ActiveExecutionMemorySpace
228 ,
typename traits::memory_space >::verify();
230 const uintptr_t NC = ( n + m_chunk_mask ) >> m_chunk_shift ;
232 if ( m_chunk_max < NC ) {
233 #if defined( KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK ) 234 printf(
"DynamicView::resize_parallel(%lu) m_chunk_max(%u) NC(%lu)\n" 235 , n , m_chunk_max , NC );
237 Kokkos::abort(
"DynamicView::resize_parallel exceeded maximum size");
240 typename traits::value_type *
volatile *
const ch = m_chunks ;
243 uintptr_t
volatile *
const pc =
244 reinterpret_cast<uintptr_t volatile*
>( m_chunks + m_chunk_max );
248 for ( uintptr_t jc = *pc ; jc < NC ; ) {
252 const uintptr_t jc_try = jc ;
256 jc = atomic_compare_exchange( pc , jc_try , jc_try + 1 );
258 if ( jc_try == jc ) {
260 ch[jc_try] =
reinterpret_cast<value_type*
>(
261 m_pool.
allocate(
sizeof(value_type) << m_chunk_shift ));
263 Kokkos::memory_fence();
272 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace
273 < Kokkos::Impl::ActiveExecutionMemorySpace
274 ,
typename traits::memory_space >::verify();
276 const uintptr_t NC = ( n + m_chunk_mask ) >> m_chunk_shift ;
278 if ( m_chunk_max < NC ) {
279 Kokkos::abort(
"DynamicView::resize_serial exceeded maximum size");
282 uintptr_t *
const pc =
283 reinterpret_cast<uintptr_t*
>( m_chunks + m_chunk_max );
288 m_pool.
allocate(
sizeof(traits::value_type) << m_chunk_shift );
293 while ( NC + 1 <= *pc ) {
296 ,
sizeof(traits::value_type) << m_chunk_shift );
311 template<
class RT ,
class ... RP >
312 KOKKOS_INLINE_FUNCTION
314 : m_pool( rhs.m_pool )
315 , m_track( rhs.m_track )
316 , m_chunks( rhs.m_chunks )
317 , m_chunk_shift( rhs.m_chunk_shift )
318 , m_chunk_mask( rhs.m_chunk_mask )
319 , m_chunk_max( rhs.m_chunk_max )
327 typename traits::value_type ** m_chunks ;
328 unsigned m_chunk_max ;
334 KOKKOS_INLINE_FUNCTION
335 void operator()(
unsigned i )
const 337 if ( m_destroy && i < m_chunk_max && 0 != m_chunks[i] ) {
338 m_pool.deallocate( m_chunks[i] , m_pool.get_min_block_size() );
343 void execute(
bool arg_destroy )
347 m_destroy = arg_destroy ;
350 closure( *
this , Range(0, m_chunk_max + 1) );
354 traits::execution_space::fence();
357 void construct_shared_allocation()
358 { execute(
false ); }
360 void destroy_shared_allocation()
363 Destroy() = default ;
364 Destroy( Destroy && ) = default ;
365 Destroy(
const Destroy & ) = default ;
366 Destroy & operator = ( Destroy && ) = default ;
367 Destroy & operator = (
const Destroy & ) = default ;
369 Destroy(
const memory_pool & arg_pool
370 ,
typename traits::value_type ** arg_chunk
371 ,
const unsigned arg_chunk_max )
373 , m_chunks( arg_chunk )
374 , m_chunk_max( arg_chunk_max )
390 ,
const size_t arg_size_max )
396 Kokkos::Impl::integral_power_of_two(
397 m_pool.get_min_block_size()/sizeof(typename
traits::value_type)) )
398 , m_chunk_mask( ( 1 << m_chunk_shift ) - 1 )
399 , m_chunk_max( ( arg_size_max + m_chunk_mask ) >> m_chunk_shift )
401 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace
402 < Kokkos::Impl::ActiveExecutionMemorySpace
403 ,
typename traits::memory_space >::verify();
407 typedef typename traits::memory_space memory_space ;
408 typedef Kokkos::Experimental::Impl::SharedAllocationRecord< memory_space , Destroy > record_type ;
411 record_type *
const record =
412 record_type::allocate( memory_space()
414 , (
sizeof(pointer_type) * ( m_chunk_max + 1 ) ) );
416 m_chunks =
reinterpret_cast<pointer_type*
>( record->data() );
418 record->m_destroy = Destroy( m_pool , m_chunks , m_chunk_max );
422 record->m_destroy.construct_shared_allocation();
424 m_track.assign_allocated_record_to_uninitialized( record );
432 namespace Experimental {
434 template<
class T ,
class ... P >
442 template<
class T ,
class ... DP ,
class ... SP >
444 void deep_copy(
const View<T,DP...> & dst
445 ,
const DynamicView<T,SP...> & src
448 typedef View<T,DP...> dst_type ;
449 typedef DynamicView<T,SP...> src_type ;
451 typedef typename ViewTraits<T,DP...>::execution_space dst_execution_space ;
452 typedef typename ViewTraits<T,SP...>::memory_space src_memory_space ;
454 enum { DstExecCanAccessSrc =
455 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace< typename dst_execution_space::memory_space , src_memory_space >::value };
457 if ( DstExecCanAccessSrc ) {
459 Kokkos::Experimental::Impl::ViewRemap< dst_type , src_type >( dst , src );
462 Kokkos::Impl::throw_runtime_exception(
"deep_copy given views that would require a temporary allocation");
466 template<
class T ,
class ... DP ,
class ... SP >
468 void deep_copy(
const DynamicView<T,DP...> & dst
469 ,
const View<T,SP...> & src
472 typedef DynamicView<T,SP...> dst_type ;
473 typedef View<T,DP...> src_type ;
475 typedef typename ViewTraits<T,DP...>::execution_space dst_execution_space ;
476 typedef typename ViewTraits<T,SP...>::memory_space src_memory_space ;
478 enum { DstExecCanAccessSrc =
479 Kokkos::Impl::VerifyExecutionCanAccessMemorySpace< typename dst_execution_space::memory_space , src_memory_space >::value };
481 if ( DstExecCanAccessSrc ) {
483 Kokkos::Experimental::Impl::ViewRemap< dst_type , src_type >( dst , src );
486 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.
KOKKOS_FUNCTION void deallocate(void *alloc_ptr, size_t alloc_size) const
Release allocated memory back to the pool.
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.
Memory space for main process and CPU execution spaces.
DynamicView HostMirror
Must be accessible everywhere.
Implementation of the ParallelFor operator that has a partial specialization for the device...
KOKKOS_FUNCTION void * allocate(size_t alloc_size) const
Allocate a chunk of memory.
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.
void resize_serial(size_t n)
Resizing in serial can grow or shrink the array size,.
Traits class for accessing attributes of a View.
DynamicView< typename traits::non_const_data_type, typename traits::device_type > non_const_type
Compatible view of non-const data type.