fix: Update Relaxed Memory Size to check physical before global mem size

Related-To: NEO-9012

- Allows for the memory size requested by the user to be within the
physical memory size if that is set, otherwise the limit is the global
memory size.

Signed-off-by: Spruit, Neil R <neil.r.spruit@intel.com>
This commit is contained in:
Spruit, Neil R
2023-09-28 23:28:12 +00:00
committed by Compute-Runtime-Automation
parent 56f05303c9
commit 5a22477b83
3 changed files with 133 additions and 31 deletions

View File

@@ -157,6 +157,38 @@ bool ContextImp::isDeviceDefinedForThisContext(Device *inDevice) {
return (this->getDevices().find(deviceIndex) != this->getDevices().end());
}
ze_result_t ContextImp::checkMemSizeLimit(Device *inDevice, size_t size, bool relaxedSizeAllowed, void **ptr) {
auto neoDevice = inDevice->getNEODevice();
auto osInterface = neoDevice->getRootDeviceEnvironment().osInterface.get();
uint32_t enabledSubDeviceCount = 1;
if (inDevice->isImplicitScalingCapable()) {
enabledSubDeviceCount = static_cast<uint32_t>(neoDevice->getDeviceBitfield().count());
}
if (relaxedSizeAllowed == false &&
(size > neoDevice->getDeviceInfo().maxMemAllocSize)) {
*ptr = nullptr;
return ZE_RESULT_ERROR_UNSUPPORTED_SIZE;
}
auto &productHelper = inDevice->getProductHelper();
auto physicalMemSize = productHelper.getDeviceMemoryPhysicalSizeInBytes(osInterface, 0) * enabledSubDeviceCount;
uint64_t globalMemSize = neoDevice->getDeviceInfo().globalMemSize;
uint32_t numSubDevices = neoDevice->getNumGenericSubDevices();
if ((!inDevice->isImplicitScalingCapable()) && (numSubDevices > 1)) {
globalMemSize = globalMemSize / numSubDevices;
}
uint64_t memSizeLimit = physicalMemSize;
if (physicalMemSize == 0) {
memSizeLimit = globalMemSize;
}
if (relaxedSizeAllowed && (size > memSizeLimit)) {
*ptr = nullptr;
return ZE_RESULT_ERROR_UNSUPPORTED_SIZE;
}
return ZE_RESULT_SUCCESS;
}
ze_result_t ContextImp::allocDeviceMem(ze_device_handle_t hDevice,
const ze_device_mem_alloc_desc_t *deviceDesc,
size_t size,
@@ -207,21 +239,9 @@ ze_result_t ContextImp::allocDeviceMem(ze_device_handle_t hDevice,
return ZE_RESULT_SUCCESS;
}
if (lookupTable.relaxedSizeAllowed == false &&
(size > neoDevice->getDeviceInfo().maxMemAllocSize)) {
*ptr = nullptr;
return ZE_RESULT_ERROR_UNSUPPORTED_SIZE;
}
uint64_t globalMemSize = neoDevice->getDeviceInfo().globalMemSize;
uint32_t numSubDevices = neoDevice->getNumGenericSubDevices();
if ((!device->isImplicitScalingCapable()) && (numSubDevices > 1)) {
globalMemSize = globalMemSize / numSubDevices;
}
if (lookupTable.relaxedSizeAllowed && (size > globalMemSize)) {
*ptr = nullptr;
return ZE_RESULT_ERROR_UNSUPPORTED_SIZE;
ze_result_t checkResult = checkMemSizeLimit(device, size, lookupTable.relaxedSizeAllowed, ptr);
if (checkResult != ZE_RESULT_SUCCESS) {
return checkResult;
}
deviceBitfields[rootDeviceIndex] = neoDevice->getDeviceBitfield();
@@ -283,22 +303,9 @@ ze_result_t ContextImp::allocSharedMem(ze_device_handle_t hDevice,
return parseResult;
}
if (lookupTable.relaxedSizeAllowed == false &&
(size > neoDevice->getDeviceInfo().maxMemAllocSize)) {
*ptr = nullptr;
return ZE_RESULT_ERROR_UNSUPPORTED_SIZE;
}
uint64_t globalMemSize = neoDevice->getDeviceInfo().globalMemSize;
uint32_t numSubDevices = neoDevice->getNumGenericSubDevices();
if ((!device->isImplicitScalingCapable()) && (numSubDevices > 1)) {
globalMemSize = globalMemSize / numSubDevices;
}
if (lookupTable.relaxedSizeAllowed &&
(size > globalMemSize)) {
*ptr = nullptr;
return ZE_RESULT_ERROR_UNSUPPORTED_SIZE;
ze_result_t checkResult = checkMemSizeLimit(device, size, lookupTable.relaxedSizeAllowed, ptr);
if (checkResult != ZE_RESULT_SUCCESS) {
return checkResult;
}
auto deviceBitfields = this->deviceBitfields;

View File

@@ -187,6 +187,7 @@ struct ContextImp : Context {
NEO::VirtualMemoryReservation *findSupportedVirtualReservation(const void *ptr, size_t size);
std::map<uint64_t, IpcHandleTracking *> &getIPCHandleMap() { return this->ipcHandles; };
[[nodiscard]] std::unique_lock<std::mutex> lockIPCHandleMap() { return std::unique_lock<std::mutex>(this->ipcHandleMapMutex); };
ze_result_t checkMemSizeLimit(Device *inDevice, size_t size, bool relaxedSizeAllowed, void **ptr);
protected:
void setIPCHandleData(NEO::GraphicsAllocation *graphicsAllocation, uint64_t handle, IpcMemoryData &ipcData, uint64_t ptrAddress, uint8_t type);

View File

@@ -16,6 +16,8 @@
#include "shared/source/os_interface/device_factory.h"
#include "shared/source/os_interface/os_context.h"
#include "shared/test/common/helpers/debug_manager_state_restore.h"
#include "shared/test/common/helpers/mock_product_helper_hw.h"
#include "shared/test/common/helpers/raii_product_helper.h"
#include "shared/test/common/helpers/test_files.h"
#include "shared/test/common/mocks/mock_compilers.h"
#include "shared/test/common/mocks/mock_driver_model.h"
@@ -2652,6 +2654,98 @@ TEST_F(MemoryRelaxedSizeTests,
EXPECT_EQ(nullptr, ptr);
}
TEST_F(MemoryRelaxedSizeTests,
givenCallToDeviceAllocWithNoPhysicalMemSizeThenAllocationLargerThanGlobalMemSizeFails) {
auto mockProductHelper = std::make_unique<MockProductHelper>();
std::unique_ptr<ProductHelper> productHelper = std::move(mockProductHelper);
auto &rootDeviceEnvironment = neoDevice->getRootDeviceEnvironmentRef();
std::swap(rootDeviceEnvironment.productHelper, productHelper);
size_t size = device->getNEODevice()->getDeviceInfo().globalMemSize + 1;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
deviceDesc.stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC;
ze_relaxed_allocation_limits_exp_desc_t relaxedSizeDesc = {};
relaxedSizeDesc.stype = ZE_STRUCTURE_TYPE_RELAXED_ALLOCATION_LIMITS_EXP_DESC;
relaxedSizeDesc.flags = ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE;
deviceDesc.pNext = &relaxedSizeDesc;
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_SIZE, result);
EXPECT_EQ(nullptr, ptr);
}
TEST_F(MemoryRelaxedSizeTests,
givenCallToSharedAllocWithNoPhysicalMemSizeThenAllocationLargerThanGlobalMemSizeFails) {
auto mockProductHelper = std::make_unique<MockProductHelper>();
std::unique_ptr<ProductHelper> productHelper = std::move(mockProductHelper);
auto &rootDeviceEnvironment = neoDevice->getRootDeviceEnvironmentRef();
std::swap(rootDeviceEnvironment.productHelper, productHelper);
size_t size = device->getNEODevice()->getDeviceInfo().globalMemSize + 1;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
deviceDesc.stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC;
ze_relaxed_allocation_limits_exp_desc_t relaxedSizeDesc = {};
relaxedSizeDesc.stype = ZE_STRUCTURE_TYPE_RELAXED_ALLOCATION_LIMITS_EXP_DESC;
relaxedSizeDesc.flags = ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE;
deviceDesc.pNext = &relaxedSizeDesc;
ze_host_mem_alloc_desc_t hostDesc = {};
ze_result_t result = context->allocSharedMem(device->toHandle(),
&deviceDesc,
&hostDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_SIZE, result);
EXPECT_EQ(nullptr, ptr);
}
HWTEST2_F(MemoryRelaxedSizeTests,
givenCallToDeviceAllocWithPhysicalMemSizeThenAllocationLargerThanPhysicalMemSizeFails, MatchAny) {
NEO::RAIIProductHelperFactory<MockProductHelperHw<productFamily>> raii(*device->getNEODevice()->getExecutionEnvironment()->rootDeviceEnvironments[0]);
size_t size = 1024u + 1;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
deviceDesc.stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC;
ze_relaxed_allocation_limits_exp_desc_t relaxedSizeDesc = {};
relaxedSizeDesc.stype = ZE_STRUCTURE_TYPE_RELAXED_ALLOCATION_LIMITS_EXP_DESC;
relaxedSizeDesc.flags = ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE;
deviceDesc.pNext = &relaxedSizeDesc;
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_SIZE, result);
EXPECT_EQ(nullptr, ptr);
}
HWTEST2_F(MemoryRelaxedSizeTests,
givenCallToSharedAllocWithNoPhysicalMemSizeThenAllocationLargerThanPhysicalMemSizeFails, MatchAny) {
NEO::RAIIProductHelperFactory<MockProductHelperHw<productFamily>> raii(*device->getNEODevice()->getExecutionEnvironment()->rootDeviceEnvironments[0]);
size_t size = 1024 + 1;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
deviceDesc.stype = ZE_STRUCTURE_TYPE_DEVICE_MEM_ALLOC_DESC;
ze_relaxed_allocation_limits_exp_desc_t relaxedSizeDesc = {};
relaxedSizeDesc.stype = ZE_STRUCTURE_TYPE_RELAXED_ALLOCATION_LIMITS_EXP_DESC;
relaxedSizeDesc.flags = ZE_RELAXED_ALLOCATION_LIMITS_EXP_FLAG_MAX_SIZE;
deviceDesc.pNext = &relaxedSizeDesc;
ze_host_mem_alloc_desc_t hostDesc = {};
ze_result_t result = context->allocSharedMem(device->toHandle(),
&deviceDesc,
&hostDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_SIZE, result);
EXPECT_EQ(nullptr, ptr);
}
TEST_F(MemoryRelaxedSizeTests,
givenCallToDeviceAllocWithLargerThanAllowedSizeAndRelaxedFlagWithIncorrectFlagThenAllocationIsNotMade) {
size_t size = device->getNEODevice()->getDeviceInfo().maxMemAllocSize + 1;