Skip to content

Commit 667f858

Browse files
committed
Add Unit Test for multi driver init
Signed-off-by: Neil R. Spruit <neil.r.spruit@intel.com>
1 parent 834f6a7 commit 667f858

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

test/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,18 @@ set_property(TEST tests_missing_api PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG
161161
add_test(NAME tests_multi_call_failure COMMAND tests --gtest_filter=*GivenLevelZeroLoaderPresentWhenCallingZeInitDriversWithTypesUnsupportedWithFailureThenSupportedTypesThenSuccessReturned*)
162162
set_property(TEST tests_multi_call_failure PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")
163163

164+
# Regression test: NPU driver must not be lost after an intermediate GPU-only call
165+
# Uses ze_intel_gpu (ZEL_NULL_DRIVER_TYPE_GPU) and ze_intel_npu (ZEL_NULL_DRIVER_TYPE_NPU)
166+
# from lib_fake so each driver has a distinct compile-time type, making the 4-step
167+
# sequence (NPU|GPU → GPU → NPU → NPU|GPU) a meaningful regression check.
168+
if(NOT BUILD_STATIC AND NOT WIN32)
169+
add_test(NAME tests_init_gpu_npu_regression_combined
170+
COMMAND tests --gtest_filter=*InitDriverUnitTest.zeInitDriversGPUAndNPU_AfterGPUOnlyThenNPUOnly_BothStillReturnedOnCombined*)
171+
set_property(TEST tests_init_gpu_npu_regression_combined PROPERTY ENVIRONMENT
172+
"ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_ALT_DRIVERS=${CMAKE_BINARY_DIR}/lib_fake/libze_intel_gpu.so,${CMAKE_BINARY_DIR}/lib_fake/libze_intel_npu.so")
173+
endif()
174+
175+
164176
# Run with multiple drivers
165177
add_test(NAME tests_multi_driver_missing_initDrivers COMMAND tests --gtest_filter=*GivenLevelZeroLoaderPresentWithMultipleDriversMissingInitDriversWhenCallingZeInitDriversThenExpectSuccessForZeInit)
166178
if (MSVC)

test/init_driver_dynamic_unit_tests.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,4 +252,71 @@ TEST_F(InitDriverUnitTest, zeInitDriversWithAllTypes_VerifyRoutingToCorrectDrive
252252
// At least one type of driver should be found if we have drivers
253253
EXPECT_TRUE(foundGPUDriver || foundNPUDriver);
254254
}
255+
}
256+
257+
// Regression test for the bug where calling zeInitDrivers with GPU-only flags
258+
// causes the NPU driver to be absent in a subsequent NPU|GPU call.
259+
//
260+
// Reproduction sequence:
261+
// Step 1: NPU|GPU → count=N (GPU + NPU) [expected: success]
262+
// Step 2: GPU → count=1 (GPU only) [expected: success]
263+
// Step 3: NPU → count=1 (NPU only) [expected: success]
264+
// Step 4: NPU|GPU → count should still equal N [BUG: count was < N]
265+
TEST_F(InitDriverUnitTest, zeInitDriversGPUAndNPU_AfterGPUOnlyThenNPUOnly_BothStillReturnedOnCombined) {
266+
ze_init_driver_type_desc_t descBoth = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
267+
descBoth.flags = ZE_INIT_DRIVER_TYPE_FLAG_GPU | ZE_INIT_DRIVER_TYPE_FLAG_NPU;
268+
descBoth.pNext = nullptr;
269+
270+
ze_init_driver_type_desc_t descGPU = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
271+
descGPU.flags = ZE_INIT_DRIVER_TYPE_FLAG_GPU;
272+
descGPU.pNext = nullptr;
273+
274+
ze_init_driver_type_desc_t descNPU = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
275+
descNPU.flags = ZE_INIT_DRIVER_TYPE_FLAG_NPU;
276+
descNPU.pNext = nullptr;
277+
278+
// Step 1: NPU|GPU — establish the baseline combined count
279+
uint32_t countBothFirst = 0;
280+
ASSERT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&countBothFirst, nullptr, &descBoth));
281+
282+
// Only meaningful if at least one driver is present
283+
if (countBothFirst == 0) {
284+
GTEST_SKIP() << "No GPU or NPU drivers available; skipping regression test";
285+
}
286+
287+
EXPECT_EQ(countBothFirst, 2);
288+
289+
// Step 2: GPU-only call
290+
uint32_t countGPU = 0;
291+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&countGPU, nullptr, &descGPU));
292+
293+
EXPECT_EQ(countGPU, 1);
294+
295+
// Step 3: NPU-only call
296+
uint32_t countNPU = 0;
297+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&countNPU, nullptr, &descNPU));
298+
299+
EXPECT_EQ(countNPU, 1);
300+
301+
// Step 4: NPU|GPU again — must return the same count as Step 1
302+
// This is the regression check: the NPU driver must not have been lost
303+
// as a side-effect of the intermediate GPU-only or NPU-only calls.
304+
uint32_t countBothSecond = 0;
305+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&countBothSecond, nullptr, &descBoth));
306+
EXPECT_EQ(countBothFirst, countBothSecond)
307+
<< "Regression: zeInitDrivers(NPU|GPU) returned fewer drivers after "
308+
"intermediate GPU-only and NPU-only calls. "
309+
"First combined count=" << countBothFirst
310+
<< ", second combined count=" << countBothSecond;
311+
312+
// Verify the returned handles are valid
313+
if (countBothSecond > 0) {
314+
std::vector<ze_driver_handle_t> drivers(countBothSecond);
315+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&countBothSecond, drivers.data(), &descBoth));
316+
for (uint32_t i = 0; i < countBothSecond; i++) {
317+
EXPECT_NE(drivers[i], nullptr);
318+
uint32_t deviceCount = 0;
319+
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDeviceGet(drivers[i], &deviceCount, nullptr));
320+
}
321+
}
255322
}

0 commit comments

Comments
 (0)