Add support for importing memory handles through zeMemAllocDevice

Add support for passing ze_external_memory_import_fd_t extended
structure to zeMemAllocDevice() to allocate a device memory
out of an fd handle.

Signed-off-by: Jaime Arteaga <jaime.a.arteaga.molina@intel.com>
This commit is contained in:
Jaime Arteaga
2020-11-16 01:43:20 +00:00
committed by Compute-Runtime-Automation
parent 3e69b2084c
commit 4432547ff5
3 changed files with 133 additions and 6 deletions

View File

@@ -44,6 +44,7 @@ struct DriverHandleImp : public DriverHandle {
ze_result_t freeMem(const void *ptr) override;
NEO::MemoryManager *getMemoryManager() override;
void setMemoryManager(NEO::MemoryManager *memoryManager) override;
MOCKABLE_VIRTUAL void *importFdHandle(ze_device_handle_t hDevice, uint64_t handle);
ze_result_t closeIpcMemHandle(const void *ptr) override;
ze_result_t getIpcMemHandle(const void *ptr, ze_ipc_mem_handle_t *pIpcHandle) override;
ze_result_t openIpcMemHandle(ze_device_handle_t hDevice, ze_ipc_mem_handle_t handle,

View File

@@ -27,21 +27,20 @@ ze_result_t DriverHandleImp::getIpcMemHandle(const void *ptr, ze_ipc_mem_handle_
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
ze_result_t DriverHandleImp::openIpcMemHandle(ze_device_handle_t hDevice, ze_ipc_mem_handle_t pIpcHandle,
ze_ipc_memory_flag_t flags, void **ptr) {
void *DriverHandleImp::importFdHandle(ze_device_handle_t hDevice, uint64_t handle) {
auto neoDevice = Device::fromHandle(hDevice)->getNEODevice();
uint64_t handle = *(pIpcHandle.data);
NEO::osHandle osHandle = static_cast<NEO::osHandle>(handle);
NEO::AllocationProperties unifiedMemoryProperties{neoDevice->getRootDeviceIndex(),
MemoryConstants::pageSize,
NEO::GraphicsAllocation::AllocationType::BUFFER, neoDevice->getDeviceBitfield()};
NEO::GraphicsAllocation::AllocationType::BUFFER,
neoDevice->getDeviceBitfield()};
unifiedMemoryProperties.subDevicesBitfield = neoDevice->getDeviceBitfield();
NEO::GraphicsAllocation *alloc =
this->getMemoryManager()->createGraphicsAllocationFromSharedHandle(osHandle,
unifiedMemoryProperties,
false);
if (alloc == nullptr) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
return nullptr;
}
NEO::SvmAllocationData allocData(neoDevice->getRootDeviceIndex());
@@ -53,7 +52,17 @@ ze_result_t DriverHandleImp::openIpcMemHandle(ze_device_handle_t hDevice, ze_ipc
this->getSvmAllocsManager()->insertSVMAlloc(allocData);
*ptr = reinterpret_cast<void *>(alloc->getGpuAddress());
return reinterpret_cast<void *>(alloc->getGpuAddress());
}
ze_result_t DriverHandleImp::openIpcMemHandle(ze_device_handle_t hDevice, ze_ipc_mem_handle_t pIpcHandle,
ze_ipc_memory_flag_t flags, void **ptr) {
uint64_t handle = *(pIpcHandle.data);
*ptr = this->importFdHandle(hDevice, handle);
if (nullptr == *ptr) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
return ZE_RESULT_SUCCESS;
}
@@ -137,6 +146,17 @@ ze_result_t DriverHandleImp::allocDeviceMem(ze_device_handle_t hDevice, const ze
if (externalMemoryExportDesc->flags & ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_FD) {
return ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}
} else if (extendedDesc->stype == ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD) {
const ze_external_memory_import_fd_t *externalMemoryImportDesc =
reinterpret_cast<const ze_external_memory_import_fd_t *>(extendedDesc);
if (externalMemoryImportDesc->flags & ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_FD) {
return ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION;
}
*ptr = this->importFdHandle(hDevice, externalMemoryImportDesc->fd);
if (nullptr == *ptr) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}
return ZE_RESULT_SUCCESS;
}
}

View File

@@ -43,6 +43,13 @@ TEST_F(MemoryTest, givenDevicePointerThenDriverGetAllocPropertiesReturnsDeviceHa
}
struct DriverHandleGetFdMock : public DriverHandleImp {
void *importFdHandle(ze_device_handle_t hDevice, uint64_t handle) override {
if (mockFd == allocationMap.second) {
return allocationMap.first;
}
return nullptr;
}
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);
@@ -216,6 +223,105 @@ TEST_F(MemoryExportImportTest,
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryExportImportTest,
givenCallToDeviceAllocWithExtendedImportDescriptorAndNonSupportedFlagThenUnsupportedEnumerationIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
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;
deviceDesc.pNext = &extendedDesc;
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<int>::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<int>::max());
EXPECT_EQ(extendedProperties.fd, driverHandle->mockFd);
ze_device_mem_alloc_desc_t importDeviceDesc = {};
ze_external_memory_import_fd_t extendedImportDesc = {};
extendedImportDesc.stype = ZE_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMPORT_FD;
extendedImportDesc.flags = ZE_EXTERNAL_MEMORY_TYPE_FLAG_OPAQUE_FD;
extendedImportDesc.fd = extendedProperties.fd;
importDeviceDesc.pNext = &extendedImportDesc;
void *importedPtr = nullptr;
result = driverHandle->allocDeviceMem(device->toHandle(),
&importDeviceDesc,
size, alignment, &importedPtr);
EXPECT_EQ(ZE_RESULT_ERROR_UNSUPPORTED_ENUMERATION, result);
EXPECT_EQ(nullptr, importedPtr);
result = driverHandle->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryExportImportTest,
givenCallToDeviceAllocWithExtendedImportDescriptorAndSupportedFlagThenSuccessIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
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;
deviceDesc.pNext = &extendedDesc;
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<int>::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<int>::max());
EXPECT_EQ(extendedProperties.fd, driverHandle->mockFd);
ze_device_mem_alloc_desc_t importDeviceDesc = {};
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;
importDeviceDesc.pNext = &extendedImportDesc;
void *importedPtr = nullptr;
result = driverHandle->allocDeviceMem(device->toHandle(),
&importDeviceDesc,
size, alignment, &importedPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = driverHandle->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
using DeviceMemorySizeTest = Test<DeviceFixture>;
TEST_F(DeviceMemorySizeTest, givenSizeGreaterThanLimitThenDeviceAllocationFails) {