SWDEV-311270 - Clean-up IPC path in ROCclr
- Make IPC interfaces generic between devices and rely on the IPC buffer
for attach/detach logic
Change-Id: Id3c18d122030329b7ee532bbb6317de9dd6a0bbe
[ROCm/clr commit: 9aa6f25f1c]
Tá an tiomantas seo le fáil i:
tiomanta ag
German Andryeyev
tuismitheoir
60b9dc4a45
tiomantas
c8e65415ea
@@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -817,6 +817,116 @@ char* Device::getExtensionString() {
|
|||||||
return result;
|
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<address>(dev_ptr) - reinterpret_cast<address>(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<device::Memory*>(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 amd
|
||||||
|
|
||||||
namespace device {
|
namespace device {
|
||||||
|
|||||||
@@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
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
|
//! Returns CPU pointer to HW state
|
||||||
virtual const address cpuSrd() const { return nullptr; }
|
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; }
|
bool getAllowedPeerAccess() const { return (flags_ & AllowedPeerAccess) ? true : false; }
|
||||||
void setAllowedPeerAccess(bool flag) {
|
void setAllowedPeerAccess(bool flag) {
|
||||||
if (flag == true) {
|
if (flag == true) {
|
||||||
@@ -1894,21 +1897,12 @@ class Device : public RuntimeObject {
|
|||||||
//! Checks if OCL runtime can use hsail for compilation
|
//! Checks if OCL runtime can use hsail for compilation
|
||||||
bool ValidateHsail();
|
bool ValidateHsail();
|
||||||
|
|
||||||
virtual bool IpcCreate(void* dev_ptr, size_t* mem_size, void* handle, size_t* mem_offset) const {
|
bool IpcCreate(void* dev_ptr, size_t* mem_size, void* handle, size_t* mem_offset) const;
|
||||||
ShouldNotReachHere();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool IpcAttach(const void* handle, size_t mem_size, size_t mem_offset,
|
bool IpcAttach(const void* handle, size_t mem_size, size_t mem_offset, unsigned int flags,
|
||||||
unsigned int flags, void** dev_ptr) const {
|
void** dev_ptr) const;
|
||||||
ShouldNotReachHere();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool IpcDetach(void* dev_ptr) const {
|
bool IpcDetach(void* dev_ptr) const;
|
||||||
ShouldNotReachHere();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//! Return context
|
//! Return context
|
||||||
amd::Context& context() const { return *context_; }
|
amd::Context& context() const { return *context_; }
|
||||||
|
|||||||
@@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
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<address>(dev_ptr) - reinterpret_cast<address>(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<void**>(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<amd::Os::FileDesc*>(const_cast<void*>(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() {
|
bool Device::AcquireExclusiveGpuAccess() {
|
||||||
// Lock the virtual GPU list
|
// Lock the virtual GPU list
|
||||||
|
|||||||
@@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
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* virtualAlloc(void* addr, size_t size, size_t alignment);
|
||||||
virtual void virtualFree(void* addr);
|
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
|
//! Returns SRD manger object
|
||||||
SrdManager& srds() const { return *srdManager_; }
|
SrdManager& srds() const { return *srdManager_; }
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
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 {
|
Memory* Buffer::createBufferView(amd::Memory& subBufferOwner) const {
|
||||||
pal::Memory* subBuffer;
|
pal::Memory* subBuffer;
|
||||||
Resource::ViewParams params;
|
Resource::ViewParams params;
|
||||||
@@ -1017,6 +1018,16 @@ Memory* Buffer::createBufferView(amd::Memory& subBufferOwner) const {
|
|||||||
return subBuffer;
|
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<Pal::OsExternalHandle*>(handle) = iMem()->ExportExternalHandle(exportInfo);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ================================================================================================
|
||||||
void* Image::allocMapTarget(const amd::Coord3D& origin, const amd::Coord3D& region, uint mapFlags,
|
void* Image::allocMapTarget(const amd::Coord3D& origin, const amd::Coord3D& region, uint mapFlags,
|
||||||
size_t* rowPitch, size_t* slicePitch) {
|
size_t* rowPitch, size_t* slicePitch) {
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
|
|||||||
@@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
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
|
amd::Memory& subBufferOwner //!< The abstraction layer subbuf owner
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//! Returns an export handle for the interprocess communication
|
||||||
|
virtual bool ExportHandle(void* handle) const final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
//! Disable copy constructor
|
//! Disable copy constructor
|
||||||
Buffer(const Buffer&);
|
Buffer(const Buffer&);
|
||||||
|
|||||||
@@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -1032,7 +1032,8 @@ bool Resource::CreateIpc(CreateParams* params) {
|
|||||||
Pal::ExternalGpuMemoryOpenInfo gpuMemOpenInfo = {};
|
Pal::ExternalGpuMemoryOpenInfo gpuMemOpenInfo = {};
|
||||||
Pal::ExternalResourceOpenInfo& openInfo = gpuMemOpenInfo.resourceInfo;
|
Pal::ExternalResourceOpenInfo& openInfo = gpuMemOpenInfo.resourceInfo;
|
||||||
|
|
||||||
openInfo.hExternalResource = reinterpret_cast<amd::IpcBuffer*>(params->owner_)->Handle();
|
openInfo.hExternalResource = *reinterpret_cast<const Pal::OsExternalHandle*>(
|
||||||
|
reinterpret_cast<amd::IpcBuffer*>(params->owner_)->Handle());
|
||||||
openInfo.flags.ntHandle = false;
|
openInfo.flags.ntHandle = false;
|
||||||
|
|
||||||
memRef_ = GpuMemoryReference::Create(dev(), gpuMemOpenInfo);
|
memRef_ = GpuMemoryReference::Create(dev(), gpuMemOpenInfo);
|
||||||
@@ -1336,14 +1337,6 @@ bool Resource::create(MemoryType memType, CreateParams* params, bool forceLinear
|
|||||||
return true;
|
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<void*>(handle);
|
|
||||||
}
|
|
||||||
// ================================================================================================
|
// ================================================================================================
|
||||||
void Resource::free() {
|
void Resource::free() {
|
||||||
if (memRef_ == nullptr) {
|
if (memRef_ == nullptr) {
|
||||||
|
|||||||
@@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
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
|
bool CreateP2PAccess(CreateParams* params //!< special parameters for resource allocation
|
||||||
);
|
);
|
||||||
//! Returns an export handle for the interprocess communication
|
|
||||||
void* ExportHandle() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*! \brief Creates a PAL memory object, from IPC handle
|
/*! \brief Creates a PAL memory object, from IPC handle
|
||||||
|
|||||||
@@ -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());
|
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<address>(dev_ptr) - reinterpret_cast<address>(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<hsa_amd_ipc_memory_t*>(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<const hsa_amd_ipc_memory_t*>(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<address>(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* Device::svmAlloc(amd::Context& context, size_t size, size_t alignment, cl_svm_mem_flags flags,
|
||||||
void* svmPtr) const {
|
void* svmPtr) const {
|
||||||
|
|||||||
@@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
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
|
// P2P agents avaialble for this device
|
||||||
const std::vector<hsa_agent_t>& p2pAgents() const { return p2p_agents_; }
|
const std::vector<hsa_agent_t>& 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
|
// User enabled peer devices
|
||||||
const bool isP2pEnabled() const { return (enabled_p2p_devices_.size() > 0) ? true : false; }
|
const bool isP2pEnabled() const { return (enabled_p2p_devices_.size() > 0) ? true : false; }
|
||||||
|
|
||||||
// Update the global free memory size
|
// Update the global free memory size
|
||||||
void updateFreeMemory(size_t size, bool free);
|
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();
|
bool AcquireExclusiveGpuAccess();
|
||||||
void ReleaseExclusiveGpuAccess(VirtualGPU& vgpu) const;
|
void ReleaseExclusiveGpuAccess(VirtualGPU& vgpu) const;
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -618,6 +618,14 @@ Buffer::~Buffer() {
|
|||||||
dev().hostFree(deviceMemory_, size());
|
dev().hostFree(deviceMemory_, size());
|
||||||
} else {
|
} else {
|
||||||
destroy();
|
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;
|
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<const hsa_amd_ipc_memory_t*>(
|
||||||
|
reinterpret_cast<const amd::IpcBuffer*>(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
|
// Allocate backing storage in device local memory unless UHP or AHP are set
|
||||||
cl_mem_flags memFlags = owner()->getMemFlags();
|
cl_mem_flags memFlags = owner()->getMemFlags();
|
||||||
|
|
||||||
@@ -955,6 +979,24 @@ bool Buffer::create(bool alloc_local) {
|
|||||||
return deviceMemory_ != nullptr;
|
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<hsa_amd_ipc_memory_t*>(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 =============================================
|
// ======================================= roc::Image =============================================
|
||||||
typedef struct ChannelOrderMap {
|
typedef struct ChannelOrderMap {
|
||||||
uint32_t cl_channel_order;
|
uint32_t cl_channel_order;
|
||||||
|
|||||||
@@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
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.
|
// Create device memory according to OpenCL memory flag.
|
||||||
virtual bool create(bool local_alloc = false);
|
virtual bool create(bool local_alloc = false);
|
||||||
|
|
||||||
|
virtual bool ExportHandle(void* handle) const final;
|
||||||
|
|
||||||
// Recreate the device memory using new size and alignment.
|
// Recreate the device memory using new size and alignment.
|
||||||
bool recreate(size_t newSize, size_t newAlignment, bool forceSystem);
|
bool recreate(size_t newSize, size_t newAlignment, bool forceSystem);
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -675,16 +675,17 @@ public:
|
|||||||
|
|
||||||
class IpcBuffer : public Buffer {
|
class IpcBuffer : public Buffer {
|
||||||
public:
|
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) {
|
: Buffer(context, flags, offset, size), handle_(handle) {
|
||||||
setIpcShared(true);
|
setIpcShared(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void initDeviceMemory();
|
virtual void initDeviceMemory();
|
||||||
amd::Os::FileDesc Handle() const { return handle_; }
|
|
||||||
|
const void* Handle() const { return handle_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
amd::Os::FileDesc handle_; //!< Ipc handle, associated with this memory object
|
const void* handle_; //!< Ipc handle, associated with this memory object
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Tagairt in Eagrán Nua
Cuir bac ar úsáideoir