45 #ifndef KOKKOS_DYNAMIC_VIEW_HPP
46 #define KOKKOS_DYNAMIC_VIEW_HPP
50 #include <Kokkos_Core.hpp>
51 #include <impl/Kokkos_Error.hpp>
54 namespace Experimental {
62 template <
class MemSpace>
63 struct ChunkArraySpace {
64 using memory_space = MemSpace;
67 #ifdef KOKKOS_ENABLE_CUDA
69 struct ChunkArraySpace<Kokkos::CudaSpace> {
70 using memory_space =
typename Kokkos::CudaUVMSpace;
73 #ifdef KOKKOS_ENABLE_HIP
75 struct ChunkArraySpace<Kokkos::Experimental::HIPSpace> {
76 using memory_space =
typename Kokkos::Experimental::HIPHostPinnedSpace;
85 template <
typename DataType,
typename... P>
91 template <
class,
class...>
94 typedef Kokkos::Impl::SharedAllocationTracker track_type;
96 static_assert(traits::rank == 1 && traits::rank_dynamic == 1,
97 "DynamicView must be rank-one");
101 static_assert(std::is_same<typename traits::specialize, void>::value,
102 "DynamicView only implemented for non-specialized View type");
105 Space,
typename traits::memory_space>::accessible>
106 struct verify_space {
107 KOKKOS_FORCEINLINE_FUNCTION
static void check() {}
110 template <
class Space>
111 struct verify_space<Space, false> {
112 KOKKOS_FORCEINLINE_FUNCTION
static void check() {
114 "Kokkos::DynamicView ERROR: attempt to access inaccessible memory "
121 typename traits::value_type**
123 unsigned m_chunk_shift;
124 unsigned m_chunk_mask;
125 unsigned m_chunk_max;
127 unsigned m_chunk_size;
137 typedef DynamicView<
typename traits::const_data_type,
138 typename traits::device_type>
142 typedef DynamicView<
typename traits::non_const_data_type,
143 typename traits::device_type>
150 typedef Kokkos::Device<
typename traits::device_type::execution_space,
151 Kokkos::AnonymousSpace>
170 KOKKOS_INLINE_FUNCTION
171 size_t allocation_extent() const noexcept {
172 uintptr_t n = *
reinterpret_cast<const uintptr_t*
>(m_chunks + m_chunk_max);
173 return (n << m_chunk_shift);
176 KOKKOS_INLINE_FUNCTION
177 size_t chunk_size() const noexcept {
return m_chunk_size; }
179 KOKKOS_INLINE_FUNCTION
180 size_t size() const noexcept {
182 *
reinterpret_cast<const size_t*
>(m_chunks + m_chunk_max + 1);
186 template <
typename iType>
187 KOKKOS_INLINE_FUNCTION
size_t extent(
const iType& r)
const {
188 return r == 0 ? size() : 1;
191 template <
typename iType>
192 KOKKOS_INLINE_FUNCTION
size_t extent_int(
const iType& r)
const {
193 return r == 0 ? size() : 1;
196 #ifdef KOKKOS_ENABLE_DEPRECATED_CODE
197 KOKKOS_INLINE_FUNCTION
size_t dimension_0()
const {
return size(); }
198 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_1()
const {
return 1; }
199 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_2()
const {
return 1; }
200 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_3()
const {
return 1; }
201 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_4()
const {
return 1; }
202 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_5()
const {
return 1; }
203 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_6()
const {
return 1; }
204 KOKKOS_INLINE_FUNCTION constexpr
size_t dimension_7()
const {
return 1; }
207 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_0()
const {
return 0; }
208 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_1()
const {
return 0; }
209 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_2()
const {
return 0; }
210 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_3()
const {
return 0; }
211 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_4()
const {
return 0; }
212 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_5()
const {
return 0; }
213 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_6()
const {
return 0; }
214 KOKKOS_INLINE_FUNCTION constexpr
size_t stride_7()
const {
return 0; }
216 template <
typename iType>
217 KOKKOS_INLINE_FUNCTION
void stride(iType*
const s)
const {
224 KOKKOS_INLINE_FUNCTION
225 int use_count()
const {
return m_track.use_count(); }
227 inline const std::string label()
const {
228 return m_track.template get_label<typename traits::memory_space>();
234 typedef typename traits::value_type& reference_type;
235 typedef typename traits::value_type* pointer_type;
238 reference_type_is_lvalue_reference =
239 std::is_lvalue_reference<reference_type>::value
242 KOKKOS_INLINE_FUNCTION constexpr
bool span_is_contiguous()
const {
245 KOKKOS_INLINE_FUNCTION constexpr
size_t span()
const {
return 0; }
246 KOKKOS_INLINE_FUNCTION constexpr pointer_type data()
const {
return 0; }
250 template <
typename I0,
class... Args>
251 KOKKOS_INLINE_FUNCTION reference_type
252 operator()(
const I0& i0,
const Args&... )
const {
253 static_assert(Kokkos::Impl::are_integral<I0, Args...>::value,
254 "Indices must be integral type");
256 DynamicView::template verify_space<
257 Kokkos::Impl::ActiveExecutionMemorySpace>::check();
260 const uintptr_t ic = uintptr_t(i0 >> m_chunk_shift);
262 typename traits::value_type*
volatile*
const ch = m_chunks + ic;
267 #if !defined(KOKKOS_ENABLE_DEBUG_BOUNDS_CHECK)
275 *
reinterpret_cast<uintptr_t volatile*
>(m_chunks + m_chunk_max);
278 Kokkos::abort(
"Kokkos::DynamicView array bounds error");
283 while (
nullptr == *ch)
287 return (*ch)[i0 & m_chunk_mask];
294 template <
typename IntType>
295 inline typename std::enable_if<
296 std::is_integral<IntType>::value &&
299 typename Impl::ChunkArraySpace<
300 typename traits::memory_space>::memory_space>::accessible>::type
302 typedef typename traits::value_type local_value_type;
303 typedef local_value_type* value_pointer_type;
306 (n + m_chunk_mask) >>
309 if (m_chunk_max < NC) {
310 Kokkos::abort(
"DynamicView::resize_serial exceeded maximum size");
314 uintptr_t*
const pc =
reinterpret_cast<uintptr_t*
>(m_chunks + m_chunk_max);
318 m_chunks[*pc] =
reinterpret_cast<value_pointer_type
>(
319 typename traits::memory_space().allocate(
sizeof(local_value_type)
324 while (NC + 1 <= *pc) {
326 typename traits::memory_space().deallocate(
327 m_chunks[*pc],
sizeof(local_value_type) << m_chunk_shift);
328 m_chunks[*pc] =
nullptr;
344 template <
class RT,
class... RP>
346 : m_track(rhs.m_track),
347 m_chunks((typename traits::value_type**)rhs.m_chunks),
348 m_chunk_shift(rhs.m_chunk_shift),
349 m_chunk_mask(rhs.m_chunk_mask),
350 m_chunk_max(rhs.m_chunk_max),
351 m_chunk_size(rhs.m_chunk_size) {
352 typedef typename DynamicView<RT, RP...>::traits SrcTraits;
353 typedef Kokkos::Impl::ViewMapping<traits, SrcTraits, void> Mapping;
354 static_assert(Mapping::is_assignable,
355 "Incompatible DynamicView copy construction");
361 typename traits::value_type** m_chunks;
362 unsigned m_chunk_max;
364 unsigned m_chunk_size;
368 inline void operator()(
unsigned i)
const {
369 if (m_destroy && i < m_chunk_max &&
nullptr != m_chunks[i]) {
370 typename traits::memory_space().deallocate(m_chunks[i], m_chunk_size);
372 m_chunks[i] =
nullptr;
375 void execute(
bool arg_destroy) {
380 m_destroy = arg_destroy;
384 Range(0, m_chunk_max + 2));
389 typename traits::execution_space().fence();
394 void construct_shared_allocation() { execute(
false); }
396 void destroy_shared_allocation() { execute(
true); }
399 Destroy(Destroy&&) =
default;
400 Destroy(
const Destroy&) =
default;
401 Destroy& operator=(Destroy&&) =
default;
402 Destroy& operator=(
const Destroy&) =
default;
404 Destroy(
typename traits::value_type** arg_chunk,
405 const unsigned arg_chunk_max,
const unsigned arg_chunk_size)
406 : m_chunks(arg_chunk),
407 m_chunk_max(arg_chunk_max),
409 m_chunk_size(arg_chunk_size) {}
419 const unsigned min_chunk_size,
420 const unsigned max_extent)
425 m_chunk_shift(Kokkos::Impl::integral_power_of_two_that_contains(
428 m_chunk_mask((1 << m_chunk_shift) - 1)
430 m_chunk_max((max_extent + m_chunk_mask) >>
433 m_chunk_size(2 << (m_chunk_shift - 1)) {
434 typedef typename Impl::ChunkArraySpace<
435 typename traits::memory_space>::memory_space chunk_array_memory_space;
437 typedef Kokkos::Impl::SharedAllocationRecord<chunk_array_memory_space,
442 record_type*
const record =
443 record_type::allocate(chunk_array_memory_space(), arg_label,
444 (
sizeof(pointer_type) * (m_chunk_max + 2)));
449 m_chunks =
reinterpret_cast<pointer_type*
>(record->data());
451 record->m_destroy = Destroy(m_chunks, m_chunk_max, m_chunk_size);
454 record->m_destroy.construct_shared_allocation();
456 m_track.assign_allocated_record_to_uninitialized(record);
465 template <
class T,
class... P>
471 template <
class T,
class... DP,
class... SP>
472 inline void deep_copy(
const View<T, DP...>& dst,
474 typedef View<T, DP...> dst_type;
477 typedef typename ViewTraits<T, DP...>::execution_space dst_execution_space;
478 typedef typename ViewTraits<T, SP...>::memory_space src_memory_space;
481 DstExecCanAccessSrc =
483 src_memory_space>::accessible
486 if (DstExecCanAccessSrc) {
489 Kokkos::Impl::ViewRemap<dst_type, src_type>(dst, src);
491 Kokkos::Impl::throw_runtime_exception(
492 "deep_copy given views that would require a temporary allocation");
496 template <
class T,
class... DP,
class... SP>
498 const View<T, SP...>& src) {
500 typedef View<T, DP...> src_type;
502 typedef typename ViewTraits<T, DP...>::execution_space dst_execution_space;
503 typedef typename ViewTraits<T, SP...>::memory_space src_memory_space;
506 DstExecCanAccessSrc =
508 src_memory_space>::accessible
511 if (DstExecCanAccessSrc) {
514 Kokkos::Impl::ViewRemap<dst_type, src_type>(dst, src);
516 Kokkos::Impl::throw_runtime_exception(
517 "deep_copy given views that would require a temporary allocation");
522 template <
class Arg0,
class... DP,
class... SP>
523 struct CommonSubview<Kokkos::Experimental::DynamicView<DP...>,
527 typedef DstType dst_subview_type;
528 typedef SrcType src_subview_type;
529 dst_subview_type dst_sub;
530 src_subview_type src_sub;
531 CommonSubview(
const DstType& dst,
const SrcType& src,
const Arg0& )
532 : dst_sub(dst), src_sub(src) {}
535 template <
class... DP,
class SrcType,
class Arg0>
536 struct CommonSubview<Kokkos::Experimental::DynamicView<DP...>, SrcType, 1,
539 typedef DstType dst_subview_type;
540 typedef typename Kokkos::Subview<SrcType, Arg0> src_subview_type;
541 dst_subview_type dst_sub;
542 src_subview_type src_sub;
543 CommonSubview(
const DstType& dst,
const SrcType& src,
const Arg0& arg0)
544 : dst_sub(dst), src_sub(src, arg0) {}
547 template <
class DstType,
class... SP,
class Arg0>
548 struct CommonSubview<DstType, Kokkos::Experimental::DynamicView<SP...>, 1,
551 typedef typename Kokkos::Subview<DstType, Arg0> dst_subview_type;
552 typedef SrcType src_subview_type;
553 dst_subview_type dst_sub;
554 src_subview_type src_sub;
555 CommonSubview(
const DstType& dst,
const SrcType& src,
const Arg0& arg0)
556 : dst_sub(dst, arg0), src_sub(src) {}
559 template <
class... DP,
class ViewTypeB,
class Layout,
class ExecSpace,
561 struct ViewCopy<Kokkos::Experimental::DynamicView<DP...>, ViewTypeB, Layout,
562 ExecSpace, 1, iType, false> {
575 KOKKOS_INLINE_FUNCTION
576 void operator()(
const iType& i0)
const { a(i0) = b(i0); };
579 template <
class... DP,
class... SP,
class Layout,
class ExecSpace,
581 struct ViewCopy<Kokkos::Experimental::DynamicView<DP...>,
592 const iType n = std::min(a.extent(0), b.extent(0));
596 KOKKOS_INLINE_FUNCTION
597 void operator()(
const iType& i0)
const { a(i0) = b(i0); };
DynamicView(const std::string &arg_label, const unsigned min_chunk_size, const unsigned max_extent)
Allocation constructor.
DynamicView< typename traits::non_const_data_type, typename traits::device_type > non_const_type
Compatible view of non-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 *=nullptr)
Deep copy a value from Host memory into a view.
Dynamic views are restricted to rank-one and no layout. Resize only occurs on host outside of paralle...
Can AccessSpace access MemorySpace ?
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 parallel_for(const ExecPolicy &policy, const FunctorType &functor, const std::string &str="", typename std::enable_if< Kokkos::Impl::is_execution_policy< ExecPolicy >::value >::type *=nullptr)
Execute functor in parallel according to the execution policy.
DynamicView< typename traits::data_type, typename traits::device_type > array_type
Compatible view of array of scalar types.
Execution policy for work over a range of an integral type.
DynamicView< typename traits::const_data_type, typename traits::device_type > const_type
Compatible view of const data type.
Traits class for accessing attributes of a View.
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.
Kokkos::Device< typename traits::device_type::execution_space, Kokkos::AnonymousSpace > uniform_device
Unified types.
Access relationship between DstMemorySpace and SrcMemorySpace.