feature: Add support for host IPC allocations

Add support for importing and exporting host allocations.

Related-To: LOCI-3771

Signed-off-by: Jaime Arteaga <jaime.a.arteaga.molina@intel.com>
This commit is contained in:
Jaime Arteaga
2023-01-04 08:36:12 +00:00
committed by Compute-Runtime-Automation
parent 98b60ba148
commit dcea913fbc
6 changed files with 268 additions and 4 deletions

View File

@@ -84,6 +84,37 @@ ze_result_t ContextImp::allocHostMem(const ze_host_mem_alloc_desc_t *hostDesc,
return ZE_RESULT_ERROR_UNSUPPORTED_SIZE;
}
StructuresLookupTable lookupTable = {};
lookupTable.relaxedSizeAllowed = NEO::DebugManager.flags.AllowUnrestrictedSize.get();
auto parseResult = prepareL0StructuresLookupTable(lookupTable, hostDesc->pNext);
if (parseResult != ZE_RESULT_SUCCESS) {
return parseResult;
}
if (lookupTable.isSharedHandle) {
if (lookupTable.sharedHandleType.isDMABUFHandle) {
ze_ipc_memory_flags_t flags = {};
*ptr = getMemHandlePtr(this->devices.begin()->second,
lookupTable.sharedHandleType.fd,
NEO::AllocationType::BUFFER_HOST_MEMORY,
flags);
if (nullptr == *ptr) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
} else {
UNRECOVERABLE_IF(!lookupTable.sharedHandleType.isNTHandle);
*ptr = this->driverHandle->importNTHandle(this->devices.begin()->second,
lookupTable.sharedHandleType.ntHnadle,
NEO::AllocationType::BUFFER_HOST_MEMORY);
if (*ptr == nullptr) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
}
return ZE_RESULT_SUCCESS;
}
NEO::SVMAllocsManager::UnifiedMemoryProperties unifiedMemoryProperties(InternalMemoryType::HOST_UNIFIED_MEMORY,
this->rootDeviceIndices,
this->deviceBitfields);
@@ -625,7 +656,7 @@ ze_result_t ContextImp::handleAllocationExtensions(NEO::GraphicsAllocation *allo
if (extendedMemoryExportProperties->flags & ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_FD) {
return ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}
if (type != ZE_MEMORY_TYPE_DEVICE) {
if (type == ZE_MEMORY_TYPE_SHARED) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
uint64_t handle = 0;

View File

@@ -67,6 +67,18 @@ struct ContextFdMock : public L0::ContextImp {
return res;
}
ze_result_t allocHostMem(const ze_host_mem_alloc_desc_t *hostDesc,
size_t size,
size_t alignment, void **ptr) override {
ze_result_t res = L0::ContextImp::allocHostMem(hostDesc, size, alignment, ptr);
if (ZE_RESULT_SUCCESS == res) {
driverHandle->allocationMap.first = *ptr;
driverHandle->allocationMap.second = driverHandle->mockFd;
}
return res;
}
ze_result_t getMemAllocProperties(const void *ptr,
ze_memory_allocation_properties_t *pMemAllocProperties,
ze_device_handle_t *phDevice) override {

View File

@@ -235,6 +235,31 @@ HWTEST_F(ImportNTHandle, givenNTHandleWhenCreatingDeviceMemoryThenSuccessIsRetur
EXPECT_EQ(result, ZE_RESULT_SUCCESS);
}
HWTEST_F(ImportNTHandle, givenNTHandleWhenCreatingHostMemoryThenSuccessIsReturned) {
ze_host_mem_alloc_desc_t hostDesc = {};
hostDesc.stype = ZE_STRUCTURE_TYPE_HOST_MEM_ALLOC_DESC;
uint64_t imageHandle = 0x1;
ze_external_memory_import_win32_handle_t importNTHandle = {};
importNTHandle.handle = &imageHandle;
importNTHandle.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32;
importNTHandle.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_WIN32;
hostDesc.pNext = &importNTHandle;
delete driverHandle->svmAllocsManager;
execEnv->memoryManager.reset(new MemoryManagerNTHandleMock(*execEnv));
driverHandle->setMemoryManager(execEnv->memoryManager.get());
driverHandle->svmAllocsManager = new NEO::SVMAllocsManager(execEnv->memoryManager.get(), false);
void *ptr = nullptr;
auto result = context->allocHostMem(&hostDesc, 100, 1, &ptr);
EXPECT_EQ(result, ZE_RESULT_SUCCESS);
auto alloc = driverHandle->getSvmAllocsManager()->getSVMAlloc(ptr);
ASSERT_EQ(alloc->gpuAllocations.getGraphicsAllocation(device->getRootDeviceIndex())->peekSharedHandle(), NEO::toOsHandle(importNTHandle.handle));
result = context->freeMem(ptr);
EXPECT_EQ(result, ZE_RESULT_SUCCESS);
}
HWTEST_F(ImportNTHandle, whenCallingCreateGraphicsAllocationFromMultipleSharedHandlesFromOsAgnosticMemoryManagerThenNullptrIsReturned) {
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
@@ -277,6 +302,24 @@ HWTEST_F(ImportNTHandle, givenNotExistingNTHandleWhenCreatingDeviceMemoryThenErr
EXPECT_EQ(result, ZE_RESULT_ERROR_INVALID_ARGUMENT);
}
HWTEST_F(ImportNTHandle, givenNotExistingNTHandleWhenCreatingHostMemoryThenErrorIsReturned) {
using RENDER_SURFACE_STATE = typename FamilyType::RENDER_SURFACE_STATE;
ze_host_mem_alloc_desc_t hostDesc = {};
hostDesc.stype = ZE_STRUCTURE_TYPE_HOST_MEM_ALLOC_DESC;
ze_external_memory_import_win32_handle_t importNTHandle = {};
importNTHandle.handle = reinterpret_cast<void *>(invalidHandle);
importNTHandle.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_WIN32;
importNTHandle.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_WIN32;
hostDesc.pNext = &importNTHandle;
void *ptr = nullptr;
auto result = context->allocHostMem(&hostDesc, 100, 1, &ptr);
EXPECT_EQ(result, ZE_RESULT_ERROR_INVALID_ARGUMENT);
}
TEST(DriverTestFamilySupport, whenInitializingDriverOnSupportedFamilyThenDriverIsCreated) {
ze_result_t returnValue;

View File

@@ -2328,7 +2328,39 @@ TEST_F(MemoryExportImportTest,
}
TEST_F(MemoryExportImportTest,
givenCallToMemAllocPropertiesWithExtendedExportPropertiesForNonDeviceAllocationThenUnsupportedFeatureIsReturned) {
givenCallToMemAllocPropertiesWithExtendedExportPropertiesForSharedAllocationThenUnsupportedFeatureIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_host_mem_alloc_desc_t hostDesc = {};
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocSharedMem(device->toHandle(),
&deviceDesc,
&hostDesc,
size,
alignment,
&ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_memory_allocation_properties_t memoryProperties = {};
ze_external_memory_export_fd_t extendedProperties = {};
extendedProperties.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD;
extendedProperties.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
extendedProperties.fd = std::numeric_limits<int>::max();
memoryProperties.pNext = &extendedProperties;
result = context->getMemAllocProperties(ptr, &memoryProperties, nullptr);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
EXPECT_EQ(extendedProperties.fd, std::numeric_limits<int>::max());
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryExportImportTest,
givenCallToMemAllocPropertiesWithExtendedExportPropertiesForHostAllocationThenSuccessIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
@@ -2346,8 +2378,8 @@ TEST_F(MemoryExportImportTest,
memoryProperties.pNext = &extendedProperties;
result = context->getMemAllocProperties(ptr, &memoryProperties, nullptr);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result);
EXPECT_EQ(extendedProperties.fd, std::numeric_limits<int>::max());
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(extendedProperties.fd, 57);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);

View File

@@ -288,5 +288,55 @@ TEST_F(MemoryExportImportTest,
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryExportImportTest,
givenCallToHostAllocWithExtendedImportDescriptorAndSupportedFlagThenSuccessIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_host_mem_alloc_desc_t hostDesc = {};
ze_external_memory_export_desc_t extendedDesc = {};
extendedDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC;
extendedDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
hostDesc.pNext = &extendedDesc;
ze_result_t result = context->allocHostMem(&hostDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_memory_allocation_properties_t memoryProperties = {};
ze_external_memory_export_fd_t extendedProperties = {};
extendedProperties.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD;
extendedProperties.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
extendedProperties.fd = std::numeric_limits<int>::max();
memoryProperties.pNext = &extendedProperties;
result = context->getMemAllocProperties(ptr, &memoryProperties, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(memoryProperties.type, ZE_MEMORY_TYPE_HOST);
EXPECT_NE(extendedProperties.fd, std::numeric_limits<int>::max());
EXPECT_EQ(extendedProperties.fd, driverHandle->mockFd);
ze_host_mem_alloc_desc_t importHostDesc = {};
ze_external_memory_import_fd_t extendedImportDesc = {};
extendedImportDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD;
extendedImportDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
extendedImportDesc.fd = extendedProperties.fd;
importHostDesc.pNext = &extendedImportDesc;
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<NEO::MockDriverModelDRM>());
void *importedPtr = nullptr;
result = context->allocHostMem(&importHostDesc,
size, alignment, &importedPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(driverHandle->allocationTypeRequested, NEO::AllocationType::BUFFER_HOST_MEMORY);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
} // namespace ult
} // namespace L0

View File

@@ -306,6 +306,102 @@ TEST_F(MemoryExportImportTest,
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryExportImportTest,
givenCallToHostAllocWithExtendedImportDescriptorAndSupportedFlagThenSuccessIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_host_mem_alloc_desc_t hostDesc = {};
ze_external_memory_export_desc_t extendedDesc = {};
extendedDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC;
extendedDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
hostDesc.pNext = &extendedDesc;
ze_result_t result = context->allocHostMem(&hostDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_memory_allocation_properties_t memoryProperties = {};
ze_external_memory_export_fd_t extendedProperties = {};
extendedProperties.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD;
extendedProperties.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
extendedProperties.fd = std::numeric_limits<int>::max();
memoryProperties.pNext = &extendedProperties;
result = context->getMemAllocProperties(ptr, &memoryProperties, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(memoryProperties.type, ZE_MEMORY_TYPE_HOST);
EXPECT_NE(extendedProperties.fd, std::numeric_limits<int>::max());
EXPECT_EQ(extendedProperties.fd, driverHandle->mockFd);
ze_host_mem_alloc_desc_t importHostDesc = {};
ze_external_memory_import_fd_t extendedImportDesc = {};
extendedImportDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD;
extendedImportDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
extendedImportDesc.fd = extendedProperties.fd;
importHostDesc.pNext = &extendedImportDesc;
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<NEO::MockDriverModelDRM>());
void *importedPtr = nullptr;
result = context->allocHostMem(&importHostDesc,
size, alignment, &importedPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryExportImportTest,
givenCallToHostAllocWithExtendedImportDescriptorAndWDDMDriverTypeThenFailureIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_host_mem_alloc_desc_t hostDesc = {};
ze_external_memory_export_desc_t extendedDesc = {};
extendedDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_DESC;
extendedDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
hostDesc.pNext = &extendedDesc;
ze_result_t result = context->allocHostMem(&hostDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_memory_allocation_properties_t memoryProperties = {};
ze_external_memory_export_fd_t extendedProperties = {};
extendedProperties.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD;
extendedProperties.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
extendedProperties.fd = std::numeric_limits<int>::max();
memoryProperties.pNext = &extendedProperties;
result = context->getMemAllocProperties(ptr, &memoryProperties, nullptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(memoryProperties.type, ZE_MEMORY_TYPE_HOST);
EXPECT_NE(extendedProperties.fd, std::numeric_limits<int>::max());
EXPECT_EQ(extendedProperties.fd, driverHandle->mockFd);
ze_host_mem_alloc_desc_t importHostDesc = {};
ze_external_memory_import_fd_t extendedImportDesc = {};
extendedImportDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD;
extendedImportDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_DMA_BUF;
extendedImportDesc.fd = extendedProperties.fd;
importHostDesc.pNext = &extendedImportDesc;
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<NEO::MockDriverModelWDDM>());
void *importedPtr = nullptr;
result = context->allocHostMem(&importHostDesc,
size, alignment, &importedPtr);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryExportImportTest,
givenCallToDeviceAllocWithExtendedImportDescriptorAndWDDMDriverTypeThenFailureIsReturned) {
size_t size = 10;