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
2 changes: 1 addition & 1 deletion scripts/templates/validation/valddi.cpp.mako
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ return ${failure_return};

<%
func_name = th.make_func_name(n, tags, obj)
generate_post_call = re.match(r"\w+Create\w*$|\w+Get$|\w+Get\w*Exp$|\w+GetIpcHandle$|\w+GetSubDevices$", func_name)
generate_post_call = re.match(r"\w+Create\w*$|\w+Get$|\w+Get\w*Exp$|\w+GetIpcHandle$|\w+GetSubDevices$|\w+InitDrivers$", func_name)
%>
if(context.enableHandleLifetime ){
auto result = context.handleLifetime->${n}HandleLifetime.${th.make_func_name(n, tags, obj)}Prologue( \
Expand Down
9 changes: 9 additions & 0 deletions source/layers/validation/ze_valddi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7748,6 +7748,15 @@ namespace validation_layer
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult_zeInitDrivers(result, pCount, phDrivers, desc);
}


if( driver_result == ZE_RESULT_SUCCESS && context.enableHandleLifetime ){
for (size_t i = 0; ( nullptr != phDrivers) && (i < *pCount); ++i){
if (phDrivers[i]){
context.handleLifetime->addHandle( phDrivers[i] );
context.handleLifetime->addDependent( pCount, phDrivers[i] );
}
}
}
return logAndPropagateResult_zeInitDrivers(driver_result, pCount, phDrivers, desc);
}

Expand Down
11 changes: 11 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1130,6 +1130,17 @@ set_property(TEST test_zer_validation_layer_positive_case PROPERTY ENVIRONMENT "
add_test(NAME test_zer_parameter_validation_layer_negative_case COMMAND tests --gtest_filter=*GivenLevelZeroLoaderPresentWhenCallingZerApiWithParameterValidationEnabledThenExpectValidationsAreTriggered)
set_property(TEST test_zer_parameter_validation_layer_negative_case PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1;ZE_ENABLE_VALIDATION_LAYER=1;ZE_ENABLE_PARAMETER_VALIDATION=1;ZE_ENABLE_HANDLE_LIFETIME=1;ZEL_ENABLE_EVENTS_CHECKER=1;ZEL_ENABLE_BASIC_LEAK_CHECKER=1;ZEL_ENABLE_CERTIFICATION_CHECKER=1")

# Handle Lifetime Validation Tests
# Regression: zeInitDrivers must register driver handles so downstream calls succeed.
add_test(NAME test_handle_lifetime_zeInitDrivers_path COMMAND tests --gtest_filter=*HandleLifetimeValidation*GivenHandleLifetimeEnabledWhenCallingzeDeviceGetWithDriverHandleFromzeInitDriversThenSucceeds*)
set_property(TEST test_handle_lifetime_zeInitDrivers_path PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1;ZEL_TEST_NULL_DRIVER_TYPE=GPU;ZE_ENABLE_VALIDATION_LAYER=1;ZE_ENABLE_HANDLE_LIFETIME=1")

add_test(NAME test_handle_lifetime_zeDriverGet_path COMMAND tests --gtest_filter=*HandleLifetimeValidation*GivenHandleLifetimeEnabledWhenCallingzeDeviceGetWithDriverHandleFromzeDriverGetThenSucceeds*)
set_property(TEST test_handle_lifetime_zeDriverGet_path PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1;ZEL_TEST_NULL_DRIVER_TYPE=GPU;ZE_ENABLE_VALIDATION_LAYER=1;ZE_ENABLE_HANDLE_LIFETIME=1")

add_test(NAME test_handle_lifetime_null_handle_rejected COMMAND tests --gtest_filter=*HandleLifetimeValidation*GivenHandleLifetimeEnabledWhenCallingzeDeviceGetWithNullDriverHandleThenReturnsInvalidHandle*)
set_property(TEST test_handle_lifetime_null_handle_rejected PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1;ZEL_TEST_NULL_DRIVER_TYPE=GPU;ZE_ENABLE_VALIDATION_LAYER=1;ZE_ENABLE_HANDLE_LIFETIME=1")

# API Call Tracing Tests - Validation Layer with Trace Logging
add_test(NAME test_validation_layer_api_tracing_basic COMMAND tests --gtest_filter=ValidationLayerApiTracing.GivenValidationLayerEnabledWithTraceLevelLoggingWhenCallingBasicApisThenTracingDoesNotCrash)
set_property(TEST test_validation_layer_api_tracing_basic PROPERTY ENVIRONMENT "ZE_ENABLE_VALIDATION_LAYER=1;ZEL_ENABLE_LOADER_LOGGING=1;ZEL_LOADER_LOGGING_LEVEL=trace;ZE_ENABLE_NULL_DRIVER=1")
Expand Down
86 changes: 86 additions & 0 deletions test/loader_validation_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -970,3 +970,89 @@ TEST(
EXPECT_EQ(ZE_RESULT_SUCCESS, zeCommandQueueDestroy(commandQueue));
EXPECT_EQ(ZE_RESULT_SUCCESS, zeContextDestroy(context));
}

///////////////////////////////////////////////////////////////////////////////
// Handle Lifetime Tests
//
// These tests validate the ZE_ENABLE_HANDLE_LIFETIME feature of the validation
// layer. Handle lifetime tracking registers handles when they are created and
// validates them on every subsequent API call, returning
// ZE_RESULT_ERROR_INVALID_NULL_HANDLE for any unregistered handle.
//
// The tests are run as separate CTest invocations with the environment:
// ZE_ENABLE_VALIDATION_LAYER=1
// ZE_ENABLE_HANDLE_LIFETIME=1
// ZE_ENABLE_NULL_DRIVER=1

// Regression test: driver handles obtained via zeInitDrivers must be registered
// in the handle lifetime tracker so that subsequent API calls succeed.
// Before the fix, zeInitDrivers had no handle-registration epilogue (unlike
// zeDriverGet), causing zeDeviceGet to return ZE_RESULT_ERROR_INVALID_NULL_HANDLE.
TEST(
HandleLifetimeValidation,
GivenHandleLifetimeEnabledWhenCallingzeDeviceGetWithDriverHandleFromzeInitDriversThenSucceeds) {

ze_init_driver_type_desc_t driverTypeDesc = {};
driverTypeDesc.stype = ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC;
driverTypeDesc.pNext = nullptr;
driverTypeDesc.flags = UINT32_MAX;

uint32_t count = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&count, nullptr, &driverTypeDesc));
EXPECT_GT(count, 0);

std::vector<ze_driver_handle_t> drivers(count);
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&count, drivers.data(), &driverTypeDesc));

// Regression: driver handles from zeInitDrivers must be registered with the
// handle lifetime tracker so that zeDeviceGet does not fail with
// ZE_RESULT_ERROR_INVALID_NULL_HANDLE.
uint32_t deviceCount = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDeviceGet(drivers[0], &deviceCount, nullptr));
EXPECT_GT(deviceCount, 0);

std::vector<ze_device_handle_t> devices(deviceCount);
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDeviceGet(drivers[0], &deviceCount, devices.data()));
}

// Verify that driver handles obtained via zeDriverGet are registered correctly
// and can be used with zeDeviceGet when handle lifetime tracking is enabled.
TEST(
HandleLifetimeValidation,
GivenHandleLifetimeEnabledWhenCallingzeDeviceGetWithDriverHandleFromzeDriverGetThenSucceeds) {

EXPECT_EQ(ZE_RESULT_SUCCESS, zeInit(ZE_INIT_FLAG_GPU_ONLY));

uint32_t driverCount = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDriverGet(&driverCount, nullptr));
EXPECT_GT(driverCount, 0);

std::vector<ze_driver_handle_t> drivers(driverCount);
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDriverGet(&driverCount, drivers.data()));

uint32_t deviceCount = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDeviceGet(drivers[0], &deviceCount, nullptr));
EXPECT_GT(deviceCount, 0);

std::vector<ze_device_handle_t> devices(deviceCount);
EXPECT_EQ(ZE_RESULT_SUCCESS, zeDeviceGet(drivers[0], &deviceCount, devices.data()));
}

// Verify that calling an API with a null (unregistered) handle returns
// ZE_RESULT_ERROR_INVALID_NULL_HANDLE when handle lifetime tracking is enabled.
TEST(
HandleLifetimeValidation,
GivenHandleLifetimeEnabledWhenCallingzeDeviceGetWithNullDriverHandleThenReturnsInvalidHandle) {

ze_init_driver_type_desc_t driverTypeDesc = {};
driverTypeDesc.stype = ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC;
driverTypeDesc.pNext = nullptr;
driverTypeDesc.flags = UINT32_MAX;

uint32_t count = 0;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&count, nullptr, &driverTypeDesc));

// A null handle is never registered; the handle lifetime checker must reject it.
uint32_t deviceCount = 0;
EXPECT_EQ(ZE_RESULT_ERROR_INVALID_NULL_HANDLE, zeDeviceGet(nullptr, &deviceCount, nullptr));
}
Loading