diff --git a/projects/clr/rocclr/device/device.cpp b/projects/clr/rocclr/device/device.cpp
index a25622ac18..3e8a284dec 100644
--- a/projects/clr/rocclr/device/device.cpp
+++ b/projects/clr/rocclr/device/device.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008 - 2022 Advanced Micro Devices, Inc.
+/* Copyright (c) 2008 - 2023 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -817,6 +817,116 @@ char* Device::getExtensionString() {
return result;
}
+// ================================================================================================
+bool Device::IpcCreate(void* dev_ptr, size_t* mem_size, void* handle, size_t* mem_offset) const {
+ amd::Memory* amd_mem_obj = amd::MemObjMap::FindMemObj(dev_ptr);
+ if (amd_mem_obj == nullptr) {
+ DevLogPrintfError("Cannot retrieve amd_mem_obj for dev_ptr: 0x%x", dev_ptr);
+ return false;
+ }
+
+ // Get the original pointer from the amd::Memory object
+ void* orig_dev_ptr = nullptr;
+ if (amd_mem_obj->getSvmPtr() != nullptr) {
+ orig_dev_ptr = amd_mem_obj->getSvmPtr();
+ } else if (amd_mem_obj->getHostMem() != nullptr) {
+ orig_dev_ptr = amd_mem_obj->getHostMem();
+ } else {
+ ShouldNotReachHere();
+ }
+
+ // Check if the dev_ptr is lesser than original dev_ptr
+ if (orig_dev_ptr > dev_ptr) {
+ // If this happens, then revisit FindMemObj logic
+ DevLogPrintfError("Original dev_ptr: 0x%x cannot be greater than dev_ptr: 0x%x", orig_dev_ptr,
+ dev_ptr);
+ return false;
+ }
+
+ // Calculate the memory offset from the original base ptr
+ *mem_offset = reinterpret_cast
(dev_ptr) - reinterpret_cast(orig_dev_ptr);
+ *mem_size = amd_mem_obj->getSize();
+
+ // Check if the dev_ptr is greater than memory allocated
+ if (*mem_offset > *mem_size) {
+ DevLogPrintfError(
+ "Memory offset: %u cannot be greater than size of original memory allocated: %u", *mem_size,
+ *mem_offset);
+ return false;
+ }
+ auto dev_mem = static_cast(amd_mem_obj->getDeviceMemory(*this));
+ auto result = dev_mem->ExportHandle(handle);
+
+ return true;
+}
+
+// ================================================================================================
+bool Device::IpcAttach(const void* handle, size_t mem_size, size_t mem_offset, unsigned int flags,
+ void** dev_ptr) const {
+ amd::Memory* amd_mem_obj = nullptr;
+
+ // Create an amd Memory object for the handle
+ amd_mem_obj = new (context()) amd::IpcBuffer(context(), flags, mem_offset, mem_size, handle);
+ if (amd_mem_obj == nullptr) {
+ LogError("failed to create a mem object!");
+ return false;
+ }
+
+ if (!amd_mem_obj->create(nullptr)) {
+ LogError("failed to create a svm hidden buffer!");
+ amd_mem_obj->release();
+ return false;
+ }
+
+ auto mem_obj_exist = amd::MemObjMap::FindMemObj(amd_mem_obj->getSvmPtr());
+ if (mem_obj_exist == nullptr) {
+ // Add the original mem_ptr to the MemObjMap with newly created amd_mem_obj
+ amd::MemObjMap::AddMemObj(amd_mem_obj->getSvmPtr(), amd_mem_obj);
+
+ // Make sure the mem_offset doesnt overflow the allocated memory
+ guarantee((mem_offset < mem_size), "IPC mem offset greater than allocated size");
+ } else {
+ amd_mem_obj->release();
+ amd_mem_obj = mem_obj_exist;
+ // Memory already exists, just retain the old one.
+ amd_mem_obj->retain();
+ }
+
+ *dev_ptr = amd_mem_obj->getSvmPtr();
+
+ return true;
+}
+
+// ================================================================================================
+bool Device::IpcDetach(void* dev_ptr) const {
+ amd::Memory* amd_mem_obj = amd::MemObjMap::FindMemObj(dev_ptr);
+ if (amd_mem_obj == nullptr) {
+ DevLogPrintfError("Memory object for the ptr: 0x%x cannot be null \n", dev_ptr);
+ return false;
+ }
+
+ if (!amd_mem_obj->ipcShared()) {
+ DevLogPrintfError("Memory object for the ptr: 0x%x is not ipcShared \n", dev_ptr);
+ return false;
+ }
+
+ // Get the original pointer from the amd::Memory object
+ void* orig_dev_ptr = nullptr;
+ if (amd_mem_obj->getSvmPtr() != nullptr) {
+ orig_dev_ptr = amd_mem_obj->getSvmPtr();
+ } else if (amd_mem_obj->getHostMem() != nullptr) {
+ orig_dev_ptr = amd_mem_obj->getHostMem();
+ } else {
+ ShouldNotReachHere();
+ }
+
+ if (amd_mem_obj->release() == 0) {
+ amd::MemObjMap::RemoveMemObj(orig_dev_ptr);
+ }
+
+ return true;
+}
+
} // namespace amd
namespace device {
diff --git a/projects/clr/rocclr/device/device.hpp b/projects/clr/rocclr/device/device.hpp
index 1a37677864..5074c6fb72 100644
--- a/projects/clr/rocclr/device/device.hpp
+++ b/projects/clr/rocclr/device/device.hpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008 - 2022 Advanced Micro Devices, Inc.
+/* Copyright (c) 2008 - 2023 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -884,6 +884,9 @@ class Memory : public amd::HeapObject {
//! Returns CPU pointer to HW state
virtual const address cpuSrd() const { return nullptr; }
+ //! Returns an export handle for the interprocess communication
+ virtual bool ExportHandle(void* handle) const { return false; }
+
bool getAllowedPeerAccess() const { return (flags_ & AllowedPeerAccess) ? true : false; }
void setAllowedPeerAccess(bool flag) {
if (flag == true) {
@@ -1894,21 +1897,12 @@ class Device : public RuntimeObject {
//! Checks if OCL runtime can use hsail for compilation
bool ValidateHsail();
- virtual bool IpcCreate(void* dev_ptr, size_t* mem_size, void* handle, size_t* mem_offset) const {
- ShouldNotReachHere();
- return false;
- }
+ bool IpcCreate(void* dev_ptr, size_t* mem_size, void* handle, size_t* mem_offset) const;
- virtual bool IpcAttach(const void* handle, size_t mem_size, size_t mem_offset,
- unsigned int flags, void** dev_ptr) const {
- ShouldNotReachHere();
- return false;
- }
+ bool IpcAttach(const void* handle, size_t mem_size, size_t mem_offset, unsigned int flags,
+ void** dev_ptr) const;
- virtual bool IpcDetach(void* dev_ptr) const {
- ShouldNotReachHere();
- return false;
- }
+ bool IpcDetach(void* dev_ptr) const;
//! Return context
amd::Context& context() const { return *context_; }
diff --git a/projects/clr/rocclr/device/pal/paldevice.cpp b/projects/clr/rocclr/device/pal/paldevice.cpp
index 3bfaf31844..9b951eb258 100644
--- a/projects/clr/rocclr/device/pal/paldevice.cpp
+++ b/projects/clr/rocclr/device/pal/paldevice.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008 - 2021 Advanced Micro Devices, Inc.
+/* Copyright (c) 2008 - 2023 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -2345,116 +2345,6 @@ void Device::virtualFree(void* addr) {
}
}
-// ================================================================================================
-bool Device::IpcCreate(void* dev_ptr, size_t* mem_size, void* handle, size_t* mem_offset) const {
- hsa_status_t hsa_status = HSA_STATUS_SUCCESS;
-
- amd::Memory* amd_mem_obj = amd::MemObjMap::FindMemObj(dev_ptr);
- if (amd_mem_obj == nullptr) {
- DevLogPrintfError("Cannot retrieve amd_mem_obj for dev_ptr: 0x%x", dev_ptr);
- return false;
- }
-
- // Get the original pointer from the amd::Memory object
- void* orig_dev_ptr = nullptr;
- if (amd_mem_obj->getSvmPtr() != nullptr) {
- orig_dev_ptr = amd_mem_obj->getSvmPtr();
- } else if (amd_mem_obj->getHostMem() != nullptr) {
- orig_dev_ptr = amd_mem_obj->getHostMem();
- } else {
- ShouldNotReachHere();
- }
-
- // Check if the dev_ptr is lesser than original dev_ptr
- if (orig_dev_ptr > dev_ptr) {
- // If this happens, then revisit FindMemObj logic
- DevLogPrintfError("Original dev_ptr: 0x%x cannot be greater than dev_ptr: 0x%x", orig_dev_ptr,
- dev_ptr);
- return false;
- }
-
- // Calculate the memory offset from the original base ptr
- *mem_offset = reinterpret_cast(dev_ptr) - reinterpret_cast(orig_dev_ptr);
- *mem_size = amd_mem_obj->getSize();
-
- // Check if the dev_ptr is greater than memory allocated
- if (*mem_offset > *mem_size) {
- DevLogPrintfError(
- "Memory offset: %u cannot be greater than size of original memory allocated: %u", *mem_size,
- *mem_offset);
- return false;
- }
- auto dev_mem = getGpuMemory(amd_mem_obj);
- *reinterpret_cast(handle) = dev_mem->ExportHandle();
-
- return true;
-}
-
-// ================================================================================================
-bool Device::IpcAttach(const void* handle, size_t mem_size, size_t mem_offset, unsigned int flags,
- void** dev_ptr) const {
- amd::Memory* amd_mem_obj = nullptr;
-
- // Note: ROCr path has a validation for duplicated IPC memory, but PAL currently can't
- // identify the duplicates
-
- // Create an amd Memory object for the handle
- amd_mem_obj = new (context()) amd::IpcBuffer(context(), flags, mem_offset, mem_size,
- *reinterpret_cast(const_cast(handle)));
- if (amd_mem_obj == nullptr) {
- LogError("failed to create a mem object!");
- return false;
- }
-
- if (!amd_mem_obj->create(nullptr)) {
- LogError("failed to create a svm hidden buffer!");
- amd_mem_obj->release();
- return false;
- }
-
- // Add the original mem_ptr to the MemObjMap with newly created amd_mem_obj
- amd::MemObjMap::AddMemObj(amd_mem_obj->getSvmPtr(), amd_mem_obj);
-
- // Make sure the mem_offset doesnt overflow the allocated memory
- guarantee((mem_offset < mem_size), "IPC mem offset greater than allocated size");
-
- *dev_ptr = amd_mem_obj->getSvmPtr();
-
- return true;
-}
-
-// ================================================================================================
-bool Device::IpcDetach(void* dev_ptr) const {
- hsa_status_t hsa_status = HSA_STATUS_SUCCESS;
-
- amd::Memory* amd_mem_obj = amd::MemObjMap::FindMemObj(dev_ptr);
- if (amd_mem_obj == nullptr) {
- DevLogPrintfError("Memory object for the ptr: 0x%x cannot be null \n", dev_ptr);
- return false;
- }
-
- if (!amd_mem_obj->ipcShared()) {
- DevLogPrintfError("Memory object for the ptr: 0x%x is not ipcShared \n", dev_ptr);
- return false;
- }
-
- // Get the original pointer from the amd::Memory object
- void* orig_dev_ptr = nullptr;
- if (amd_mem_obj->getSvmPtr() != nullptr) {
- orig_dev_ptr = amd_mem_obj->getSvmPtr();
- } else if (amd_mem_obj->getHostMem() != nullptr) {
- orig_dev_ptr = amd_mem_obj->getHostMem();
- } else {
- ShouldNotReachHere();
- }
-
- if (amd_mem_obj->release() == 0) {
- amd::MemObjMap::RemoveMemObj(orig_dev_ptr);
- }
-
- return true;
-}
-
// ================================================================================================
bool Device::AcquireExclusiveGpuAccess() {
// Lock the virtual GPU list
diff --git a/projects/clr/rocclr/device/pal/paldevice.hpp b/projects/clr/rocclr/device/pal/paldevice.hpp
index 3efc171729..da584569c3 100644
--- a/projects/clr/rocclr/device/pal/paldevice.hpp
+++ b/projects/clr/rocclr/device/pal/paldevice.hpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015 - 2021 Advanced Micro Devices, Inc.
+/* Copyright (c) 2015 - 2023 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -533,15 +533,6 @@ class Device : public NullDevice {
virtual void* virtualAlloc(void* addr, size_t size, size_t alignment);
virtual void virtualFree(void* addr);
- //! Creates IPC memory handle from a provided SVM pointer
- virtual bool IpcCreate(void* dev_ptr, size_t* mem_size,
- void* handle, size_t* mem_offset) const override;
- //! Attch IPC memory to the current device
- virtual bool IpcAttach(const void* handle, size_t mem_size, size_t mem_offset, unsigned int flags,
- void** dev_ptr) const override;
- //! Detach IPC memory from the current device
- virtual bool IpcDetach(void* dev_ptr) const override;
-
//! Returns SRD manger object
SrdManager& srds() const { return *srdManager_; }
diff --git a/projects/clr/rocclr/device/pal/palmemory.cpp b/projects/clr/rocclr/device/pal/palmemory.cpp
index 2799aae9b1..33f356086d 100644
--- a/projects/clr/rocclr/device/pal/palmemory.cpp
+++ b/projects/clr/rocclr/device/pal/palmemory.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015 - 2022 Advanced Micro Devices, Inc.
+/* Copyright (c) 2015 - 2023 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -989,6 +989,7 @@ void Memory::mgpuCacheWriteBack(VirtualGPU& gpu) {
}
}
+// ================================================================================================
Memory* Buffer::createBufferView(amd::Memory& subBufferOwner) const {
pal::Memory* subBuffer;
Resource::ViewParams params;
@@ -1017,6 +1018,16 @@ Memory* Buffer::createBufferView(amd::Memory& subBufferOwner) const {
return subBuffer;
}
+// ================================================================================================
+bool Buffer::ExportHandle(void* handle) const {
+ Pal::GpuMemoryExportInfo exportInfo = {};
+ // Set default flags in case they are not provided by application
+ exportInfo.accessFlags = GENERIC_READ | GENERIC_WRITE;
+ *reinterpret_cast(handle) = iMem()->ExportExternalHandle(exportInfo);
+ return true;
+}
+
+// ================================================================================================
void* Image::allocMapTarget(const amd::Coord3D& origin, const amd::Coord3D& region, uint mapFlags,
size_t* rowPitch, size_t* slicePitch) {
// Sanity checks
diff --git a/projects/clr/rocclr/device/pal/palmemory.hpp b/projects/clr/rocclr/device/pal/palmemory.hpp
index 6d8d0cd832..4a557c7ee7 100644
--- a/projects/clr/rocclr/device/pal/palmemory.hpp
+++ b/projects/clr/rocclr/device/pal/palmemory.hpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015 - 2022 Advanced Micro Devices, Inc.
+/* Copyright (c) 2015 - 2023 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -207,6 +207,9 @@ class Buffer : public pal::Memory {
amd::Memory& subBufferOwner //!< The abstraction layer subbuf owner
) const;
+ //! Returns an export handle for the interprocess communication
+ virtual bool ExportHandle(void* handle) const final;
+
private:
//! Disable copy constructor
Buffer(const Buffer&);
diff --git a/projects/clr/rocclr/device/pal/palresource.cpp b/projects/clr/rocclr/device/pal/palresource.cpp
index 2380c48e80..552c5395a5 100644
--- a/projects/clr/rocclr/device/pal/palresource.cpp
+++ b/projects/clr/rocclr/device/pal/palresource.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015 - 2021 Advanced Micro Devices, Inc.
+/* Copyright (c) 2015 - 2023 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -1032,7 +1032,8 @@ bool Resource::CreateIpc(CreateParams* params) {
Pal::ExternalGpuMemoryOpenInfo gpuMemOpenInfo = {};
Pal::ExternalResourceOpenInfo& openInfo = gpuMemOpenInfo.resourceInfo;
- openInfo.hExternalResource = reinterpret_cast(params->owner_)->Handle();
+ openInfo.hExternalResource = *reinterpret_cast(
+ reinterpret_cast(params->owner_)->Handle());
openInfo.flags.ntHandle = false;
memRef_ = GpuMemoryReference::Create(dev(), gpuMemOpenInfo);
@@ -1336,14 +1337,6 @@ bool Resource::create(MemoryType memType, CreateParams* params, bool forceLinear
return true;
}
-// ================================================================================================
-void* Resource::ExportHandle() const {
- Pal::GpuMemoryExportInfo exportInfo = {};
- // Set default flags in case they are not provided by application
- exportInfo.accessFlags = GENERIC_READ | GENERIC_WRITE;
- Pal::OsExternalHandle handle = iMem()->ExportExternalHandle(exportInfo);
- return reinterpret_cast(handle);
-}
// ================================================================================================
void Resource::free() {
if (memRef_ == nullptr) {
diff --git a/projects/clr/rocclr/device/pal/palresource.hpp b/projects/clr/rocclr/device/pal/palresource.hpp
index 5350442671..e868c75077 100644
--- a/projects/clr/rocclr/device/pal/palresource.hpp
+++ b/projects/clr/rocclr/device/pal/palresource.hpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2015 - 2021 Advanced Micro Devices, Inc.
+/* Copyright (c) 2015 - 2023 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -433,8 +433,6 @@ class Resource : public amd::HeapObject {
*/
bool CreateP2PAccess(CreateParams* params //!< special parameters for resource allocation
);
- //! Returns an export handle for the interprocess communication
- void* ExportHandle() const;
protected:
/*! \brief Creates a PAL memory object, from IPC handle
diff --git a/projects/clr/rocclr/device/rocm/rocdevice.cpp b/projects/clr/rocclr/device/rocm/rocdevice.cpp
index e05ccf4898..22018bd945 100644
--- a/projects/clr/rocclr/device/rocm/rocdevice.cpp
+++ b/projects/clr/rocclr/device/rocm/rocdevice.cpp
@@ -2220,142 +2220,6 @@ void Device::updateFreeMemory(size_t size, bool free) {
ClPrint(amd::LOG_INFO, amd::LOG_MEM, "device=0x%lx, freeMem_ = 0x%zx", this, freeMem_.load());
}
-bool Device::IpcCreate(void* dev_ptr, size_t* mem_size, void* handle, size_t* mem_offset) const {
- hsa_status_t hsa_status = HSA_STATUS_SUCCESS;
-
- amd::Memory* amd_mem_obj = amd::MemObjMap::FindMemObj(dev_ptr);
- if (amd_mem_obj == nullptr) {
- DevLogPrintfError("Cannot retrieve amd_mem_obj for dev_ptr: 0x%x", dev_ptr);
- return false;
- }
-
- // Get the original pointer from the amd::Memory object
- void* orig_dev_ptr = nullptr;
- if (amd_mem_obj->getSvmPtr() != nullptr) {
- orig_dev_ptr = amd_mem_obj->getSvmPtr();
- } else if (amd_mem_obj->getHostMem() != nullptr) {
- orig_dev_ptr = amd_mem_obj->getHostMem();
- } else {
- ShouldNotReachHere();
- }
-
- // Check if the dev_ptr is lesser than original dev_ptr
- if (orig_dev_ptr > dev_ptr) {
- //If this happens, then revisit FindMemObj logic
- DevLogPrintfError("Original dev_ptr: 0x%x cannot be greater than dev_ptr: 0x%x",
- orig_dev_ptr, dev_ptr);
- return false;
- }
-
- //Calculate the memory offset from the original base ptr
- *mem_offset = reinterpret_cast(dev_ptr) - reinterpret_cast(orig_dev_ptr);
- *mem_size = amd_mem_obj->getSize();
-
- //Check if the dev_ptr is greater than memory allocated
- if (*mem_offset > *mem_size) {
- DevLogPrintfError("Memory offset: %u cannot be greater than size of "
- "original memory allocated: %u", *mem_size, *mem_offset);
- return false;
- }
-
- hsa_status = hsa_amd_ipc_memory_create(orig_dev_ptr, *mem_size,
- reinterpret_cast(handle));
-
- if (hsa_status != HSA_STATUS_SUCCESS) {
- LogPrintfError("Failed to create memory for IPC, failed with hsa_status: %d \n", hsa_status);
- return false;
- }
-
- return true;
-}
-
-bool Device::IpcAttach(const void* handle, size_t mem_size, size_t mem_offset,
- unsigned int flags, void** dev_ptr) const {
- amd::Memory* amd_mem_obj = nullptr;
- void* orig_dev_ptr = nullptr;
-
- // Retrieve the devPtr from the handle
- hsa_status_t hsa_status =
- hsa_amd_ipc_memory_attach(reinterpret_cast(handle),
- mem_size, (1 + p2p_agents_.size()), p2p_agents_list_,
- &orig_dev_ptr);
-
- if (hsa_status != HSA_STATUS_SUCCESS) {
- LogPrintfError("HSA failed to attach IPC memory with status: %d \n", hsa_status);
- return false;
- }
-
- amd_mem_obj = amd::MemObjMap::FindMemObj(orig_dev_ptr);
- if (amd_mem_obj == nullptr) {
-
- // Memory does not exist, create an amd Memory object for the pointer
- amd_mem_obj = new (context()) amd::Buffer(context(), flags, mem_size, orig_dev_ptr);
- if (amd_mem_obj == nullptr) {
- LogError("failed to create a mem object!");
- return false;
- }
-
- if (!amd_mem_obj->create(nullptr)) {
- LogError("failed to create a svm hidden buffer!");
- amd_mem_obj->release();
- return false;
- }
- amd_mem_obj->setIpcShared(true);
- // Add the original mem_ptr to the MemObjMap with newly created amd_mem_obj
- amd::MemObjMap::AddMemObj(orig_dev_ptr, amd_mem_obj);
-
- } else {
- //Memory already exists, just retain the old one.
- amd_mem_obj->retain();
- }
-
- //Make sure the mem_offset doesnt overflow the allocated memory
- guarantee((mem_offset < mem_size), "IPC mem offset greater than allocated size");
-
- // Return orig_dev_ptr
- *dev_ptr = reinterpret_cast(orig_dev_ptr);
-
- return true;
-}
-
-bool Device::IpcDetach (void* dev_ptr) const {
- hsa_status_t hsa_status = HSA_STATUS_SUCCESS;
-
- amd::Memory* amd_mem_obj = amd::MemObjMap::FindMemObj(dev_ptr);
- if (amd_mem_obj == nullptr) {
- DevLogPrintfError("Memory object for the ptr: 0x%x cannot be null \n", dev_ptr);
- return false;
- }
-
- if (!amd_mem_obj->ipcShared()) {
- DevLogPrintfError("Memory object for the ptr: 0x%x is not ipcShared \n", dev_ptr);
- return false;
- }
-
- // Get the original pointer from the amd::Memory object
- void* orig_dev_ptr = nullptr;
- if (amd_mem_obj->getSvmPtr() != nullptr) {
- orig_dev_ptr = amd_mem_obj->getSvmPtr();
- } else if (amd_mem_obj->getHostMem() != nullptr) {
- orig_dev_ptr = amd_mem_obj->getHostMem();
- } else {
- ShouldNotReachHere();
- }
-
- if (amd_mem_obj->release() == 0) {
- amd::MemObjMap::RemoveMemObj(orig_dev_ptr);
-
- // Detach the memory from HSA
- hsa_status = hsa_amd_ipc_memory_detach(orig_dev_ptr);
- if (hsa_status != HSA_STATUS_SUCCESS) {
- LogPrintfError("HSA failed to detach memory with status: %d \n", hsa_status);
- return false;
- }
- }
-
- return true;
-}
-
// ================================================================================================
void* Device::svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags,
void* svmPtr) const {
diff --git a/projects/clr/rocclr/device/rocm/rocdevice.hpp b/projects/clr/rocclr/device/rocm/rocdevice.hpp
index 8618e0a89b..db67b17070 100644
--- a/projects/clr/rocclr/device/rocm/rocdevice.hpp
+++ b/projects/clr/rocclr/device/rocm/rocdevice.hpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2009 - 2021 Advanced Micro Devices, Inc.
+/* Copyright (c) 2009 - 2023 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -483,17 +483,15 @@ class Device : public NullDevice {
// P2P agents avaialble for this device
const std::vector& p2pAgents() const { return p2p_agents_; }
+ //! Returns the list of HSA agents used for IPC memory attach
+ const hsa_agent_t* IpcAgents() const { return p2p_agents_list_; }
+
// User enabled peer devices
const bool isP2pEnabled() const { return (enabled_p2p_devices_.size() > 0) ? true : false; }
// Update the global free memory size
void updateFreeMemory(size_t size, bool free);
- virtual bool IpcCreate(void* dev_ptr, size_t* mem_size, void* handle, size_t* mem_offset) const;
- virtual bool IpcAttach(const void* handle, size_t mem_size, size_t mem_offset,
- unsigned int flags, void** dev_ptr) const;
- virtual bool IpcDetach (void* dev_ptr) const;
-
bool AcquireExclusiveGpuAccess();
void ReleaseExclusiveGpuAccess(VirtualGPU& vgpu) const;
diff --git a/projects/clr/rocclr/device/rocm/rocmemory.cpp b/projects/clr/rocclr/device/rocm/rocmemory.cpp
index cbe0e6cb2b..08cbc5f508 100644
--- a/projects/clr/rocclr/device/rocm/rocmemory.cpp
+++ b/projects/clr/rocclr/device/rocm/rocmemory.cpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008 - 2022 Advanced Micro Devices, Inc.
+/* Copyright (c) 2008 - 2023 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -618,6 +618,14 @@ Buffer::~Buffer() {
dev().hostFree(deviceMemory_, size());
} else {
destroy();
+
+ if (owner()->ipcShared()) {
+ // Detach the memory from HSA
+ auto hsa_status = hsa_amd_ipc_memory_detach(owner()->getHostMem());
+ if (hsa_status != HSA_STATUS_SUCCESS) {
+ LogPrintfError("HSA failed to detach memory with status: %d \n", hsa_status);
+ }
+ }
}
}
@@ -724,6 +732,22 @@ bool Buffer::create(bool alloc_local) {
return false;
}
+ if (owner()->ipcShared()) {
+ void* orig_dev_ptr = nullptr;
+ // Extra 1 for the current device
+ const uint32_t ipc_agents_num = dev().p2pAgents().size() + 1;
+ // Retrieve the devPtr from the handle
+ auto hsa_status = hsa_amd_ipc_memory_attach(
+ reinterpret_cast(
+ reinterpret_cast(owner())->Handle()),
+ owner()->getSize(), ipc_agents_num, dev().IpcAgents(), &orig_dev_ptr);
+ if (hsa_status != HSA_STATUS_SUCCESS) {
+ LogPrintfError("HSA failed to attach IPC memory with status: %d \n", hsa_status);
+ return false;
+ }
+ owner()->setSvmPtr(orig_dev_ptr);
+ }
+
// Allocate backing storage in device local memory unless UHP or AHP are set
cl_mem_flags memFlags = owner()->getMemFlags();
@@ -955,6 +979,24 @@ bool Buffer::create(bool alloc_local) {
return deviceMemory_ != nullptr;
}
+// ================================================================================================
+bool Buffer::ExportHandle(void* handle) const {
+ void* orig_dev_ptr = nullptr;
+ if (owner()->getSvmPtr() != nullptr) {
+ orig_dev_ptr = owner()->getSvmPtr();
+ } else if (owner()->getHostMem() != nullptr) {
+ orig_dev_ptr = owner()->getHostMem();
+ }
+
+ auto hsa_status = hsa_amd_ipc_memory_create(orig_dev_ptr, owner()->getSize(),
+ reinterpret_cast(handle));
+ if (hsa_status != HSA_STATUS_SUCCESS) {
+ LogPrintfError("Failed to create memory for IPC, failed with hsa_status: %d \n", hsa_status);
+ return false;
+ }
+ return true;
+}
+
// ======================================= roc::Image =============================================
typedef struct ChannelOrderMap {
uint32_t cl_channel_order;
diff --git a/projects/clr/rocclr/device/rocm/rocmemory.hpp b/projects/clr/rocclr/device/rocm/rocmemory.hpp
index bcffcf3de1..8a420c54ca 100644
--- a/projects/clr/rocclr/device/rocm/rocmemory.hpp
+++ b/projects/clr/rocclr/device/rocm/rocmemory.hpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2016 - 2022 Advanced Micro Devices, Inc.
+/* Copyright (c) 2016 - 2023 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -171,6 +171,8 @@ class Buffer : public roc::Memory {
// Create device memory according to OpenCL memory flag.
virtual bool create(bool local_alloc = false);
+ virtual bool ExportHandle(void* handle) const final;
+
// Recreate the device memory using new size and alignment.
bool recreate(size_t newSize, size_t newAlignment, bool forceSystem);
diff --git a/projects/clr/rocclr/platform/memory.hpp b/projects/clr/rocclr/platform/memory.hpp
index 847e848a8e..1ea2ff0e4f 100644
--- a/projects/clr/rocclr/platform/memory.hpp
+++ b/projects/clr/rocclr/platform/memory.hpp
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010 - 2022 Advanced Micro Devices, Inc.
+/* Copyright (c) 2010 - 2023 Advanced Micro Devices, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -675,16 +675,17 @@ public:
class IpcBuffer : public Buffer {
public:
- IpcBuffer(Context& context, Flags flags, size_t offset, size_t size, amd::Os::FileDesc handle)
+ IpcBuffer(Context& context, Flags flags, size_t offset, size_t size, const void* handle)
: Buffer(context, flags, offset, size), handle_(handle) {
setIpcShared(true);
}
virtual void initDeviceMemory();
- amd::Os::FileDesc Handle() const { return handle_; }
+
+ const void* Handle() const { return handle_; }
private:
- amd::Os::FileDesc handle_; //!< Ipc handle, associated with this memory object
+ const void* handle_; //!< Ipc handle, associated with this memory object
};