Convert FD to NT Handle for Import/Export of Memory

- In WSL the handle for DMA buf is an NT handle.
- To share and import this memory we check if the
handle is an NT handle before attempting to
load as an FD.
- If the handle is and NT handle, then we open the fd
as an NT handle.

Signed-off-by: Spruit, Neil R <neil.r.spruit@intel.com>
This commit is contained in:
Spruit, Neil R
2022-02-04 19:58:35 +00:00
committed by Compute-Runtime-Automation
parent 93e117fa9e
commit 8986435bd7
8 changed files with 543 additions and 274 deletions

View File

@@ -128,7 +128,7 @@ ze_result_t ContextImp::allocDeviceMem(ze_device_handle_t hDevice,
if (lookupTable.isSharedHandle) {
if (lookupTable.sharedHandleType.isDMABUFHandle) {
ze_ipc_memory_flags_t flags = {};
*ptr = this->driverHandle->importFdHandle(hDevice, flags, lookupTable.sharedHandleType.fd, nullptr);
*ptr = getMemHandlePtr(hDevice, lookupTable.sharedHandleType.fd, flags);
if (nullptr == *ptr) {
return ZE_RESULT_ERROR_INVALID_ARGUMENT;
}

View File

@@ -109,6 +109,101 @@ struct MemoryExportImportTest : public ::testing::Test {
std::unique_ptr<ContextFdMock> context;
};
struct DriverHandleGetMemHandleMock : public L0::DriverHandleImp {
void *importNTHandle(ze_device_handle_t hDevice, void *handle) override {
if (mockHandle == allocationHandleMap.second) {
return allocationHandleMap.first;
}
return nullptr;
}
void *importFdHandle(ze_device_handle_t hDevice, ze_ipc_memory_flags_t flags, uint64_t handle, NEO::GraphicsAllocation **pAloc) override {
if (mockFd == allocationFdMap.second) {
return allocationFdMap.first;
}
return nullptr;
}
const int mockFd = 57;
std::pair<void *, int> allocationFdMap;
uint64_t mockHandle = 57;
std::pair<void *, uint64_t> allocationHandleMap;
};
struct ContextMemHandleMock : public L0::ContextImp {
ContextMemHandleMock(DriverHandleGetMemHandleMock *inDriverHandle) : L0::ContextImp(static_cast<L0::DriverHandle *>(inDriverHandle)) {
driverHandle = inDriverHandle;
}
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 = L0::ContextImp::allocDeviceMem(hDevice, deviceDesc, size, alignment, ptr);
if (ZE_RESULT_SUCCESS == res) {
driverHandle->allocationFdMap.first = *ptr;
driverHandle->allocationFdMap.second = driverHandle->mockFd;
driverHandle->allocationHandleMap.first = *ptr;
driverHandle->allocationHandleMap.second = driverHandle->mockHandle;
}
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 = ContextImp::getMemAllocProperties(ptr, pMemAllocProperties, phDevice);
if (ZE_RESULT_SUCCESS == res && pMemAllocProperties->pNext) {
ze_external_memory_export_fd_t *extendedMemoryExportProperties =
reinterpret_cast<ze_external_memory_export_fd_t *>(pMemAllocProperties->pNext);
extendedMemoryExportProperties->fd = driverHandle->mockFd;
}
return res;
}
ze_result_t closeIpcMemHandle(const void *ptr) override {
return ZE_RESULT_SUCCESS;
}
DriverHandleGetMemHandleMock *driverHandle = nullptr;
};
struct MemoryExportImportWSLTest : 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<DriverHandleGetMemHandleMock>();
prevMemoryManager = driverHandle->getMemoryManager();
currMemoryManager = new MemoryManagerMemHandleMock();
driverHandle->setMemoryManager(currMemoryManager);
driverHandle->initialize(std::move(devices));
device = driverHandle->devices[0];
context = std::make_unique<ContextMemHandleMock>(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->setMemoryManager(prevMemoryManager);
delete currMemoryManager;
}
std::unique_ptr<DriverHandleGetMemHandleMock> driverHandle;
NEO::MockDevice *neoDevice = nullptr;
L0::Device *device = nullptr;
ze_context_handle_t hContext;
std::unique_ptr<ContextMemHandleMock> context;
NEO::MemoryManager *prevMemoryManager = nullptr;
MemoryManagerMemHandleMock *currMemoryManager = nullptr;
};
struct DriverHandleGetWinHandleMock : public L0::DriverHandleImp {
void *importNTHandle(ze_device_handle_t hDevice, void *handle) override {
if (mockHandle == allocationMap.second) {

View File

@@ -7,5 +7,5 @@
target_sources(${TARGET_NAME} PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt
${CMAKE_CURRENT_SOURCE_DIR}/test_memory.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_memory_${DRIVER_MODEL}/test_memory_ipc.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test_memory_${DRIVER_MODEL}/test_memory.cpp
)

View File

@@ -1388,55 +1388,6 @@ TEST_F(MemoryExportImportTest,
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 = context->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 = context->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 = context->allocDeviceMem(device->toHandle(),
&importDeviceDesc,
size, alignment, &importedPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryExportImportWinHandleTest,
givenCallToDeviceAllocWithExtendedExportDescriptorAndNTHandleFlagThenAllocationIsMade) {
size_t size = 10;

View File

@@ -231,5 +231,57 @@ TEST_F(MemoryOpenIpcHandleTest,
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 = context->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 = context->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;
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<MockDriverModelDRM>(512));
void *importedPtr = nullptr;
result = context->allocDeviceMem(device->toHandle(),
&importDeviceDesc,
size, alignment, &importedPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
} // namespace ult
} // namespace L0

View File

@@ -1,223 +0,0 @@
/*
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/core/test/unit_tests/fixtures/memory_ipc_fixture.h"
namespace L0 {
namespace ult {
using MemoryIPCTests = MemoryExportImportTest;
TEST_F(MemoryIPCTests,
givenCallToGetIpcHandleWithNotKnownPointerThenInvalidArgumentIsReturned) {
uint32_t value = 0;
ze_ipc_mem_handle_t ipcHandle;
ze_result_t result = context->getIpcMemHandle(&value, &ipcHandle);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
}
TEST_F(MemoryIPCTests,
givenCallToGetIpcHandleWithDeviceAllocationThenIpcHandleIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle;
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryIPCTests,
whenCallingOpenIpcHandleWithIpcHandleThenDeviceAllocationIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle = {};
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
ze_ipc_memory_flags_t flags = {};
void *ipcPtr;
result = context->openIpcMemHandle(device->toHandle(), ipcHandle, flags, &ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(ipcPtr, ptr);
result = context->closeIpcMemHandle(ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryIPCTests,
whenCallingOpenIpcHandleWithIpcHandleAndUsingContextThenDeviceAllocationIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle = {};
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
ze_ipc_memory_flags_t flags = {};
void *ipcPtr;
result = context->openIpcMemHandle(device->toHandle(), ipcHandle, flags, &ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(ipcPtr, ptr);
result = context->closeIpcMemHandle(ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryIPCTests,
givenCallingGetIpcHandleWithDeviceAllocationAndUsingContextThenIpcHandleIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle;
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryIPCTests,
whenCallingOpenIpcHandleWithIncorrectHandleThenInvalidArgumentIsReturned) {
ze_ipc_mem_handle_t ipcHandle = {};
ze_ipc_memory_flags_t flags = {};
void *ipcPtr;
ze_result_t res = context->openIpcMemHandle(device->toHandle(), ipcHandle, flags, &ipcPtr);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, res);
}
struct MemoryGetIpcHandleTest : 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<DriverHandleGetIpcHandleMock>();
driverHandle->initialize(std::move(devices));
device = driverHandle->devices[0];
context = std::make_unique<ContextGetIpcHandleMock>(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 {
}
std::unique_ptr<DriverHandleGetIpcHandleMock> driverHandle;
NEO::MockDevice *neoDevice = nullptr;
L0::Device *device = nullptr;
std::unique_ptr<ContextGetIpcHandleMock> context;
};
TEST_F(MemoryGetIpcHandleTest,
whenCallingOpenIpcHandleWithIpcHandleThenFdHandleIsCorrectlyRead) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle = {};
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
ze_ipc_memory_flags_t flags = {};
void *ipcPtr;
result = context->openIpcMemHandle(device->toHandle(), ipcHandle, flags, &ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(ipcPtr, ptr);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryOpenIpcHandleTest,
givenCallToOpenIpcMemHandleItIsSuccessfullyOpenedAndClosed) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle = {};
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
ze_ipc_memory_flags_t flags = {};
void *ipcPtr;
result = context->openIpcMemHandle(device->toHandle(), ipcHandle, flags, &ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(ipcPtr, nullptr);
result = context->closeIpcMemHandle(ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
} // namespace ult
} // namespace L0

View File

@@ -0,0 +1,394 @@
/*
* Copyright (C) 2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
*/
#include "level_zero/core/test/unit_tests/fixtures/memory_ipc_fixture.h"
namespace L0 {
namespace ult {
using MemoryIPCTests = MemoryExportImportTest;
TEST_F(MemoryIPCTests,
givenCallToGetIpcHandleWithNotKnownPointerThenInvalidArgumentIsReturned) {
uint32_t value = 0;
ze_ipc_mem_handle_t ipcHandle;
ze_result_t result = context->getIpcMemHandle(&value, &ipcHandle);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
}
TEST_F(MemoryIPCTests,
givenCallToGetIpcHandleWithDeviceAllocationThenIpcHandleIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle;
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryIPCTests,
whenCallingOpenIpcHandleWithIpcHandleThenDeviceAllocationIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle = {};
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<MockDriverModelDRM>(512));
ze_ipc_memory_flags_t flags = {};
void *ipcPtr;
result = context->openIpcMemHandle(device->toHandle(), ipcHandle, flags, &ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(ipcPtr, ptr);
result = context->closeIpcMemHandle(ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryIPCTests,
whenCallingOpenIpcHandleWithIpcHandleAndUsingContextThenDeviceAllocationIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle = {};
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<MockDriverModelDRM>(512));
ze_ipc_memory_flags_t flags = {};
void *ipcPtr;
result = context->openIpcMemHandle(device->toHandle(), ipcHandle, flags, &ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(ipcPtr, ptr);
result = context->closeIpcMemHandle(ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryIPCTests,
givenCallingGetIpcHandleWithDeviceAllocationAndUsingContextThenIpcHandleIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle;
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryIPCTests,
whenCallingOpenIpcHandleWithIncorrectHandleThenInvalidArgumentIsReturned) {
ze_ipc_mem_handle_t ipcHandle = {};
ze_ipc_memory_flags_t flags = {};
void *ipcPtr;
ze_result_t res = context->openIpcMemHandle(device->toHandle(), ipcHandle, flags, &ipcPtr);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, res);
}
struct MemoryGetIpcHandleTest : 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<DriverHandleGetIpcHandleMock>();
driverHandle->initialize(std::move(devices));
device = driverHandle->devices[0];
context = std::make_unique<ContextGetIpcHandleMock>(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 {
}
std::unique_ptr<DriverHandleGetIpcHandleMock> driverHandle;
NEO::MockDevice *neoDevice = nullptr;
L0::Device *device = nullptr;
std::unique_ptr<ContextGetIpcHandleMock> context;
};
TEST_F(MemoryGetIpcHandleTest,
whenCallingOpenIpcHandleWithIpcHandleThenFdHandleIsCorrectlyRead) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle = {};
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<MockDriverModelDRM>(512));
ze_ipc_memory_flags_t flags = {};
void *ipcPtr;
result = context->openIpcMemHandle(device->toHandle(), ipcHandle, flags, &ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_EQ(ipcPtr, ptr);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryOpenIpcHandleTest,
givenCallToOpenIpcMemHandleItIsSuccessfullyOpenedAndClosed) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
ze_device_mem_alloc_desc_t deviceDesc = {};
ze_result_t result = context->allocDeviceMem(device->toHandle(),
&deviceDesc,
size, alignment, &ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(nullptr, ptr);
ze_ipc_mem_handle_t ipcHandle = {};
result = context->getIpcMemHandle(ptr, &ipcHandle);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<MockDriverModelDRM>(512));
ze_ipc_memory_flags_t flags = {};
void *ipcPtr;
result = context->openIpcMemHandle(device->toHandle(), ipcHandle, flags, &ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
EXPECT_NE(ipcPtr, nullptr);
result = context->closeIpcMemHandle(ipcPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->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 = context->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 = context->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;
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<MockDriverModelDRM>(512));
void *importedPtr = nullptr;
result = context->allocDeviceMem(device->toHandle(),
&importDeviceDesc,
size, alignment, &importedPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryExportImportTest,
givenCallToDeviceAllocWithExtendedImportDescriptorAndWDDMDriverTypeThenFailureIsReturned) {
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 = context->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 = context->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;
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<MockDriverModelWDDM>(512));
void *importedPtr = nullptr;
result = context->allocDeviceMem(device->toHandle(),
&importDeviceDesc,
size, alignment, &importedPtr);
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
TEST_F(MemoryExportImportWSLTest,
givenCallToDeviceAllocWithExtendedImportDescriptorAndNTHandleWithWDDMThenSuccessIsReturned) {
size_t size = 10;
size_t alignment = 1u;
void *ptr = nullptr;
MemoryManagerMemHandleMock *fixtureMemoryManager = static_cast<MemoryManagerMemHandleMock *>(currMemoryManager);
fixtureMemoryManager->NTHandle = true;
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 = context->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 = context->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;
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<MockDriverModelWDDM>(512));
void *importedPtr = nullptr;
result = context->allocDeviceMem(device->toHandle(),
&importDeviceDesc,
size, alignment, &importedPtr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
result = context->freeMem(ptr);
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
}
} // namespace ult
} // namespace L0