@@ -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