Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,18 @@ set_property(TEST tests_missing_api PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG
add_test(NAME tests_multi_call_failure COMMAND tests --gtest_filter=*GivenLevelZeroLoaderPresentWhenCallingZeInitDriversWithTypesUnsupportedWithFailureThenSupportedTypesThenSuccessReturned*)
set_property(TEST tests_multi_call_failure PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

# Regression test: NPU driver must not be lost after an intermediate GPU-only call
# Uses ze_intel_gpu (ZEL_NULL_DRIVER_TYPE_GPU) and ze_intel_npu (ZEL_NULL_DRIVER_TYPE_NPU)
# from lib_fake so each driver has a distinct compile-time type, making the 4-step
# sequence (NPU|GPU → GPU → NPU → NPU|GPU) a meaningful regression check.
if(NOT BUILD_STATIC AND NOT WIN32)
add_test(NAME tests_init_gpu_npu_regression_combined
COMMAND tests --gtest_filter=*InitDriverGPUNPURegressionTest*)
set_property(TEST tests_init_gpu_npu_regression_combined PROPERTY ENVIRONMENT
"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")
endif()


# Run with multiple drivers
add_test(NAME tests_multi_driver_missing_initDrivers COMMAND tests --gtest_filter=*GivenLevelZeroLoaderPresentWithMultipleDriversMissingInitDriversWhenCallingZeInitDriversThenExpectSuccessForZeInit)
if (MSVC)
Expand Down
71 changes: 71 additions & 0 deletions test/init_driver_dynamic_unit_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -252,4 +252,75 @@ TEST_F(InitDriverUnitTest, zeInitDriversWithAllTypes_VerifyRoutingToCorrectDrive
// At least one type of driver should be found if we have drivers
EXPECT_TRUE(foundGPUDriver || foundNPUDriver);
}
}

// Derived fixture for the NPU-loss regression test so it runs as its own
// named test suite and can be targeted independently via --gtest_filter.
class InitDriverGPUNPURegressionTest : public InitDriverUnitTest {};

// Regression test for the bug where calling zeInitDrivers with GPU-only flags
// causes the NPU driver to be absent in a subsequent NPU|GPU call.
//
// Reproduction sequence:
// Step 1: NPU|GPU → count=N (GPU + NPU) [expected: success]
// Step 2: GPU → count=1 (GPU only) [expected: success]
// Step 3: NPU → count=1 (NPU only) [expected: success]
// Step 4: NPU|GPU → count should still equal N [BUG: count was < N]
TEST_F(InitDriverGPUNPURegressionTest, zeInitDriversGPUAndNPU_AfterGPUOnlyThenNPUOnly_BothStillReturnedOnCombined) {
ze_init_driver_type_desc_t descBoth = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
descBoth.flags = ZE_INIT_DRIVER_TYPE_FLAG_GPU | ZE_INIT_DRIVER_TYPE_FLAG_NPU;
descBoth.pNext = nullptr;

ze_init_driver_type_desc_t descGPU = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
descGPU.flags = ZE_INIT_DRIVER_TYPE_FLAG_GPU;
descGPU.pNext = nullptr;

ze_init_driver_type_desc_t descNPU = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
descNPU.flags = ZE_INIT_DRIVER_TYPE_FLAG_NPU;
descNPU.pNext = nullptr;

// Step 1: NPU|GPU — establish the baseline combined count
uint32_t countBothFirst = 0;
ASSERT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&countBothFirst, nullptr, &descBoth));

// Only meaningful if at least one driver is present
if (countBothFirst == 0) {
GTEST_SKIP() << "No GPU or NPU drivers available; skipping regression test";
}

EXPECT_EQ(countBothFirst, 2);

// Step 2: GPU-only call
uint32_t countGPU = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&countGPU, nullptr, &descGPU));

EXPECT_EQ(countGPU, 1);

// Step 3: NPU-only call
uint32_t countNPU = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&countNPU, nullptr, &descNPU));

EXPECT_EQ(countNPU, 1);

// Step 4: NPU|GPU again — must return the same count as Step 1
// This is the regression check: the NPU driver must not have been lost
// as a side-effect of the intermediate GPU-only or NPU-only calls.
uint32_t countBothSecond = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&countBothSecond, nullptr, &descBoth));
EXPECT_EQ(countBothFirst, countBothSecond)
<< "Regression: zeInitDrivers(NPU|GPU) returned fewer drivers after "
"intermediate GPU-only and NPU-only calls. "
"First combined count=" << countBothFirst
<< ", second combined count=" << countBothSecond;

// Verify the returned handles are valid
if (countBothSecond > 0) {
std::vector<ze_driver_handle_t> drivers(countBothSecond);
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&countBothSecond, drivers.data(), &descBoth));
for (uint32_t i = 0; i < countBothSecond; i++) {
EXPECT_NE(drivers[i], nullptr);
uint32_t deviceCount = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDeviceGet(drivers[i], &deviceCount, nullptr));
}
}
}
Loading