Skip to content

Commit f95644f

Browse files
fix: Fix usage of root device when opening IPC handle
- Use root device if device is implicit scaling capable Related-To: NEO-13433 Signed-off-by: Aravind Gopalakrishnan <[email protected]>
1 parent 7a0deb1 commit f95644f

File tree

4 files changed

+381
-270
lines changed

4 files changed

+381
-270
lines changed

level_zero/core/source/context/context_imp.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,12 @@ ze_result_t ContextImp::openIpcMemHandles(ze_device_handle_t hDevice,
791791

792792
handles.push_back(static_cast<NEO::osHandle>(handle));
793793
}
794-
auto neoDevice = Device::fromHandle(hDevice)->getNEODevice();
794+
795+
auto device = Device::fromHandle(hDevice);
796+
auto neoDevice = device->getNEODevice();
797+
if (device->isImplicitScalingCapable()) {
798+
neoDevice = device->getNEODevice()->getRootDevice();
799+
}
795800
NEO::SvmAllocationData allocDataInternal(neoDevice->getRootDeviceIndex());
796801
*pptr = this->driverHandle->importFdHandles(neoDevice, flags, handles, nullptr, nullptr, allocDataInternal);
797802
if (nullptr == *pptr) {

level_zero/core/test/unit_tests/fixtures/memory_ipc_fixture.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2023-2024 Intel Corporation
2+
* Copyright (C) 2023-2025 Intel Corporation
33
*
44
* SPDX-License-Identifier: MIT
55
*
@@ -507,6 +507,7 @@ NEO::GraphicsAllocation *MemoryManagerIpcImplicitScalingMock::createGraphicsAllo
507507
void MemoryExportImportImplicitScalingTest::SetUp() {
508508
DebugManagerStateRestore restorer;
509509
debugManager.flags.EnableImplicitScaling.set(1);
510+
debugManager.flags.EnableWalkerPartition.set(1);
510511

511512
neoDevice =
512513
NEO::MockDevice::createWithNewExecutionEnvironment<NEO::MockDevice>(NEO::defaultHwInfo.get());

level_zero/core/test/unit_tests/sources/memory/linux/test_memory_linux.cpp

Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,5 +702,292 @@ TEST_F(MemoryObtainFdTest,
702702
ASSERT_EQ(result, ZE_RESULT_SUCCESS);
703703
}
704704

705+
TEST_F(MemoryExportImportImplicitScalingTest,
706+
whenCallingOpenIpcHandlesWithIpcHandleThenDeviceAllocationIsReturned) {
707+
size_t size = 10;
708+
size_t alignment = 1u;
709+
void *ptr = nullptr;
710+
711+
ze_device_mem_alloc_desc_t deviceDesc = {};
712+
ze_result_t result = context->allocDeviceMem(device->toHandle(),
713+
&deviceDesc,
714+
size, alignment, &ptr);
715+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
716+
EXPECT_NE(nullptr, ptr);
717+
718+
uint32_t numIpcHandles = 0;
719+
result = context->getIpcMemHandles(ptr, &numIpcHandles, nullptr);
720+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
721+
EXPECT_EQ(numIpcHandles, 2u);
722+
723+
std::vector<ze_ipc_mem_handle_t> ipcHandles(numIpcHandles);
724+
result = context->getIpcMemHandles(ptr, &numIpcHandles, ipcHandles.data());
725+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
726+
727+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
728+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<NEO::MockDriverModelDRM>());
729+
730+
ze_ipc_memory_flags_t flags = {};
731+
void *ipcPtr;
732+
result = context->openIpcMemHandles(device->toHandle(), numIpcHandles, ipcHandles.data(), flags, &ipcPtr);
733+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
734+
735+
result = context->closeIpcMemHandle(ipcPtr);
736+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
737+
738+
result = context->freeMem(ptr);
739+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
740+
}
741+
742+
TEST_F(MemoryExportImportImplicitScalingTest,
743+
whenCallingOpenIpcHandleWithIpcHandleThenAllocationCountIsIncremented) {
744+
size_t size = 10;
745+
size_t alignment = 1u;
746+
void *ptr = nullptr;
747+
748+
ze_device_mem_alloc_desc_t deviceDesc = {};
749+
ze_result_t result = context->allocDeviceMem(device->toHandle(),
750+
&deviceDesc,
751+
size, alignment, &ptr);
752+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
753+
EXPECT_NE(nullptr, ptr);
754+
755+
uint32_t numIpcHandles = 0;
756+
result = context->getIpcMemHandles(ptr, &numIpcHandles, nullptr);
757+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
758+
auto usmManager = context->getDriverHandle()->getSvmAllocsManager();
759+
auto currentAllocationCount = usmManager->allocationsCounter.load();
760+
761+
std::vector<ze_ipc_mem_handle_t> ipcHandles(numIpcHandles);
762+
result = context->getIpcMemHandles(ptr, &numIpcHandles, ipcHandles.data());
763+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
764+
765+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
766+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<NEO::MockDriverModelDRM>());
767+
768+
ze_ipc_memory_flags_t flags = {};
769+
void *ipcPtr;
770+
771+
result = context->openIpcMemHandle(device->toHandle(), ipcHandles[0], flags, &ipcPtr);
772+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
773+
774+
auto newAllocationCount = usmManager->allocationsCounter.load();
775+
EXPECT_GT(newAllocationCount, currentAllocationCount);
776+
EXPECT_EQ(usmManager->getSVMAlloc(ipcPtr)->getAllocId(), newAllocationCount);
777+
778+
result = context->closeIpcMemHandle(ipcPtr);
779+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
780+
781+
result = context->freeMem(ptr);
782+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
783+
}
784+
785+
TEST_F(MemoryExportImportImplicitScalingTest,
786+
whenCallingOpenIpcHandleWithIpcHandleAndSharedMemoryTypeThenInvalidArgumentIsReturned) {
787+
DebugManagerStateRestore restorer;
788+
debugManager.flags.EnableImplicitScaling.set(0u);
789+
790+
size_t size = 10;
791+
size_t alignment = 1u;
792+
void *ptr = nullptr;
793+
794+
ze_device_mem_alloc_desc_t deviceDesc = {};
795+
ze_result_t result = context->allocDeviceMem(device->toHandle(),
796+
&deviceDesc,
797+
size, alignment, &ptr);
798+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
799+
EXPECT_NE(nullptr, ptr);
800+
801+
ze_ipc_mem_handle_t ipcHandle;
802+
result = context->getIpcMemHandle(ptr, &ipcHandle);
803+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
804+
805+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
806+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<NEO::MockDriverModelDRM>());
807+
808+
ze_ipc_memory_flags_t flags = {};
809+
void *ipcPtr;
810+
811+
IpcMemoryData &ipcData = *reinterpret_cast<IpcMemoryData *>(ipcHandle.data);
812+
ipcData.type = static_cast<uint8_t>(ZE_MEMORY_TYPE_SHARED);
813+
814+
result = context->openIpcMemHandle(device->toHandle(), ipcHandle, flags, &ipcPtr);
815+
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
816+
817+
result = context->freeMem(ptr);
818+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
819+
}
820+
821+
TEST_F(MemoryExportImportImplicitScalingTest,
822+
whenCallingOpenIpcHandlesWithIpcHandleAndHostTypeAllocationTheninvalidArgumentIsReturned) {
823+
size_t size = 10;
824+
size_t alignment = 1u;
825+
void *ptr = nullptr;
826+
827+
ze_host_mem_alloc_desc_t hostDesc = {};
828+
ze_result_t result = context->allocHostMem(&hostDesc,
829+
size, alignment, &ptr);
830+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
831+
EXPECT_NE(nullptr, ptr);
832+
833+
uint32_t numIpcHandles = 0;
834+
result = context->getIpcMemHandles(ptr, &numIpcHandles, nullptr);
835+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
836+
EXPECT_EQ(numIpcHandles, 2u);
837+
838+
std::vector<ze_ipc_mem_handle_t> ipcHandles(numIpcHandles);
839+
result = context->getIpcMemHandles(ptr, &numIpcHandles, ipcHandles.data());
840+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
841+
842+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
843+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<NEO::MockDriverModelDRM>());
844+
845+
ze_ipc_memory_flags_t flags = {};
846+
void *ipcPtr;
847+
result = context->openIpcMemHandles(device->toHandle(), numIpcHandles, ipcHandles.data(), flags, &ipcPtr);
848+
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
849+
850+
result = context->freeMem(ptr);
851+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
852+
}
853+
854+
TEST_F(MemoryExportImportImplicitScalingTest,
855+
whenCallingImportFdHandlesWithAllocationPointerThenAllocationIsReturned) {
856+
size_t size = 10;
857+
size_t alignment = 1u;
858+
void *ptr = nullptr;
859+
860+
ze_device_mem_alloc_desc_t deviceDesc = {};
861+
ze_result_t result = context->allocDeviceMem(device->toHandle(),
862+
&deviceDesc,
863+
size, alignment, &ptr);
864+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
865+
EXPECT_NE(nullptr, ptr);
866+
867+
uint32_t numIpcHandles = 0;
868+
result = context->getIpcMemHandles(ptr, &numIpcHandles, nullptr);
869+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
870+
EXPECT_EQ(numIpcHandles, 2u);
871+
872+
std::vector<ze_ipc_mem_handle_t> ipcHandles(numIpcHandles);
873+
result = context->getIpcMemHandles(ptr, &numIpcHandles, ipcHandles.data());
874+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
875+
876+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
877+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<NEO::MockDriverModelDRM>());
878+
879+
std::vector<NEO::osHandle> handles;
880+
for (uint32_t i = 0; i < numIpcHandles; i++) {
881+
uint64_t handle = 0;
882+
memcpy_s(&handle,
883+
sizeof(handle),
884+
reinterpret_cast<void *>(ipcHandles[i].data),
885+
sizeof(handle));
886+
handles.push_back(static_cast<NEO::osHandle>(handle));
887+
}
888+
889+
ze_ipc_memory_flags_t flags = {};
890+
void *ipcPtr;
891+
NEO::GraphicsAllocation *ipcAlloc = nullptr;
892+
DriverHandleImp *driverHandleImp = static_cast<DriverHandleImp *>(context->getDriverHandle());
893+
NEO::SvmAllocationData allocDataInternal(device->getNEODevice()->getRootDeviceIndex());
894+
ipcPtr = driverHandleImp->importFdHandles(device->getNEODevice(), flags, handles, nullptr, &ipcAlloc, allocDataInternal);
895+
EXPECT_NE(ipcPtr, nullptr);
896+
EXPECT_NE(ipcAlloc, nullptr);
897+
898+
result = context->closeIpcMemHandle(ipcPtr);
899+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
900+
901+
result = context->freeMem(ptr);
902+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
903+
}
904+
905+
TEST_F(MemoryExportImportImplicitScalingTest,
906+
whenCallingImportFdHandlesWithUncachedFlagAllocationPointerThenAllocationIsReturned) {
907+
size_t size = 10;
908+
size_t alignment = 1u;
909+
void *ptr = nullptr;
910+
911+
ze_device_mem_alloc_desc_t deviceDesc = {};
912+
ze_result_t result = context->allocDeviceMem(device->toHandle(),
913+
&deviceDesc,
914+
size, alignment, &ptr);
915+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
916+
EXPECT_NE(nullptr, ptr);
917+
918+
uint32_t numIpcHandles = 0;
919+
result = context->getIpcMemHandles(ptr, &numIpcHandles, nullptr);
920+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
921+
EXPECT_EQ(numIpcHandles, 2u);
922+
923+
std::vector<ze_ipc_mem_handle_t> ipcHandles(numIpcHandles);
924+
result = context->getIpcMemHandles(ptr, &numIpcHandles, ipcHandles.data());
925+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
926+
927+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
928+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<NEO::MockDriverModelDRM>());
929+
930+
std::vector<NEO::osHandle> handles;
931+
for (uint32_t i = 0; i < numIpcHandles; i++) {
932+
uint64_t handle = 0;
933+
memcpy_s(&handle,
934+
sizeof(handle),
935+
reinterpret_cast<void *>(ipcHandles[i].data),
936+
sizeof(handle));
937+
handles.push_back(static_cast<NEO::osHandle>(handle));
938+
}
939+
940+
ze_ipc_memory_flags_t flags = {ZE_IPC_MEMORY_FLAG_BIAS_UNCACHED};
941+
void *ipcPtr;
942+
NEO::GraphicsAllocation *ipcAlloc = nullptr;
943+
DriverHandleImp *driverHandleImp = static_cast<DriverHandleImp *>(context->getDriverHandle());
944+
NEO::SvmAllocationData allocDataInternal(device->getNEODevice()->getRootDeviceIndex());
945+
ipcPtr = driverHandleImp->importFdHandles(device->getNEODevice(), flags, handles, nullptr, &ipcAlloc, allocDataInternal);
946+
EXPECT_NE(ipcPtr, nullptr);
947+
EXPECT_NE(ipcAlloc, nullptr);
948+
949+
result = context->closeIpcMemHandle(ipcPtr);
950+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
951+
952+
result = context->freeMem(ptr);
953+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
954+
}
955+
956+
TEST_F(MemoryExportImportImplicitScalingTest,
957+
whenCallingGetIpcMemHandlesAndImportFailsThenInvalidArgumentFails) {
958+
currMemoryManager->failOnCreateGraphicsAllocationFromSharedHandle = true;
959+
960+
size_t size = 10;
961+
size_t alignment = 1u;
962+
void *ptr = nullptr;
963+
964+
ze_device_mem_alloc_desc_t deviceDesc = {};
965+
ze_result_t result = context->allocDeviceMem(device->toHandle(),
966+
&deviceDesc,
967+
size, alignment, &ptr);
968+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
969+
EXPECT_NE(nullptr, ptr);
970+
971+
uint32_t numIpcHandles = 0;
972+
result = context->getIpcMemHandles(ptr, &numIpcHandles, nullptr);
973+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
974+
EXPECT_EQ(numIpcHandles, 2u);
975+
976+
std::vector<ze_ipc_mem_handle_t> ipcHandles(numIpcHandles);
977+
result = context->getIpcMemHandles(ptr, &numIpcHandles, ipcHandles.data());
978+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
979+
980+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface.reset(new NEO::OSInterface());
981+
neoDevice->executionEnvironment->rootDeviceEnvironments[0]->osInterface->setDriverModel(std::make_unique<NEO::MockDriverModelDRM>());
982+
983+
ze_ipc_memory_flags_t flags = {};
984+
void *ipcPtr;
985+
result = context->openIpcMemHandles(device->toHandle(), numIpcHandles, ipcHandles.data(), flags, &ipcPtr);
986+
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_ARGUMENT, result);
987+
988+
result = context->freeMem(ptr);
989+
EXPECT_EQ(ZE_RESULT_SUCCESS, result);
990+
}
991+
705992
} // namespace ult
706993
} // namespace L0

0 commit comments

Comments
 (0)