Initial HMM support

- Expose ROCclr interfaces for HIP usage
- ROCr interfaces aren't available in staging, thus control the
build with AMD_HMM_SUPPORT define

Change-Id: Iadc2bcc230e78d3b0dc22b235189c8cc80843446
This commit is contained in:
German Andryeyev
2020-06-11 14:26:15 -04:00
parent da1f5bfb94
commit c5afd5d412
12 changed files with 368 additions and 16 deletions
+42 -11
View File
@@ -42,7 +42,7 @@
namespace roc {
/////////////////////////////////roc::Memory//////////////////////////////
// ======================================= roc::Memory ============================================
Memory::Memory(const roc::Device& dev, amd::Memory& owner)
: device::Memory(owner),
dev_(dev),
@@ -620,8 +620,7 @@ void Memory::mgpuCacheWriteBack() {
}
}
/////////////////////////////////roc::Buffer//////////////////////////////
// ==================================== roc::Buffer ===============================================
Buffer::Buffer(const roc::Device& dev, amd::Memory& owner) : roc::Memory(dev, owner) {}
Buffer::Buffer(const roc::Device& dev, size_t size) : roc::Memory(dev, size) {}
@@ -634,6 +633,7 @@ Buffer::~Buffer() {
}
}
// ================================================================================================
void Buffer::destroy() {
if (owner()->parent() != nullptr) {
return;
@@ -647,15 +647,24 @@ void Buffer::destroy() {
cl_mem_flags memFlags = owner()->getMemFlags();
if (owner()->getSvmPtr() != nullptr) {
if (dev().forceFineGrain(owner()) ||
dev().isFineGrainedSystem(true)) {
if (dev().forceFineGrain(owner()) || dev().isFineGrainedSystem(true)) {
memFlags |= CL_MEM_SVM_FINE_GRAIN_BUFFER;
}
const bool isFineGrain = memFlags & CL_MEM_SVM_FINE_GRAIN_BUFFER;
if (kind_ != MEMORY_KIND_PTRGIVEN) {
if (isFineGrain) {
dev().hostFree(deviceMemory_, size());
if (memFlags & CL_MEM_ALLOC_HOST_PTR) {
#if AMD_HMM_SUPPORT
// AMD HMM path. Destroy system memory
amd::Os::uncommitMemory(deviceMemory_, size());
amd::Os::releaseMemory(deviceMemory_, size());
#else
dev().hostFree(deviceMemory_, size());;
#endif // AMD_HMM_SUPPORT
} else {
dev().hostFree(deviceMemory_, size());
}
} else {
dev().memFree(deviceMemory_, size());
}
@@ -705,6 +714,7 @@ void Buffer::destroy() {
}
}
// ================================================================================================
bool Buffer::create() {
if (owner() == nullptr) {
deviceMemory_ = dev().hostAlloc(size(), 1, false);
@@ -731,7 +741,19 @@ bool Buffer::create() {
if (owner()->getSvmPtr() == reinterpret_cast<void*>(1)) {
if (isFineGrain) {
if (memFlags & CL_MEM_SVM_ATOMICS) {
if (memFlags & CL_MEM_ALLOC_HOST_PTR) {
#if AMD_HMM_SUPPORT
// AMD HMM path. Just allocate system memory and KFD will manage it
deviceMemory_ = amd::Os::reserveMemory(
0, size(), amd::Os::pageSize(), amd::Os::MEM_PROT_RW);
amd::Os::commitMemory(deviceMemory_, size(), amd::Os::MEM_PROT_RW);
// Currently HMM requires cirtain initial calls to mark sysmem allocation as
// GPU accessible or prefetch memory into GPU
dev().SvmAllocInit(deviceMemory_, size());
#else
deviceMemory_ = dev().hostAlloc(size(), 1, false);
#endif // AMD_HMM_SUPPORT
} else if (memFlags & CL_MEM_SVM_ATOMICS) {
deviceMemory_ = dev().hostAlloc(size(), 1, true);
}
else {
@@ -745,6 +767,14 @@ bool Buffer::create() {
} else {
deviceMemory_ = owner()->getSvmPtr();
kind_ = MEMORY_KIND_PTRGIVEN;
#if AMD_HMM_SUPPORT
if (memFlags & CL_MEM_ALLOC_HOST_PTR) {
// Currently HMM requires cirtain initial calls to mark sysmem allocation as
// GPU accessible or prefetch memory into the current device
// @note: Skip any allocaiton here, since sysmem was allocated on another device.
dev().SvmAllocInit(deviceMemory_, size());
}
#endif // AMD_HMM_SUPPORT
}
if (!isFineGrain && (owner()->parent() != nullptr) &&
@@ -870,9 +900,10 @@ bool Buffer::create() {
if (owner()->getSvmPtr() != owner()->getHostMem()) {
if (memFlags & (CL_MEM_USE_HOST_PTR | CL_MEM_ALLOC_HOST_PTR)) {
hsa_amd_memory_pool_t pool = (memFlags & CL_MEM_SVM_ATOMICS)? dev().SystemSegment() : dev().SystemCoarseSegment();
hsa_status_t status = hsa_amd_memory_lock_to_pool(owner()->getHostMem(), owner()->getSize(), nullptr,
0, pool, 0, &deviceMemory_);
hsa_amd_memory_pool_t pool = (memFlags & CL_MEM_SVM_ATOMICS) ?
dev().SystemSegment() : dev().SystemCoarseSegment();
hsa_status_t status = hsa_amd_memory_lock_to_pool(owner()->getHostMem(),
owner()->getSize(), nullptr, 0, pool, 0, &deviceMemory_);
if (status != HSA_STATUS_SUCCESS) {
DevLogPrintfError("Failed to lock memory to pool, failed with hsa_status: %d \n", status);
deviceMemory_ = nullptr;
@@ -887,7 +918,7 @@ bool Buffer::create() {
return deviceMemory_ != nullptr;
}
/////////////////////////////////roc::Image//////////////////////////////
// ======================================= roc::Image =============================================
typedef struct ChannelOrderMap {
uint32_t cl_channel_order;
hsa_ext_image_channel_order_t hsa_channel_order;