mirror of
https://github.com/intel/compute-runtime.git
synced 2025-09-15 13:01:45 +08:00
Add support for memory free policies
Add support for ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_BLOCKING_FREE added in v1.3. Related-To: LOCI-2672 Signed-off-by: Jaime Arteaga <jaime.a.arteaga.molina@intel.com>
This commit is contained in:

committed by
Compute-Runtime-Automation

parent
b59b0b6b36
commit
3b497270c8
@ -60,6 +60,7 @@ zeGetMemProcAddrTable(
|
||||
pDdiTable->pfnAllocDevice = zeMemAllocDevice;
|
||||
pDdiTable->pfnAllocHost = zeMemAllocHost;
|
||||
pDdiTable->pfnFree = zeMemFree;
|
||||
pDdiTable->pfnFreeExt = zeMemFreeExt;
|
||||
pDdiTable->pfnGetAllocProperties = zeMemGetAllocProperties;
|
||||
pDdiTable->pfnGetAddressRange = zeMemGetAddressRange;
|
||||
pDdiTable->pfnGetIpcHandle = zeMemGetIpcHandle;
|
||||
|
@ -48,6 +48,14 @@ zeMemFree(
|
||||
return L0::Context::fromHandle(hContext)->freeMem(ptr);
|
||||
}
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zeMemFreeExt(
|
||||
ze_context_handle_t hContext,
|
||||
const ze_memory_free_ext_desc_t *pMemFreeDesc,
|
||||
void *ptr) {
|
||||
return L0::Context::fromHandle(hContext)->freeMemExt(pMemFreeDesc, ptr);
|
||||
}
|
||||
|
||||
ZE_APIEXPORT ze_result_t ZE_APICALL
|
||||
zeMemGetAllocProperties(
|
||||
ze_context_handle_t hContext,
|
||||
|
@ -53,6 +53,9 @@ struct Context : _ze_context_handle_t {
|
||||
size_t alignment,
|
||||
void **ptr) = 0;
|
||||
virtual ze_result_t freeMem(const void *ptr) = 0;
|
||||
virtual ze_result_t freeMem(const void *ptr, bool blocking) = 0;
|
||||
virtual ze_result_t freeMemExt(const ze_memory_free_ext_desc_t *pMemFreeDesc,
|
||||
void *ptr) = 0;
|
||||
virtual ze_result_t makeMemoryResident(ze_device_handle_t hDevice,
|
||||
void *ptr,
|
||||
size_t size) = 0;
|
||||
|
@ -269,6 +269,10 @@ ze_result_t ContextImp::allocSharedMem(ze_device_handle_t hDevice,
|
||||
}
|
||||
|
||||
ze_result_t ContextImp::freeMem(const void *ptr) {
|
||||
return this->freeMem(ptr, false);
|
||||
}
|
||||
|
||||
ze_result_t ContextImp::freeMem(const void *ptr, bool blocking) {
|
||||
auto allocation = this->driverHandle->svmAllocsManager->getSVMAlloc(ptr);
|
||||
if (allocation == nullptr) {
|
||||
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
|
||||
@ -284,18 +288,30 @@ ze_result_t ContextImp::freeMem(const void *ptr) {
|
||||
auto peerAllocData = &iter->second;
|
||||
auto peerAlloc = peerAllocData->gpuAllocations.getDefaultGraphicsAllocation();
|
||||
auto peerPtr = reinterpret_cast<void *>(peerAlloc->getGpuAddress());
|
||||
this->driverHandle->svmAllocsManager->freeSVMAlloc(peerPtr);
|
||||
this->driverHandle->svmAllocsManager->freeSVMAlloc(peerPtr, blocking);
|
||||
deviceImp->peerAllocations.allocations.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
this->driverHandle->svmAllocsManager->freeSVMAlloc(const_cast<void *>(ptr));
|
||||
this->driverHandle->svmAllocsManager->freeSVMAlloc(const_cast<void *>(ptr), blocking);
|
||||
if (this->driverHandle->svmAllocsManager->getSvmMapOperation(ptr)) {
|
||||
this->driverHandle->svmAllocsManager->removeSvmMapOperation(ptr);
|
||||
}
|
||||
return ZE_RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
ze_result_t ContextImp::freeMemExt(const ze_memory_free_ext_desc_t *pMemFreeDesc,
|
||||
void *ptr) {
|
||||
|
||||
if (pMemFreeDesc->freePolicy == ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_BLOCKING_FREE) {
|
||||
return this->freeMem(ptr, true);
|
||||
}
|
||||
if (pMemFreeDesc->freePolicy == ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_DEFER_FREE) {
|
||||
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
|
||||
}
|
||||
return this->freeMem(ptr, false);
|
||||
}
|
||||
|
||||
ze_result_t ContextImp::makeMemoryResident(ze_device_handle_t hDevice, void *ptr, size_t size) {
|
||||
Device *device = L0::Device::fromHandle(hDevice);
|
||||
NEO::Device *neoDevice = device->getNEODevice();
|
||||
|
@ -34,6 +34,9 @@ struct ContextImp : Context {
|
||||
size_t alignment,
|
||||
void **ptr) override;
|
||||
ze_result_t freeMem(const void *ptr) override;
|
||||
ze_result_t freeMem(const void *ptr, bool blocking) override;
|
||||
ze_result_t freeMemExt(const ze_memory_free_ext_desc_t *pMemFreeDesc,
|
||||
void *ptr) override;
|
||||
ze_result_t makeMemoryResident(ze_device_handle_t hDevice,
|
||||
void *ptr,
|
||||
size_t size) override;
|
||||
|
@ -354,6 +354,131 @@ TEST_F(MemoryTest, whenAllocatingSharedMemoryWithHostInitialPlacementBiasFlagThe
|
||||
ASSERT_EQ(result, ZE_RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
struct SVMAllocsManagerFreeExtMock : public NEO::SVMAllocsManager {
|
||||
SVMAllocsManagerFreeExtMock(MemoryManager *memoryManager) : NEO::SVMAllocsManager(memoryManager, false) {}
|
||||
bool freeSVMAlloc(void *ptr, bool blocking) override {
|
||||
if (blocking) {
|
||||
blockingCallsMade++;
|
||||
}
|
||||
return SVMAllocsManager::freeSVMAlloc(ptr, blocking);
|
||||
}
|
||||
uint32_t blockingCallsMade = 0;
|
||||
};
|
||||
|
||||
struct FreeExtTests : public ::testing::Test {
|
||||
void SetUp() override {
|
||||
NEO::MockCompilerEnableGuard mock(true);
|
||||
neoDevice =
|
||||
NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get());
|
||||
auto mockBuiltIns = new MockBuiltins();
|
||||
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->builtins.reset(mockBuiltIns);
|
||||
NEO::DeviceVector devices;
|
||||
devices.push_back(std::unique_ptr<NEO::Device>(neoDevice));
|
||||
driverHandle = std::make_unique<DriverHandleImp>();
|
||||
driverHandle->initialize(std::move(devices));
|
||||
prevSvmAllocsManager = driverHandle->svmAllocsManager;
|
||||
currSvmAllocsManager = new SVMAllocsManagerFreeExtMock(driverHandle->memoryManager);
|
||||
driverHandle->svmAllocsManager = currSvmAllocsManager;
|
||||
device = driverHandle->devices[0];
|
||||
|
||||
context = std::make_unique<ContextImp>(driverHandle.get());
|
||||
EXPECT_NE(context, nullptr);
|
||||
context->getDevices().insert(std::make_pair(device->toHandle(), device));
|
||||
auto neoDevice = device->getNEODevice();
|
||||
context->rootDeviceIndices.insert(neoDevice->getRootDeviceIndex());
|
||||
context->deviceBitfields.insert({neoDevice->getRootDeviceIndex(), neoDevice->getDeviceBitfield()});
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
driverHandle->svmAllocsManager = prevSvmAllocsManager;
|
||||
delete currSvmAllocsManager;
|
||||
}
|
||||
NEO::SVMAllocsManager *prevSvmAllocsManager;
|
||||
NEO::SVMAllocsManager *currSvmAllocsManager;
|
||||
std::unique_ptr<DriverHandleImp> driverHandle;
|
||||
NEO::MockDevice *neoDevice = nullptr;
|
||||
L0::Device *device = nullptr;
|
||||
std::unique_ptr<ContextImp> context;
|
||||
};
|
||||
|
||||
TEST_F(FreeExtTests,
|
||||
whenFreeMemIsCalledWithoutArgumentThenNoBlockingCallIsMade) {
|
||||
size_t size = 1024;
|
||||
size_t alignment = 1u;
|
||||
void *ptr = nullptr;
|
||||
|
||||
ze_host_mem_alloc_desc_t hostDesc = {};
|
||||
ze_result_t result = context->allocHostMem(&hostDesc,
|
||||
size, alignment, &ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_NE(nullptr, ptr);
|
||||
|
||||
result = context->freeMem(ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
SVMAllocsManagerFreeExtMock *memManager = reinterpret_cast<SVMAllocsManagerFreeExtMock *>(currSvmAllocsManager);
|
||||
EXPECT_EQ(0u, memManager->blockingCallsMade);
|
||||
}
|
||||
|
||||
TEST_F(FreeExtTests,
|
||||
whenFreeMemExtIsCalledWithBlockingFreePolicyThenBlockingCallIsMade) {
|
||||
size_t size = 1024;
|
||||
size_t alignment = 1u;
|
||||
void *ptr = nullptr;
|
||||
|
||||
ze_host_mem_alloc_desc_t hostDesc = {};
|
||||
ze_result_t result = context->allocHostMem(&hostDesc,
|
||||
size, alignment, &ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_NE(nullptr, ptr);
|
||||
|
||||
ze_memory_free_ext_desc_t memFreeDesc = {};
|
||||
memFreeDesc.freePolicy = ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_BLOCKING_FREE;
|
||||
result = context->freeMemExt(&memFreeDesc, ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
SVMAllocsManagerFreeExtMock *memManager = reinterpret_cast<SVMAllocsManagerFreeExtMock *>(currSvmAllocsManager);
|
||||
EXPECT_EQ(1u, memManager->blockingCallsMade);
|
||||
}
|
||||
|
||||
TEST_F(FreeExtTests,
|
||||
whenFreeMemExtIsCalledWithDeferFreePolicyThenUnsuportedIsReturned) {
|
||||
size_t size = 1024;
|
||||
size_t alignment = 1u;
|
||||
void *ptr = nullptr;
|
||||
|
||||
ze_host_mem_alloc_desc_t hostDesc = {};
|
||||
ze_result_t result = context->allocHostMem(&hostDesc,
|
||||
size, alignment, &ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_NE(nullptr, ptr);
|
||||
|
||||
ze_memory_free_ext_desc_t memFreeDesc = {};
|
||||
memFreeDesc.freePolicy = ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_DEFER_FREE;
|
||||
result = context->freeMemExt(&memFreeDesc, ptr);
|
||||
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
|
||||
|
||||
result = context->freeMem(ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
}
|
||||
|
||||
TEST_F(FreeExtTests,
|
||||
whenFreeMemExtIsCalledWithDefaultFreePolicyThenNonBlockingCallIsMade) {
|
||||
size_t size = 1024;
|
||||
size_t alignment = 1u;
|
||||
void *ptr = nullptr;
|
||||
|
||||
ze_host_mem_alloc_desc_t hostDesc = {};
|
||||
ze_result_t result = context->allocHostMem(&hostDesc,
|
||||
size, alignment, &ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
EXPECT_NE(nullptr, ptr);
|
||||
|
||||
ze_memory_free_ext_desc_t memFreeDesc = {};
|
||||
result = context->freeMemExt(&memFreeDesc, ptr);
|
||||
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
|
||||
SVMAllocsManagerFreeExtMock *memManager = reinterpret_cast<SVMAllocsManagerFreeExtMock *>(currSvmAllocsManager);
|
||||
EXPECT_EQ(0u, memManager->blockingCallsMade);
|
||||
}
|
||||
|
||||
struct SVMAllocsManagerOutOFMemoryMock : public NEO::SVMAllocsManager {
|
||||
SVMAllocsManagerOutOFMemoryMock(MemoryManager *memoryManager) : NEO::SVMAllocsManager(memoryManager, false) {}
|
||||
void *createUnifiedMemoryAllocation(size_t size,
|
||||
@ -362,9 +487,6 @@ struct SVMAllocsManagerOutOFMemoryMock : public NEO::SVMAllocsManager {
|
||||
}
|
||||
};
|
||||
|
||||
struct DriverHandleOutOfMemoryMock : public DriverHandleImp {
|
||||
};
|
||||
|
||||
struct OutOfMemoryTests : public ::testing::Test {
|
||||
void SetUp() override {
|
||||
NEO::MockCompilerEnableGuard mock(true);
|
||||
@ -374,7 +496,7 @@ struct OutOfMemoryTests : public ::testing::Test {
|
||||
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->builtins.reset(mockBuiltIns);
|
||||
NEO::DeviceVector devices;
|
||||
devices.push_back(std::unique_ptr<NEO::Device>(neoDevice));
|
||||
driverHandle = std::make_unique<DriverHandleOutOfMemoryMock>();
|
||||
driverHandle = std::make_unique<DriverHandleImp>();
|
||||
driverHandle->initialize(std::move(devices));
|
||||
prevSvmAllocsManager = driverHandle->svmAllocsManager;
|
||||
currSvmAllocsManager = new SVMAllocsManagerOutOFMemoryMock(driverHandle->memoryManager);
|
||||
@ -395,7 +517,7 @@ struct OutOfMemoryTests : public ::testing::Test {
|
||||
}
|
||||
NEO::SVMAllocsManager *prevSvmAllocsManager;
|
||||
NEO::SVMAllocsManager *currSvmAllocsManager;
|
||||
std::unique_ptr<DriverHandleOutOfMemoryMock> driverHandle;
|
||||
std::unique_ptr<DriverHandleImp> driverHandle;
|
||||
NEO::MockDevice *neoDevice = nullptr;
|
||||
L0::Device *device = nullptr;
|
||||
std::unique_ptr<ContextImp> context;
|
||||
|
@ -131,7 +131,7 @@ class SVMAllocsManager {
|
||||
const UnifiedMemoryProperties &unifiedMemoryProperties);
|
||||
void setUnifiedAllocationProperties(GraphicsAllocation *allocation, const SvmAllocationProperties &svmProperties);
|
||||
SvmAllocationData *getSVMAlloc(const void *ptr);
|
||||
bool freeSVMAlloc(void *ptr, bool blocking);
|
||||
MOCKABLE_VIRTUAL bool freeSVMAlloc(void *ptr, bool blocking);
|
||||
bool freeSVMAlloc(void *ptr) { return freeSVMAlloc(ptr, false); }
|
||||
void insertSVMAlloc(const SvmAllocationData &svmData);
|
||||
void removeSVMAlloc(const SvmAllocationData &svmData);
|
||||
|
Reference in New Issue
Block a user