45 #ifndef KOKKOS_HIPSPACE_HPP
46 #define KOKKOS_HIPSPACE_HPP
48 #include <Kokkos_Core_fwd.hpp>
50 #if defined(KOKKOS_ENABLE_HIP)
58 #include <Kokkos_HostSpace.hpp>
60 #include <Kokkos_ScratchSpace.hpp>
62 #include <impl/Kokkos_Profiling_Interface.hpp>
64 #include <hip/hip_runtime_api.h>
68 namespace Experimental {
74 using memory_space = HIPSpace;
75 using execution_space = Kokkos::Experimental::HIP;
76 using device_type = Kokkos::Device<execution_space, memory_space>;
78 using size_type =
unsigned int;
83 HIPSpace(HIPSpace&& rhs) =
default;
84 HIPSpace(
const HIPSpace& rhs) =
default;
85 HIPSpace& operator=(HIPSpace&& rhs) =
default;
86 HIPSpace& operator=(
const HIPSpace& rhs) =
default;
87 ~HIPSpace() =
default;
90 void* allocate(
const size_t arg_alloc_size)
const;
93 void deallocate(
void*
const arg_alloc_ptr,
const size_t arg_alloc_size)
const;
96 static constexpr
const char* name() {
return "HIP"; }
100 static void access_error();
101 static void access_error(
const void*
const);
106 friend class Kokkos::Impl::SharedAllocationRecord<
107 Kokkos::Experimental::HIPSpace, void>;
120 void init_lock_arrays_hip_space();
129 int* atomic_lock_array_hip_space_ptr(
bool deallocate =
false);
138 int* scratch_lock_array_hip_space_ptr(
bool deallocate =
false);
146 int* threadid_lock_array_hip_space_ptr(
bool deallocate =
false);
154 namespace Experimental {
158 class HIPHostPinnedSpace {
162 using execution_space = HostSpace::execution_space;
163 using memory_space = HIPHostPinnedSpace;
164 using device_type = Kokkos::Device<execution_space, memory_space>;
165 using size_type =
unsigned int;
169 HIPHostPinnedSpace();
170 HIPHostPinnedSpace(HIPHostPinnedSpace&& rhs) =
default;
171 HIPHostPinnedSpace(
const HIPHostPinnedSpace& rhs) =
default;
172 HIPHostPinnedSpace& operator=(HIPHostPinnedSpace&& rhs) =
default;
173 HIPHostPinnedSpace& operator=(
const HIPHostPinnedSpace& rhs) =
default;
174 ~HIPHostPinnedSpace() =
default;
177 void* allocate(
const size_t arg_alloc_size)
const;
180 void deallocate(
void*
const arg_alloc_ptr,
const size_t arg_alloc_size)
const;
183 static constexpr
const char* name() {
return "HIPHostPinned"; }
198 Kokkos::Experimental::HIPSpace>::assignable,
204 struct MemorySpaceAccess<Kokkos::HostSpace, Kokkos::Experimental::HIPSpace> {
205 enum { assignable =
false };
206 enum { accessible =
false };
207 enum { deepcopy =
true };
211 struct MemorySpaceAccess<Kokkos::HostSpace,
212 Kokkos::Experimental::HIPHostPinnedSpace> {
214 enum { assignable =
true };
215 enum { accessible =
true };
216 enum { deepcopy =
true };
223 enum { assignable =
false };
224 enum { accessible =
false };
225 enum { deepcopy =
true };
229 struct MemorySpaceAccess<Kokkos::Experimental::HIPSpace,
230 Kokkos::Experimental::HIPHostPinnedSpace> {
232 enum { assignable =
false };
233 enum { accessible =
true };
234 enum { deepcopy =
true };
242 struct MemorySpaceAccess<Kokkos::Experimental::HIPHostPinnedSpace,
244 enum { assignable =
false };
245 enum { accessible =
true };
246 enum { deepcopy =
true };
250 struct MemorySpaceAccess<Kokkos::Experimental::HIPHostPinnedSpace,
251 Kokkos::Experimental::HIPSpace> {
252 enum { assignable =
false };
253 enum { accessible =
false };
254 enum { deepcopy =
true };
268 void DeepCopyAsyncHIP(
void* dst,
const void* src,
size_t n);
271 struct DeepCopy<Kokkos::Experimental::HIPSpace, Kokkos::Experimental::HIPSpace,
272 Kokkos::Experimental::HIP> {
273 DeepCopy(
void* dst,
const void* src,
size_t);
274 DeepCopy(
const Kokkos::Experimental::HIP&,
void* dst,
const void* src,
279 struct DeepCopy<Kokkos::Experimental::HIPSpace, HostSpace,
280 Kokkos::Experimental::HIP> {
281 DeepCopy(
void* dst,
const void* src,
size_t);
282 DeepCopy(
const Kokkos::Experimental::HIP&,
void* dst,
const void* src,
287 struct DeepCopy<HostSpace, Kokkos::Experimental::HIPSpace,
288 Kokkos::Experimental::HIP> {
289 DeepCopy(
void* dst,
const void* src,
size_t);
290 DeepCopy(
const Kokkos::Experimental::HIP&,
void* dst,
const void* src,
294 template <
class ExecutionSpace>
295 struct DeepCopy<Kokkos::Experimental::HIPSpace, Kokkos::Experimental::HIPSpace,
297 inline DeepCopy(
void* dst,
const void* src,
size_t n) {
298 (void)DeepCopy<Kokkos::Experimental::HIPSpace,
299 Kokkos::Experimental::HIPSpace, Kokkos::Experimental::HIP>(
303 inline DeepCopy(
const ExecutionSpace& exec,
void* dst,
const void* src,
306 DeepCopyAsyncHIP(dst, src, n);
310 template <
class ExecutionSpace>
311 struct DeepCopy<Kokkos::Experimental::HIPSpace, HostSpace, ExecutionSpace> {
312 inline DeepCopy(
void* dst,
const void* src,
size_t n) {
313 (void)DeepCopy<Kokkos::Experimental::HIPSpace, HostSpace,
314 Kokkos::Experimental::HIP>(dst, src, n);
317 inline DeepCopy(
const ExecutionSpace& exec,
void* dst,
const void* src,
320 DeepCopyAsyncHIP(dst, src, n);
324 template <
class ExecutionSpace>
325 struct DeepCopy<HostSpace, Kokkos::Experimental::HIPSpace, ExecutionSpace> {
326 inline DeepCopy(
void* dst,
const void* src,
size_t n) {
327 (void)DeepCopy<HostSpace, Kokkos::Experimental::HIPSpace,
328 Kokkos::Experimental::HIP>(dst, src, n);
331 inline DeepCopy(
const ExecutionSpace& exec,
void* dst,
const void* src,
334 DeepCopyAsyncHIP(dst, src, n);
339 struct DeepCopy<Kokkos::Experimental::HIPHostPinnedSpace,
340 Kokkos::Experimental::HIPHostPinnedSpace,
341 Kokkos::Experimental::HIP> {
342 DeepCopy(
void* dst,
const void* src,
size_t);
343 DeepCopy(
const Kokkos::Experimental::HIP&,
void* dst,
const void* src,
348 struct DeepCopy<Kokkos::Experimental::HIPHostPinnedSpace, HostSpace,
349 Kokkos::Experimental::HIP> {
350 DeepCopy(
void* dst,
const void* src,
size_t);
351 DeepCopy(
const Kokkos::Experimental::HIP&,
void* dst,
const void* src,
356 struct DeepCopy<HostSpace, Kokkos::Experimental::HIPHostPinnedSpace,
357 Kokkos::Experimental::HIP> {
358 DeepCopy(
void* dst,
const void* src,
size_t);
359 DeepCopy(
const Kokkos::Experimental::HIP&,
void* dst,
const void* src,
363 template <
class ExecutionSpace>
364 struct DeepCopy<Kokkos::Experimental::HIPSpace,
365 Kokkos::Experimental::HIPHostPinnedSpace, ExecutionSpace> {
366 inline DeepCopy(
void* dst,
const void* src,
size_t n) {
367 (void)DeepCopy<Kokkos::Experimental::HIPSpace, HostSpace,
368 Kokkos::Experimental::HIP>(dst, src, n);
371 inline DeepCopy(
const ExecutionSpace& exec,
void* dst,
const void* src,
374 DeepCopyAsyncHIP(dst, src, n);
378 template <
class ExecutionSpace>
379 struct DeepCopy<Kokkos::Experimental::HIPHostPinnedSpace,
380 Kokkos::Experimental::HIPSpace, ExecutionSpace> {
381 inline DeepCopy(
void* dst,
const void* src,
size_t n) {
382 (void)DeepCopy<HostSpace, Kokkos::Experimental::HIPSpace,
383 Kokkos::Experimental::HIP>(dst, src, n);
386 inline DeepCopy(
const ExecutionSpace& exec,
void* dst,
const void* src,
389 DeepCopyAsyncHIP(dst, src, n);
393 template <
class ExecutionSpace>
394 struct DeepCopy<Kokkos::Experimental::HIPHostPinnedSpace,
395 Kokkos::Experimental::HIPHostPinnedSpace, ExecutionSpace> {
396 inline DeepCopy(
void* dst,
const void* src,
size_t n) {
397 (void)DeepCopy<Kokkos::Experimental::HIPHostPinnedSpace,
398 Kokkos::Experimental::HIPHostPinnedSpace,
399 Kokkos::Experimental::HIP>(dst, src, n);
402 inline DeepCopy(
const ExecutionSpace& exec,
void* dst,
const void* src,
405 DeepCopyAsyncHIP(dst, src, n);
409 template <
class ExecutionSpace>
410 struct DeepCopy<Kokkos::Experimental::HIPHostPinnedSpace, HostSpace,
412 inline DeepCopy(
void* dst,
const void* src,
size_t n) {
413 (void)DeepCopy<Kokkos::Experimental::HIPHostPinnedSpace, HostSpace,
414 Kokkos::Experimental::HIP>(dst, src, n);
417 inline DeepCopy(
const ExecutionSpace& exec,
void* dst,
const void* src,
420 DeepCopyAsyncHIP(dst, src, n);
424 template <
class ExecutionSpace>
425 struct DeepCopy<HostSpace, Kokkos::Experimental::HIPHostPinnedSpace,
427 inline DeepCopy(
void* dst,
const void* src,
size_t n) {
428 (void)DeepCopy<HostSpace, Kokkos::Experimental::HIPHostPinnedSpace,
429 Kokkos::Experimental::HIP>(dst, src, n);
432 inline DeepCopy(
const ExecutionSpace& exec,
void* dst,
const void* src,
435 DeepCopyAsyncHIP(dst, src, n);
449 struct VerifyExecutionCanAccessMemorySpace<Kokkos::Experimental::HIPSpace,
451 enum { value =
false };
452 KOKKOS_INLINE_FUNCTION
static void verify(
void) {
453 Kokkos::abort(
"HIP code attempted to access HostSpace memory");
456 KOKKOS_INLINE_FUNCTION
static void verify(
const void*) {
457 Kokkos::abort(
"HIP code attempted to access HostSpace memory");
463 struct VerifyExecutionCanAccessMemorySpace<
464 Kokkos::Experimental::HIPSpace, Kokkos::Experimental::HIPHostPinnedSpace> {
465 enum { value =
true };
466 KOKKOS_INLINE_FUNCTION
static void verify(
void) {}
467 KOKKOS_INLINE_FUNCTION
static void verify(
const void*) {}
471 template <
class OtherSpace>
472 struct VerifyExecutionCanAccessMemorySpace<
473 typename std::enable_if<
474 !std::is_same<Kokkos::Experimental::HIPSpace, OtherSpace>::value,
475 Kokkos::Experimental::HIPSpace>::type,
477 enum { value =
false };
478 KOKKOS_INLINE_FUNCTION
static void verify(
void) {
479 Kokkos::abort(
"HIP code attempted to access unknown Space memory");
482 KOKKOS_INLINE_FUNCTION
static void verify(
const void*) {
483 Kokkos::abort(
"HIP code attempted to access unknown Space memory");
490 struct VerifyExecutionCanAccessMemorySpace<Kokkos::HostSpace,
491 Kokkos::Experimental::HIPSpace> {
492 enum { value =
false };
493 inline static void verify(
void) {
494 Kokkos::Experimental::HIPSpace::access_error();
496 inline static void verify(
const void* p) {
497 Kokkos::Experimental::HIPSpace::access_error(p);
503 struct VerifyExecutionCanAccessMemorySpace<
504 Kokkos::HostSpace, Kokkos::Experimental::HIPHostPinnedSpace> {
505 enum { value =
true };
506 KOKKOS_INLINE_FUNCTION
static void verify(
void) {}
507 KOKKOS_INLINE_FUNCTION
static void verify(
const void*) {}
519 class SharedAllocationRecord<Kokkos::Experimental::HIPSpace, void>
520 :
public SharedAllocationRecord<void, void> {
522 typedef SharedAllocationRecord<void, void> RecordBase;
524 SharedAllocationRecord(
const SharedAllocationRecord&) =
delete;
525 SharedAllocationRecord& operator=(
const SharedAllocationRecord&) =
delete;
527 static void deallocate(RecordBase*);
530 static RecordBase s_root_record;
533 const Kokkos::Experimental::HIPSpace m_space;
536 ~SharedAllocationRecord();
538 SharedAllocationRecord(
539 const Kokkos::Experimental::HIPSpace& arg_space,
540 const std::string& arg_label,
const size_t arg_alloc_size,
541 const RecordBase::function_type arg_dealloc = &deallocate);
544 std::string get_label()
const;
546 static SharedAllocationRecord* allocate(
547 const Kokkos::Experimental::HIPSpace& arg_space,
548 const std::string& arg_label,
const size_t arg_alloc_size);
551 static void* allocate_tracked(
const Kokkos::Experimental::HIPSpace& arg_space,
552 const std::string& arg_label,
553 const size_t arg_alloc_size);
556 static void* reallocate_tracked(
void*
const arg_alloc_ptr,
557 const size_t arg_alloc_size);
560 static void deallocate_tracked(
void*
const arg_alloc_ptr);
562 static SharedAllocationRecord* get_record(
void* arg_alloc_ptr);
564 static void print_records(std::ostream&,
565 const Kokkos::Experimental::HIPSpace&,
566 bool detail =
false);
570 class SharedAllocationRecord<Kokkos::Experimental::HIPHostPinnedSpace, void>
571 :
public SharedAllocationRecord<void, void> {
573 typedef SharedAllocationRecord<void, void> RecordBase;
575 SharedAllocationRecord(
const SharedAllocationRecord&) =
delete;
576 SharedAllocationRecord& operator=(
const SharedAllocationRecord&) =
delete;
578 static void deallocate(RecordBase*);
581 static RecordBase s_root_record;
584 const Kokkos::Experimental::HIPHostPinnedSpace m_space;
587 ~SharedAllocationRecord();
588 SharedAllocationRecord() : RecordBase(), m_space() {}
590 SharedAllocationRecord(
591 const Kokkos::Experimental::HIPHostPinnedSpace& arg_space,
592 const std::string& arg_label,
const size_t arg_alloc_size,
593 const RecordBase::function_type arg_dealloc = &deallocate);
596 std::string get_label()
const;
598 static SharedAllocationRecord* allocate(
599 const Kokkos::Experimental::HIPHostPinnedSpace& arg_space,
600 const std::string& arg_label,
const size_t arg_alloc_size);
602 static void* allocate_tracked(
603 const Kokkos::Experimental::HIPHostPinnedSpace& arg_space,
604 const std::string& arg_label,
const size_t arg_alloc_size);
607 static void* reallocate_tracked(
void*
const arg_alloc_ptr,
608 const size_t arg_alloc_size);
611 static void deallocate_tracked(
void*
const arg_alloc_ptr);
613 static SharedAllocationRecord* get_record(
void* arg_alloc_ptr);
615 static void print_records(std::ostream&,
616 const Kokkos::Experimental::HIPHostPinnedSpace&,
617 bool detail =
false);
626 namespace Experimental {
639 using execution_space = HIP;
640 using memory_space = HIPSpace;
641 using device_type = Kokkos::Device<execution_space, memory_space>;
643 using array_layout = LayoutLeft;
644 using size_type = HIPSpace::size_type;
646 using scratch_memory_space = ScratchMemorySpace<HIP>;
652 HIP(HIP&&) =
default;
653 HIP(
const HIP&) =
default;
654 HIP& operator=(HIP&&) =
default;
655 HIP& operator=(
const HIP&) =
default;
662 KOKKOS_INLINE_FUNCTION
static int in_parallel() {
663 #if defined(__HIP_ARCH__)
671 static void impl_static_fence();
678 static void impl_finalize();
683 struct SelectDevice {
685 SelectDevice() : hip_device_id(0) {}
686 explicit SelectDevice(
int id) : hip_device_id(id) {}
689 int hip_device()
const;
691 static void impl_initialize(
const SelectDevice = SelectDevice());
693 static int impl_is_initialized();
699 static int concurrency();
700 static const char* name();
702 inline Impl::HIPInternal* impl_internal_space_instance()
const {
703 return m_space_instance;
706 uint32_t impl_instance_id() const noexcept {
return 0; }
709 Impl::HIPInternal* m_space_instance;
712 namespace Profiling {
713 namespace Experimental {
715 struct DeviceTypeTraits<Kokkos::Experimental::HIP> {
716 static constexpr DeviceType
id = DeviceType::HIP;
726 struct MemorySpaceAccess<Kokkos::Experimental::HIPSpace,
727 Kokkos::Experimental::HIP::scratch_memory_space> {
728 enum { assignable =
false };
729 enum { accessible =
true };
730 enum { deepcopy =
false };
734 struct VerifyExecutionCanAccessMemorySpace<
735 Kokkos::Experimental::HIP::memory_space,
736 Kokkos::Experimental::HIP::scratch_memory_space> {
737 enum { value =
true };
738 KOKKOS_INLINE_FUNCTION
static void verify(
void) {}
739 KOKKOS_INLINE_FUNCTION
static void verify(
const void*) {}
743 struct VerifyExecutionCanAccessMemorySpace<
744 Kokkos::HostSpace, Kokkos::Experimental::HIP::scratch_memory_space> {
745 enum { value =
false };
746 inline static void verify(
void) {
747 Kokkos::Experimental::HIPSpace::access_error();
749 inline static void verify(
const void* p) {
750 Kokkos::Experimental::HIPSpace::access_error(p);
void print_configuration(std::ostream &, const bool detail=false)
Print "Bill of Materials".
Memory management for host memory.
Declaration of various MemoryLayout options.
Access relationship between DstMemorySpace and SrcMemorySpace.