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 {
 
   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 local_value_type ;
 
  292       typedef local_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(local_value_type) << m_chunk_shift )
 
  314         while ( NC + 1 <= *pc ) {
 
  316           typename traits::memory_space().deallocate( m_chunks[*pc]
 
  317                                          , 
sizeof(local_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         typename 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 >
 
  464 void deep_copy( 
const View<T,DP...> & dst
 
  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 >
 
  489               , 
const View<T,SP...> & src
 
  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>
 
  524 struct CommonSubview<Kokkos::Experimental::DynamicView<DP...>,SrcType,1,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>
 
  535 struct CommonSubview<DstType,Kokkos::Experimental::DynamicView<SP...>,1,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>
 
  546 struct ViewCopy<Kokkos::Experimental::DynamicView<DP...>,ViewTypeB,Layout,ExecSpace,1,iType,false> {
 
  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>
 
  564 struct ViewCopy<Kokkos::Experimental::DynamicView<DP...>,
 
  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. 
 
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.