From 97437830a7a737b32ff80be1e9463ca78341a0ef Mon Sep 17 00:00:00 2001 From: Jaime Arteaga Date: Sun, 15 Nov 2020 23:11:23 +0000 Subject: [PATCH] Add support for exporting memory handles through getAllocProperties Add support for passing ze_external_memory_export_fd_t extended structure to zeMemGetAllocProperties() to retrieve an fd handle for a device allocation. Signed-off-by: Jaime Arteaga --- .../core/source/driver/driver_handle_imp.cpp | 46 ++++-- .../unit_tests/sources/memory/test_memory.cpp | 141 +++++++++++++++++- 2 files changed, 171 insertions(+), 16 deletions(-) diff --git a/level_zero/core/source/driver/driver_handle_imp.cpp b/level_zero/core/source/driver/driver_handle_imp.cpp index 7cff679051..fcb645b857 100644 --- a/level_zero/core/source/driver/driver_handle_imp.cpp +++ b/level_zero/core/source/driver/driver_handle_imp.cpp @@ -115,22 +115,40 @@ ze_result_t DriverHandleImp::getMemAllocProperties(const void *ptr, ze_memory_allocation_properties_t *pMemAllocProperties, ze_device_handle_t *phDevice) { auto alloc = svmAllocsManager->getSVMAlloc(ptr); - if (alloc) { - pMemAllocProperties->type = parseUSMType(alloc->memoryType); - pMemAllocProperties->id = alloc->gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress(); - - if (phDevice != nullptr) { - if (alloc->device == nullptr) { - *phDevice = nullptr; - } else { - auto device = static_cast(alloc->device)->getSpecializedDevice(); - DEBUG_BREAK_IF(device == nullptr); - *phDevice = device->toHandle(); - } - } + if (nullptr == alloc) { + pMemAllocProperties->type = ZE_MEMORY_TYPE_UNKNOWN; return ZE_RESULT_SUCCESS; } - pMemAllocProperties->type = ZE_MEMORY_TYPE_UNKNOWN; + + pMemAllocProperties->type = parseUSMType(alloc->memoryType); + pMemAllocProperties->id = alloc->gpuAllocations.getDefaultGraphicsAllocation()->getGpuAddress(); + + if (phDevice != nullptr) { + if (alloc->device == nullptr) { + *phDevice = nullptr; + } else { + auto device = static_cast(alloc->device)->getSpecializedDevice(); + DEBUG_BREAK_IF(device == nullptr); + *phDevice = device->toHandle(); + } + } + + if (pMemAllocProperties->pNext) { + ze_base_properties_t *extendedProperties = + reinterpret_cast(pMemAllocProperties->pNext); + if (extendedProperties->stype == ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_EXPORT_FD) { + ze_external_memory_export_fd_t *extendedMemoryExportProperties = + reinterpret_cast(extendedProperties); + if (extendedMemoryExportProperties->flags & ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_FD) { + return ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION; + } + if (pMemAllocProperties->type != ZE_MEMORY_TYPE_DEVICE) { + return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE; + } + uint64_t handle = alloc->gpuAllocations.getDefaultGraphicsAllocation()->peekInternalHandle(this->getMemoryManager()); + extendedMemoryExportProperties->fd = static_cast(handle); + } + } return ZE_RESULT_SUCCESS; } diff --git a/level_zero/core/test/unit_tests/sources/memory/test_memory.cpp b/level_zero/core/test/unit_tests/sources/memory/test_memory.cpp index 32096f0618..f24b65b403 100644 --- a/level_zero/core/test/unit_tests/sources/memory/test_memory.cpp +++ b/level_zero/core/test/unit_tests/sources/memory/test_memory.cpp @@ -42,7 +42,56 @@ TEST_F(MemoryTest, givenDevicePointerThenDriverGetAllocPropertiesReturnsDeviceHa ASSERT_EQ(result, ZE_RESULT_SUCCESS); } -TEST_F(MemoryTest, givenCallToDeviceAllocWithExtendedDescriptorAndNonSupportedFlagThenUnsuportedEnumerationIsReturned) { +struct DriverHandleGetFdMock : public DriverHandleImp { + ze_result_t allocDeviceMem(ze_device_handle_t hDevice, const ze_device_mem_alloc_desc_t *deviceDesc, size_t size, + size_t alignment, void **ptr) override { + ze_result_t res = DriverHandleImp::allocDeviceMem(hDevice, deviceDesc, size, alignment, ptr); + if (ZE_RESULT_SUCCESS == res) { + allocationMap.first = ptr; + allocationMap.second = mockFd; + } + + return res; + } + + ze_result_t getMemAllocProperties(const void *ptr, + ze_memory_allocation_properties_t *pMemAllocProperties, + ze_device_handle_t *phDevice) override { + ze_result_t res = DriverHandleImp::getMemAllocProperties(ptr, pMemAllocProperties, phDevice); + if (ZE_RESULT_SUCCESS == res && pMemAllocProperties->pNext) { + ze_external_memory_export_fd_t *extendedMemoryExportProperties = + reinterpret_cast(pMemAllocProperties->pNext); + extendedMemoryExportProperties->fd = mockFd; + } + + return res; + } + + const int mockFd = 57; + std::pair allocationMap; +}; + +struct MemoryExportImportTest : public ::testing::Test { + void SetUp() override { + neoDevice = NEO::MockDevice::createWithNewExecutionEnvironment(NEO::defaultHwInfo.get()); + auto mockBuiltIns = new MockBuiltins(); + neoDevice->executionEnvironment->rootDeviceEnvironments[0]->builtins.reset(mockBuiltIns); + NEO::DeviceVector devices; + devices.push_back(std::unique_ptr(neoDevice)); + driverHandle = std::make_unique(); + driverHandle->initialize(std::move(devices)); + device = driverHandle->devices[0]; + } + + void TearDown() override { + } + std::unique_ptr driverHandle; + NEO::MockDevice *neoDevice = nullptr; + L0::Device *device = nullptr; +}; + +TEST_F(MemoryExportImportTest, + givenCallToDeviceAllocWithExtendedExportDescriptorAndNonSupportedFlagThenUnsuportedEnumerationIsReturned) { size_t size = 10; size_t alignment = 1u; void *ptr = nullptr; @@ -59,7 +108,8 @@ TEST_F(MemoryTest, givenCallToDeviceAllocWithExtendedDescriptorAndNonSupportedFl EXPECT_EQ(nullptr, ptr); } -TEST_F(MemoryTest, givenCallToDeviceAllocWithExtendedDescriptorAndSupportedFlagThenAllocationIsMade) { +TEST_F(MemoryExportImportTest, + givenCallToDeviceAllocWithExtendedExportDescriptorAndSupportedFlagThenAllocationIsMade) { size_t size = 10; size_t alignment = 1u; void *ptr = nullptr; @@ -79,6 +129,93 @@ TEST_F(MemoryTest, givenCallToDeviceAllocWithExtendedDescriptorAndSupportedFlagT EXPECT_EQ(ZE_RESULT_SUCCESS, result); } +TEST_F(MemoryExportImportTest, + givenCallToMemAllocPropertiesWithExtendedExportPropertiesAndUnsupportedFlagThenUnsupportedEnumerationIsReturned) { + size_t size = 10; + size_t alignment = 1u; + void *ptr = nullptr; + + ze_device_mem_alloc_desc_t deviceDesc = {}; + ze_result_t result = driverHandle->allocDeviceMem(device->toHandle(), + &deviceDesc, + 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_OPAQUE_FD; + extendedProperties.fd = std::numeric_limits::max(); + memoryProperties.pNext = &extendedProperties; + + ze_device_handle_t deviceHandle; + result = driverHandle->getMemAllocProperties(ptr, &memoryProperties, &deviceHandle); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION, result); + EXPECT_EQ(extendedProperties.fd, std::numeric_limits::max()); + + result = driverHandle->freeMem(ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); +} + +TEST_F(MemoryExportImportTest, + givenCallToMemAllocPropertiesWithExtendedExportPropertiesForNonDeviceAllocationThenUnsupportedFeatureIsReturned) { + size_t size = 10; + size_t alignment = 1u; + void *ptr = nullptr; + + ze_host_mem_alloc_desc_t hostDesc = {}; + ze_result_t result = driverHandle->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::max(); + memoryProperties.pNext = &extendedProperties; + + result = driverHandle->getMemAllocProperties(ptr, &memoryProperties, nullptr); + EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_FEATURE, result); + EXPECT_EQ(extendedProperties.fd, std::numeric_limits::max()); + + result = driverHandle->freeMem(ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); +} + +TEST_F(MemoryExportImportTest, + givenCallToMemAllocPropertiesWithExtendedExportPropertiesAndSupportedFlagThenValidFileDescriptorIsReturned) { + size_t size = 10; + size_t alignment = 1u; + void *ptr = nullptr; + + ze_device_mem_alloc_desc_t deviceDesc = {}; + ze_result_t result = driverHandle->allocDeviceMem(device->toHandle(), + &deviceDesc, + 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::max(); + memoryProperties.pNext = &extendedProperties; + + ze_device_handle_t deviceHandle; + result = driverHandle->getMemAllocProperties(ptr, &memoryProperties, &deviceHandle); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); + EXPECT_EQ(memoryProperties.type, ZE_MEMORY_TYPE_DEVICE); + EXPECT_EQ(deviceHandle, device->toHandle()); + EXPECT_NE(extendedProperties.fd, std::numeric_limits::max()); + EXPECT_EQ(extendedProperties.fd, driverHandle->mockFd); + + result = driverHandle->freeMem(ptr); + EXPECT_EQ(ZE_RESULT_SUCCESS, result); +} + using DeviceMemorySizeTest = Test; TEST_F(DeviceMemorySizeTest, givenSizeGreaterThanLimitThenDeviceAllocationFails) {