feature: prepare for l0 usm device pooling

Related-To: NEO-6893

Signed-off-by: Dominik Dabek <dominik.dabek@intel.com>
This commit is contained in:
Dominik Dabek
2025-04-25 17:35:55 +00:00
committed by Compute-Runtime-Automation
parent c2266fc69e
commit 75e313ce28
23 changed files with 459 additions and 35 deletions

View File

@@ -59,6 +59,7 @@ struct DeviceFixture {
template <typename T>
struct DeviceFixtureWithCustomMemoryManager : public DeviceFixture {
void setUp() {
debugManager.flags.EnableDeviceUsmAllocationPool.set(0);
auto executionEnvironment = NEO::MockDevice::prepareExecutionEnvironment(defaultHwInfo.get(), 0u);
memoryManager = new T(*executionEnvironment);
executionEnvironment->memoryManager.reset(memoryManager);
@@ -68,7 +69,7 @@ struct DeviceFixtureWithCustomMemoryManager : public DeviceFixture {
void tearDown() {
DeviceFixture::tearDown();
}
DebugManagerStateRestore restorer;
T *memoryManager = nullptr;
};

View File

@@ -536,6 +536,11 @@ void MemoryExportImportImplicitScalingTest::SetUp() {
}
void MemoryExportImportImplicitScalingTest::TearDown() {
// cleanup pool before restoring svm manager
for (auto device : driverHandle->devices) {
device->getNEODevice()->cleanupUsmAllocationPool();
device->getNEODevice()->resetUsmAllocationPool(nullptr);
}
driverHandle->svmAllocsManager = prevSvmAllocsManager;
delete currSvmAllocsManager;
driverHandle->setMemoryManager(prevMemoryManager);

View File

@@ -5488,8 +5488,9 @@ HWTEST_F(InOrderCmdListTests, givenExternalSyncStorageWhenCreatingCounterBasedEv
EXPECT_EQ(counterValue, inOrderExecInfo->getCounterValue());
EXPECT_EQ(castToUint64(externalStorageAllocProperties.deviceAddress), inOrderExecInfo->getBaseDeviceAddress());
EXPECT_NE(nullptr, inOrderExecInfo->getDeviceCounterAllocation());
auto lockedPtr = reinterpret_cast<uint64_t *>(ptrOffset(inOrderExecInfo->getDeviceCounterAllocation()->getLockedPtr(), sizeof(uint64_t)));
SvmAllocationData *deviceAlloc = context->getDriverHandle()->getSvmAllocsManager()->getSVMAlloc(reinterpret_cast<void *>(devAddress));
auto offset = ptrDiff(devAddress, deviceAlloc->gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress());
auto lockedPtr = reinterpret_cast<uint64_t *>(ptrOffset(inOrderExecInfo->getDeviceCounterAllocation()->getLockedPtr(), sizeof(uint64_t) + offset));
EXPECT_EQ(inOrderExecInfo->getBaseHostAddress(), lockedPtr);
EXPECT_EQ(inOrderExecInfo->getExternalHostAllocation(), inOrderExecInfo->getDeviceCounterAllocation());

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2020-2024 Intel Corporation
* Copyright (C) 2020-2025 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@@ -34,6 +34,7 @@ namespace ult {
struct L0DebuggerWindowsFixture {
void setUp() {
debugManager.flags.ForcePreferredAllocationMethod.set(static_cast<int32_t>(GfxMemoryAllocationMethod::useUmdSystemPtr));
debugManager.flags.EnableDeviceUsmAllocationPool.set(0);
executionEnvironment = new NEO::ExecutionEnvironment;
executionEnvironment->setDebuggingMode(NEO::DebuggingMode::online);
executionEnvironment->prepareRootDeviceEnvironments(1);

View File

@@ -198,6 +198,7 @@ TEST_F(DriverVersionTest, givenExternalAllocatorWhenCallingGetExtensionPropertie
DebugManagerStateRestore restorer;
NEO::debugManager.flags.UseBindlessMode.set(1);
NEO::debugManager.flags.UseExternalAllocatorForSshAndDsh.set(1);
NEO::debugManager.flags.EnableDeviceUsmAllocationPool.set(0);
auto hwInfo = *NEO::defaultHwInfo;
NEO::MockDevice *neoDevice = NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(&hwInfo);

View File

@@ -50,7 +50,7 @@ TEST(ApiSpecificConfigL0Tests, WhenCheckingIfHostDeviceAllocationCacheIsEnabledT
TEST(ApiSpecificConfigL0Tests, WhenCheckingIfUsmAllocPoolingIsEnabledThenReturnFalse) {
EXPECT_FALSE(ApiSpecificConfig::isHostUsmPoolingEnabled());
EXPECT_TRUE(ApiSpecificConfig::isDeviceUsmPoolingEnabled());
EXPECT_FALSE(ApiSpecificConfig::isDeviceUsmPoolingEnabled());
}
TEST(ApiSpecificConfigL0Tests, GivenDebugFlagCombinationsGetCorrectSharedAllocPrefetchEnabled) {

View File

@@ -171,6 +171,7 @@ struct MemoryExportImportObtainFdTest : public ::testing::Test {
void SetUp() override {
DebugManagerStateRestore restorer;
debugManager.flags.EnableImplicitScaling.set(1);
debugManager.flags.EnableDeviceUsmAllocationPool.set(0); // not compatible with MemoryManagerIpcImplicitScalingObtainFdMock
executionEnvironment = new NEO::ExecutionEnvironment();
executionEnvironment->prepareRootDeviceEnvironments(numRootDevices);
@@ -604,7 +605,7 @@ struct DriverHandleObtaindFdMock : public L0::DriverHandleImp {
struct MemoryObtainFdTest : public ::testing::Test {
void SetUp() override {
DebugManagerStateRestore restorer;
debugManager.flags.EnableDeviceUsmAllocationPool.set(0); // not compatible with MemoryManagerIpcObtainFdMock
executionEnvironment = new NEO::ExecutionEnvironment();
executionEnvironment->prepareRootDeviceEnvironments(numRootDevices);
NEO::HardwareInfo hwInfo = *NEO::defaultHwInfo.get();

View File

@@ -324,6 +324,11 @@ TEST_F(MemoryExportImportImplicitScalingTest,
using MemoryTest = Test<DeviceFixture>;
struct CompressionMemoryTest : public MemoryTest {
void SetUp() override {
debugManager.flags.EnableHostUsmAllocationPool.set(0);
debugManager.flags.EnableDeviceUsmAllocationPool.set(0);
MemoryTest::SetUp();
}
GraphicsAllocation *allocDeviceMem(size_t size) {
ptr = nullptr;
ze_result_t result = context->allocDeviceMem(device->toHandle(),
@@ -1331,11 +1336,16 @@ TEST_F(MemoryTest, givenProductWithNon48bForRTWhenAllocatingSharedMemoryAsRayTra
TEST_F(MemoryTest, givenProductWith48bForRTWhenAllocatingDeviceMemoryAsRayTracingAllocationAddressIsIn48Bits) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = reinterpret_cast<void *>(0x1234);
ze_device_mem_alloc_desc_t deviceDesc = {};
// do warmup alloc to make sure usm device pool is allocated before validation in mem mgr
{
void *ptr;
EXPECT_EQ(ZE_RESULT_SUCCESS, context->allocDeviceMem(device->toHandle(), &deviceDesc, size, 0u, &ptr));
EXPECT_EQ(ZE_RESULT_SUCCESS, context->freeMem(ptr));
}
void *ptr = reinterpret_cast<void *>(0x1234);
ze_raytracing_mem_alloc_ext_desc_t rtDesc = {};
rtDesc.stype = ZE_STRUCTURE_TYPE_RAYTRACING_MEM_ALLOC_EXT_DESC;
deviceDesc.pNext = &rtDesc;
@@ -1515,6 +1525,13 @@ TEST_F(MemoryTest, whenAllocatingDeviceMemoryThenAlignmentIsPassedCorrectlyAndMe
auto memoryManager = static_cast<MockMemoryManager *>(neoDevice->getMemoryManager());
// do warmup alloc to make sure usm device pool is allocated before validation in mem mgr
{
void *ptr;
EXPECT_EQ(ZE_RESULT_SUCCESS, context->allocDeviceMem(device->toHandle(), &deviceDesc, size, 0u, &ptr));
EXPECT_EQ(ZE_RESULT_SUCCESS, context->freeMem(ptr));
}
size_t alignment = 8 * MemoryConstants::megaByte;
do {
alignment >>= 1;
@@ -1665,7 +1682,6 @@ struct SVMAllocsManagerFreeExtMock : public NEO::SVMAllocsManager {
struct FreeExtTests : public ::testing::Test {
void SetUp() override {
neoDevice =
NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get());
auto mockBuiltIns = new MockBuiltins();
@@ -2010,6 +2026,13 @@ TEST_F(FreeExtTests,
TEST_F(FreeExtTests,
whenAllocMemFailsWithDeferredFreeAllocationThenMemoryFreedAndRetrySucceeds) {
// does not make sense for usm pooling, disable for test
driverHandle->usmHostMemAllocPool.cleanup();
if (auto deviceUsmPool = neoDevice->getUsmMemAllocPool()) {
deviceUsmPool->cleanup();
neoDevice->usmMemAllocPool.reset(nullptr);
}
size_t size = 1024;
size_t alignment = 1u;
void *ptr = nullptr;
@@ -2242,7 +2265,8 @@ struct ContextRelaxedSizeMock : public ContextImp {
struct MemoryRelaxedSizeTests : public ::testing::Test {
void SetUp() override {
// disable usm device pooling, used svm manager mock does not make svmData
debugManager.flags.EnableDeviceUsmAllocationPool.set(0);
neoDevice =
NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get());
auto mockBuiltIns = new MockBuiltins();
@@ -2274,6 +2298,7 @@ struct MemoryRelaxedSizeTests : public ::testing::Test {
NEO::MockDevice *neoDevice = nullptr;
L0::Device *device = nullptr;
std::unique_ptr<ContextRelaxedSizeMock> context;
DebugManagerStateRestore restorer;
};
TEST_F(MemoryRelaxedSizeTests,
@@ -3729,6 +3754,11 @@ struct MultipleDevicePeerAllocationTest : public ::testing::Test {
}
void TearDown() override {
// cleanup pool before restoring svm manager
for (auto device : driverHandle->devices) {
device->getNEODevice()->cleanupUsmAllocationPool();
device->getNEODevice()->resetUsmAllocationPool(nullptr);
}
driverHandle->svmAllocsManager = prevSvmAllocsManager;
delete currSvmAllocsManager;
driverHandle->setMemoryManager(prevMemoryManager);
@@ -3858,6 +3888,12 @@ HWTEST2_F(MultipleDevicePeerAllocationTest,
auto ret = deviceImp1->getCsrForOrdinalAndIndex(&csr, 0u, 0u, ZE_COMMAND_QUEUE_PRIORITY_NORMAL, false);
ASSERT_EQ(ret, ZE_RESULT_SUCCESS);
// disable device usm pooling - allocation will not be pooled but pool will be initialized
for (auto device : driverHandle->devices) {
device->getNEODevice()->cleanupUsmAllocationPool();
device->getNEODevice()->resetUsmAllocationPool(nullptr);
}
size_t size = 1024;
size_t alignment = 1u;
ze_device_mem_alloc_desc_t deviceDesc = {};
@@ -3899,6 +3935,12 @@ HWTEST2_F(MultipleDevicePeerAllocationTest,
auto ret = deviceImp1->getCsrForOrdinalAndIndex(&csr, 0u, 0u, ZE_COMMAND_QUEUE_PRIORITY_NORMAL, false);
ASSERT_EQ(ret, ZE_RESULT_SUCCESS);
// disable device usm pooling - allocation will not be pooled but pool will be initialized
for (auto device : driverHandle->devices) {
device->getNEODevice()->cleanupUsmAllocationPool();
device->getNEODevice()->resetUsmAllocationPool(nullptr);
}
size_t size = 1024;
size_t alignment = 1u;
ze_device_mem_alloc_desc_t deviceDesc = {};
@@ -5567,6 +5609,11 @@ struct MemAllocMultiSubDeviceTests : public ::testing::Test {
}
void TearDown() override {
// cleanup pool before restoring svm manager
for (auto device : driverHandle->devices) {
device->getNEODevice()->cleanupUsmAllocationPool();
device->getNEODevice()->resetUsmAllocationPool(nullptr);
}
driverHandle->svmAllocsManager = prevSvmAllocsManager;
delete currSvmAllocsManager;
}

View File

@@ -21,6 +21,7 @@
#include "level_zero/core/source/driver/driver_handle_imp.h"
#include "level_zero/core/test/unit_tests/mock.h"
#include "level_zero/core/test/unit_tests/mocks/mock_driver_handle.h"
namespace L0 {
namespace ult {
template <int hostUsmPoolFlag = -1, int deviceUsmPoolFlag = -1, int poolingVersionFlag = -1>
@@ -53,6 +54,8 @@ struct AllocUsmPoolMemoryTest : public ::testing::Test {
driverHandle = std::make_unique<Mock<L0::DriverHandleImp>>();
driverHandle->initialize(std::move(devices));
l0Devices[0] = driverHandle->devices[0];
l0Devices[1] = driverHandle->devices[1];
ze_context_handle_t hContext;
ze_context_desc_t desc = {ZE_STRUCTURE_TYPE_CONTEXT_DESC, nullptr, 0};
@@ -72,6 +75,7 @@ struct AllocUsmPoolMemoryTest : public ::testing::Test {
std::vector<std::unique_ptr<NEO::Device>> devices;
std::vector<MockProductHelper *> mockProductHelpers;
NEO::ExecutionEnvironment *executionEnvironment;
L0::Device *l0Devices[2];
constexpr static auto poolAllocationThreshold = 1 * MemoryConstants::megaByte;
};
@@ -116,27 +120,46 @@ TEST_F(AllocUsmHostEnabledMemoryTest, givenDriverHandleWhenCallingAllocHostMemWi
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr1Byte);
EXPECT_TRUE(driverHandle->usmHostMemAllocPool.isInPool(ptr1Byte));
EXPECT_EQ(1u, mockHostMemAllocPool->allocations.getNumAllocs());
EXPECT_EQ(poolAllocationData, driverHandle->svmAllocsManager->getSVMAlloc(ptr1Byte));
result = context->freeMem(ptr1Byte);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, mockHostMemAllocPool->allocations.getNumAllocs());
void *ptrThreshold = nullptr;
result = context->allocHostMem(&hostDesc, poolAllocationThreshold, 0u, &ptrThreshold);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptrThreshold);
EXPECT_TRUE(driverHandle->usmHostMemAllocPool.isInPool(ptrThreshold));
EXPECT_EQ(1u, mockHostMemAllocPool->allocations.getNumAllocs());
EXPECT_EQ(poolAllocationData, driverHandle->svmAllocsManager->getSVMAlloc(ptrThreshold));
result = context->freeMem(ptrThreshold);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, mockHostMemAllocPool->allocations.getNumAllocs());
void *ptrOverThreshold = nullptr;
result = context->allocHostMem(&hostDesc, poolAllocationThreshold + 1u, 0u, &ptrOverThreshold);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptrOverThreshold);
EXPECT_FALSE(driverHandle->usmHostMemAllocPool.isInPool(ptrOverThreshold));
EXPECT_EQ(0u, mockHostMemAllocPool->allocations.getNumAllocs());
EXPECT_NE(poolAllocationData, driverHandle->svmAllocsManager->getSVMAlloc(ptrOverThreshold));
result = context->freeMem(ptrOverThreshold);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, mockHostMemAllocPool->allocations.getNumAllocs());
void *ptrFreeMemExt = nullptr;
result = context->allocHostMem(&hostDesc, poolAllocationThreshold, 0u, &ptrFreeMemExt);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptrFreeMemExt);
EXPECT_TRUE(driverHandle->usmHostMemAllocPool.isInPool(ptrFreeMemExt));
EXPECT_EQ(1u, mockHostMemAllocPool->allocations.getNumAllocs());
EXPECT_EQ(poolAllocationData, driverHandle->svmAllocsManager->getSVMAlloc(ptrFreeMemExt));
ze_memory_free_ext_desc_t memFreeDesc = {};
memFreeDesc.freePolicy = ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_DEFER_FREE;
result = context->freeMemExt(&memFreeDesc, ptrFreeMemExt);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, mockHostMemAllocPool->allocations.getNumAllocs());
void *ptrExportMemory = nullptr;
ze_external_memory_export_desc_t externalMemoryDesc{};
@@ -147,9 +170,11 @@ TEST_F(AllocUsmHostEnabledMemoryTest, givenDriverHandleWhenCallingAllocHostMemWi
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptrExportMemory);
EXPECT_FALSE(driverHandle->usmHostMemAllocPool.isInPool(ptrExportMemory));
EXPECT_EQ(0u, mockHostMemAllocPool->allocations.getNumAllocs());
EXPECT_NE(poolAllocationData, driverHandle->svmAllocsManager->getSVMAlloc(ptrExportMemory));
result = context->freeMem(ptrExportMemory);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, mockHostMemAllocPool->allocations.getNumAllocs());
}
TEST_F(AllocUsmHostEnabledMemoryTest, givenDrmDriverModelWhenOpeningIpcHandleFromPooledAllocationThenOffsetIsApplied) {
@@ -187,6 +212,176 @@ TEST_F(AllocUsmHostEnabledMemoryTest, givenDrmDriverModelWhenOpeningIpcHandleFro
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
using AllocUsmDeviceDefaultMemoryTest = AllocUsmPoolMemoryTest<-1, -1>;
TEST_F(AllocUsmDeviceDefaultMemoryTest, givenDeviceWhenCallingAllocDeviceMemThenDoNotUsePool) {
EXPECT_EQ(nullptr, l0Devices[0]->getNEODevice()->getUsmMemAllocPool());
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(l0Devices[0], &deviceDesc, 1u, 0u, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
EXPECT_EQ(nullptr, l0Devices[0]->getNEODevice()->getUsmMemAllocPool());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
using AllocUsmDeviceDisabledMemoryTest = AllocUsmPoolMemoryTest<-1, 0>;
TEST_F(AllocUsmDeviceDisabledMemoryTest, givenDeviceWhenCallingAllocDeviceMemThenDoNotUsePool) {
EXPECT_EQ(nullptr, l0Devices[0]->getNEODevice()->getUsmMemAllocPool());
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(l0Devices[0], &deviceDesc, 1u, 0u, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
EXPECT_EQ(nullptr, l0Devices[0]->getNEODevice()->getUsmMemAllocPool());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
using AllocUsmDeviceEnabledMemoryTest = AllocUsmPoolMemoryTest<0, 1>;
TEST_F(AllocUsmDeviceEnabledMemoryTest, givenDeviceWhenCallingAllocDeviceMemWithVariousParametersThenUsePoolIfAllowed) {
auto mockDeviceMemAllocPool = reinterpret_cast<MockUsmMemAllocPool *>(l0Devices[0]->getNEODevice()->getUsmMemAllocPool());
ASSERT_NE(nullptr, mockDeviceMemAllocPool);
EXPECT_TRUE(mockDeviceMemAllocPool->isInitialized());
void *ptr1Byte = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(l0Devices[0], &deviceDesc, 1u, 0u, &ptr1Byte);
EXPECT_TRUE(mockDeviceMemAllocPool->isInitialized());
auto poolAllocationData = driverHandle->svmAllocsManager->getSVMAlloc(mockDeviceMemAllocPool->pool);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr1Byte);
EXPECT_TRUE(mockDeviceMemAllocPool->isInPool(ptr1Byte));
EXPECT_EQ(1u, mockDeviceMemAllocPool->allocations.getNumAllocs());
EXPECT_EQ(poolAllocationData, driverHandle->svmAllocsManager->getSVMAlloc(ptr1Byte));
result = context->freeMem(ptr1Byte);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, mockDeviceMemAllocPool->allocations.getNumAllocs());
void *ptrThreshold = nullptr;
result = context->allocDeviceMem(l0Devices[0], &deviceDesc, poolAllocationThreshold, 0u, &ptrThreshold);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptrThreshold);
EXPECT_TRUE(mockDeviceMemAllocPool->isInPool(ptrThreshold));
EXPECT_EQ(1u, mockDeviceMemAllocPool->allocations.getNumAllocs());
EXPECT_EQ(poolAllocationData, driverHandle->svmAllocsManager->getSVMAlloc(ptrThreshold));
result = context->freeMem(ptrThreshold);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, mockDeviceMemAllocPool->allocations.getNumAllocs());
void *ptrOverThreshold = nullptr;
result = context->allocDeviceMem(l0Devices[0], &deviceDesc, poolAllocationThreshold + 1u, 0u, &ptrOverThreshold);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptrOverThreshold);
EXPECT_FALSE(mockDeviceMemAllocPool->isInPool(ptrOverThreshold));
EXPECT_EQ(0u, mockDeviceMemAllocPool->allocations.getNumAllocs());
EXPECT_NE(poolAllocationData, driverHandle->svmAllocsManager->getSVMAlloc(ptrOverThreshold));
result = context->freeMem(ptrOverThreshold);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, mockDeviceMemAllocPool->allocations.getNumAllocs());
void *ptrFreeMemExt = nullptr;
result = context->allocDeviceMem(l0Devices[0], &deviceDesc, poolAllocationThreshold, 0u, &ptrFreeMemExt);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptrFreeMemExt);
EXPECT_TRUE(mockDeviceMemAllocPool->isInPool(ptrFreeMemExt));
EXPECT_EQ(1u, mockDeviceMemAllocPool->allocations.getNumAllocs());
EXPECT_EQ(poolAllocationData, driverHandle->svmAllocsManager->getSVMAlloc(ptrFreeMemExt));
ze_memory_free_ext_desc_t memFreeDesc = {};
memFreeDesc.freePolicy = ZE_DRIVER_MEMORY_FREE_POLICY_EXT_FLAG_DEFER_FREE;
result = context->freeMemExt(&memFreeDesc, ptrFreeMemExt);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, mockDeviceMemAllocPool->allocations.getNumAllocs());
void *ptrExportMemory = nullptr;
ze_external_memory_export_desc_t externalMemoryDesc{};
externalMemoryDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC;
externalMemoryDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
deviceDesc.pNext = &externalMemoryDesc;
result = context->allocDeviceMem(l0Devices[0], &deviceDesc, poolAllocationThreshold, 0u, &ptrExportMemory);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptrExportMemory);
EXPECT_FALSE(mockDeviceMemAllocPool->isInPool(ptrExportMemory));
EXPECT_EQ(0u, mockDeviceMemAllocPool->allocations.getNumAllocs());
EXPECT_NE(poolAllocationData, driverHandle->svmAllocsManager->getSVMAlloc(ptrExportMemory));
result = context->freeMemExt(&memFreeDesc, ptrExportMemory);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(0u, mockDeviceMemAllocPool->allocations.getNumAllocs());
}
TEST_F(AllocUsmDeviceEnabledMemoryTest, givenDrmDriverModelWhenOpeningIpcHandleFromPooledAllocationThenOffsetIsApplied) {
auto mockDeviceMemAllocPool = reinterpret_cast<MockUsmMemAllocPool *>(l0Devices[0]->getNEODevice()->getUsmMemAllocPool());
ASSERT_NE(nullptr, mockDeviceMemAllocPool);
EXPECT_TRUE(mockDeviceMemAllocPool->isInitialized());
executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<NEO::MockDriverModelDRM>());
void *pooledAllocation = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(l0Devices[0], &deviceDesc, 1u, 0u, &pooledAllocation);
auto poolAllocationData = driverHandle->svmAllocsManager->getSVMAlloc(mockDeviceMemAllocPool->pool);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, pooledAllocation);
EXPECT_TRUE(mockDeviceMemAllocPool->isInPool(pooledAllocation));
EXPECT_EQ(poolAllocationData, driverHandle->svmAllocsManager->getSVMAlloc(pooledAllocation));
const auto pooledAllocationOffset = ptrDiff(mockDeviceMemAllocPool->allocations.get(pooledAllocation)->address, castToUint64(mockDeviceMemAllocPool->pool));
EXPECT_NE(0u, pooledAllocationOffset);
ze_ipc_mem_handle_t ipcHandle{};
result = context->getIpcMemHandle(pooledAllocation, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
IpcMemoryData &ipcData = *reinterpret_cast<IpcMemoryData *>(ipcHandle.data);
EXPECT_EQ(pooledAllocationOffset, ipcData.poolOffset);
ze_ipc_memory_flags_t ipcFlags{};
void *ipcPointer = nullptr;
result = context->openIpcMemHandle(driverHandle->devices[0]->toHandle(), ipcHandle, ipcFlags, &ipcPointer);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(ptrOffset(addrToPtr(0x1u), pooledAllocationOffset), ipcPointer);
context->closeIpcMemHandle(addrToPtr(0x1u));
result = context->freeMem(pooledAllocation);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(AllocUsmDeviceEnabledMemoryTest, givenDrmDriverModelWhenOpeningIpcHandleFromNotPooledAllocationThenOffsetIsNotApplied) {
auto mockDeviceMemAllocPool = reinterpret_cast<MockUsmMemAllocPool *>(l0Devices[0]->getNEODevice()->getUsmMemAllocPool());
ASSERT_NE(nullptr, mockDeviceMemAllocPool);
EXPECT_TRUE(mockDeviceMemAllocPool->isInitialized());
executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<NEO::MockDriverModelDRM>());
void *allocation = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(l0Devices[0], &deviceDesc, 1u, 1u, &allocation);
auto allocationData = driverHandle->svmAllocsManager->getSVMAlloc(mockDeviceMemAllocPool->pool);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, allocation);
EXPECT_FALSE(mockDeviceMemAllocPool->isInPool(allocation));
EXPECT_NE(allocationData, driverHandle->svmAllocsManager->getSVMAlloc(allocation));
ze_ipc_mem_handle_t ipcHandle{};
result = context->getIpcMemHandle(allocation, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
IpcMemoryData &ipcData = *reinterpret_cast<IpcMemoryData *>(ipcHandle.data);
EXPECT_EQ(0u, ipcData.poolOffset);
ze_ipc_memory_flags_t ipcFlags{};
void *ipcPointer = nullptr;
result = context->openIpcMemHandle(driverHandle->devices[0]->toHandle(), ipcHandle, ipcFlags, &ipcPointer);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(addrToPtr(0x1u), ipcPointer);
context->closeIpcMemHandle(addrToPtr(0x1u));
result = context->freeMem(allocation);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
using AllocUsmDeviceEnabledMemoryNewVersionTest = AllocUsmPoolMemoryTest<-1, 1, 2>;
TEST_F(AllocUsmDeviceEnabledMemoryNewVersionTest, givenContextWhenAllocatingAndFreeingDeviceUsmThenPoolingIsUsed) {

View File

@@ -374,6 +374,7 @@ HWTEST_F(ModuleTest, givenStatefulBufferWhenOffsetIsPatchedThenAllocBaseAddressI
auto gpuAlloc = device->getDriverHandle()->getSvmAllocsManager()->getSVMAllocs()->get(devicePtr)->gpuAllocations.getGraphicsAllocation(device->getRootDeviceIndex());
ASSERT_NE(nullptr, gpuAlloc);
const auto gpuAllocAddress = gpuAlloc->getGpuAddress();
uint32_t argIndex = 0u;
uint32_t offset = 0x1234;
@@ -386,7 +387,7 @@ HWTEST_F(ModuleTest, givenStatefulBufferWhenOffsetIsPatchedThenAllocBaseAddressI
auto argInfo = kernelImp->getImmutableData()->getDescriptor().payloadMappings.explicitArgs[argIndex].as<NEO::ArgDescPointer>();
auto surfaceStateAddressRaw = ptrOffset(kernelImp->getSurfaceStateHeapData(), argInfo.bindful);
auto surfaceStateAddress = reinterpret_cast<RENDER_SURFACE_STATE *>(const_cast<unsigned char *>(surfaceStateAddressRaw));
EXPECT_EQ(devicePtr, reinterpret_cast<void *>(surfaceStateAddress->getSurfaceBaseAddress()));
EXPECT_EQ(gpuAllocAddress, surfaceStateAddress->getSurfaceBaseAddress());
// Bindless arg
surfaceStateAddress->setSurfaceBaseAddress(0);
@@ -397,7 +398,7 @@ HWTEST_F(ModuleTest, givenStatefulBufferWhenOffsetIsPatchedThenAllocBaseAddressI
kernelImp->setBufferSurfaceState(argIndex, ptrOffset(devicePtr, offset), gpuAlloc);
surfaceStateAddress = reinterpret_cast<RENDER_SURFACE_STATE *>(const_cast<unsigned char *>(kernelImp->getSurfaceStateHeapData()));
EXPECT_EQ(devicePtr, reinterpret_cast<void *>(surfaceStateAddress->getSurfaceBaseAddress()));
EXPECT_EQ(gpuAllocAddress, surfaceStateAddress->getSurfaceBaseAddress());
Kernel::fromHandle(kernelHandle)->destroy();
@@ -446,7 +447,7 @@ HWTEST_F(ModuleTest, givenBufferWhenOffsetIsNotPatchedThenPassedPtrIsSetAsBaseAd
context->freeMem(devicePtr);
}
HWTEST_F(ModuleTest, givenBufferWhenOffsetIsNotPatchedThenSizeIsDecereasedByOffset) {
HWTEST_F(ModuleTest, givenBufferWhenOffsetIsNotPatchedThenSizeIsDecreasedByOffset) {
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
ze_kernel_handle_t kernelHandle;
@@ -470,6 +471,7 @@ HWTEST_F(ModuleTest, givenBufferWhenOffsetIsNotPatchedThenSizeIsDecereasedByOffs
auto gpuAlloc = device->getDriverHandle()->getSvmAllocsManager()->getSVMAllocs()->get(devicePtr)->gpuAllocations.getGraphicsAllocation(device->getRootDeviceIndex());
ASSERT_NE(nullptr, gpuAlloc);
const auto devicePtrOffsetInAlloc = ptrDiff(devicePtr, gpuAlloc->getGpuAddress());
uint32_t argIndex = 0u;
uint32_t offset = 0x1234;
@@ -482,7 +484,8 @@ HWTEST_F(ModuleTest, givenBufferWhenOffsetIsNotPatchedThenSizeIsDecereasedByOffs
auto surfaceStateAddressRaw = ptrOffset(kernelImp->getSurfaceStateHeapData(), argInfo.bindful);
auto surfaceStateAddress = reinterpret_cast<RENDER_SURFACE_STATE *>(const_cast<unsigned char *>(surfaceStateAddressRaw));
SurfaceStateBufferLength length = {0};
length.length = static_cast<uint32_t>((gpuAlloc->getUnderlyingBufferSize() - offset) - 1);
const auto totalOffset = offset + devicePtrOffsetInAlloc;
length.length = static_cast<uint32_t>((gpuAlloc->getUnderlyingBufferSize() - totalOffset) - 1);
EXPECT_EQ(surfaceStateAddress->getWidth(), static_cast<uint32_t>(length.surfaceState.width + 1));
EXPECT_EQ(surfaceStateAddress->getHeight(), static_cast<uint32_t>(length.surfaceState.height + 1));
EXPECT_EQ(surfaceStateAddress->getDepth(), static_cast<uint32_t>(length.surfaceState.depth + 1));