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
13 changes: 13 additions & 0 deletions doc/loader_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,17 @@ This does not unload the tracing layer library such that one can call `zelEnable

NOTE: The each call to `zelEnableTracingLayer` tracks a reference count of how many calls to enable have been seen. The Tracing Layer intercepts will not be removed until the reference count has reached 0 indicating that all users of the tracing layer have called `zelDisableTracingLayer`.

### zelGetTracingLayerState

Queries the current enabled state of the tracing layer at runtime.

This function allows applications to check whether the tracing layer is currently active, returning the state through a boolean pointer.

- __*enabled__ Pointer to a boolean that will be set to `true` if the tracing layer is currently enabled, or `false` if it is disabled.

The function returns:
- `ZE_RESULT_SUCCESS` on successful query
- `ZE_RESULT_ERROR_INVALID_NULL_POINTER` if the `enabled` pointer is null

This is a read-only, thread-safe operation that can be called multiple times concurrently. The tracing layer state is global to the process and reflects the current reference count maintained by `zelEnableTracingLayer` and `zelDisableTracingLayer` - the layer is considered enabled when the reference count is greater than zero.

22 changes: 22 additions & 0 deletions include/loader/ze_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,28 @@ zelRegisterTeardownCallback(
ZE_DLLEXPORT ze_result_t ZE_APICALL
zelDisableTracingLayer();

/**
* @brief Retrieves the current enabled state of the Level Zero tracing layer.
*
* This function queries whether the tracing layer is active and writes the result
* to the provided boolean pointer.
*
* @param enabled
* Pointer to a boolean that will be set to true if the tracing layer is
* currently enabled, or false if it is disabled. Must be a valid, non-null
* pointer.
*
* @return
* ZE_RESULT_SUCCESS on success.
* ZE_RESULT_ERROR_INVALID_NULL_POINTER if `enabled` is null.
* Other ze_result_t error codes may be returned for implementation-specific failures.
*
* @note The tracing layer state is global to the process. The function is read-only
* and thread-safe; multiple callers can query the state concurrently.
*/
ZE_DLLEXPORT ze_result_t ZE_APICALL
zelGetTracingLayerState(bool* enabled); // Pointer to bool to receive tracing layer state

#if defined(__cplusplus)
} // extern "C"
#endif
Expand Down
30 changes: 30 additions & 0 deletions source/lib/ze_lib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,36 @@ zelEnableTracingLayer()
return ZE_RESULT_SUCCESS;
}

ze_result_t ZE_APICALL
zelGetTracingLayerState
(
bool* enabled // Pointer to bool to receive tracing layer state
)
{
if (enabled == nullptr) {
return ZE_RESULT_ERROR_INVALID_NULL_POINTER;
}
#ifdef L0_STATIC_LOADER_BUILD
if(nullptr == ze_lib::context->loader)
return ZE_RESULT_ERROR_UNINITIALIZED;
typedef ze_result_t (ZE_APICALL *zelGetTracingLayerStateInternal_t)(bool* enabled);
auto getDynamicTracingState = reinterpret_cast<zelGetTracingLayerStateInternal_t>(
GET_FUNCTION_PTR(ze_lib::context->loader, "zelGetTracingLayerState") );
return getDynamicTracingState(enabled);
#else
if (ze_lib::context->dynamicTracingSupported == false) {
return ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
}
if (loader::context) {
*enabled = loader::context->tracingLayerEnabled;
}
if (!*enabled) {
*enabled = (ze_lib::context->tracingLayerEnableCounter.load() > 0);
}
#endif
return ZE_RESULT_SUCCESS;
}

ze_result_t ZE_APICALL
zelDisableTracingLayer()
{
Expand Down
38 changes: 38 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,42 @@ endif()
add_test(NAME tests_loader_teardown_check COMMAND tests --gtest_filter=*GivenLoaderNotInDestructionStateWhenCallingzelCheckIsLoaderInTearDownThenFalseIsReturned)
set_property(TEST tests_loader_teardown_check PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME tests_tracing_layer_state_null_pointer COMMAND tests --gtest_filter=*TracingLayerState.GivenNullPointerWhenCallingzelGetTracingLayerStateThenErrorInvalidNullPointerIsReturned)
set_property(TEST tests_tracing_layer_state_null_pointer PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME tests_tracing_layer_state_valid_pointer COMMAND tests --gtest_filter=*TracingLayerState.GivenValidPointerWhenCallingzelGetTracingLayerStateThenSuccessIsReturned)
set_property(TEST tests_tracing_layer_state_valid_pointer PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME tests_tracing_layer_state_not_enabled COMMAND tests --gtest_filter=*TracingLayerState.GivenTracingLayerNotEnabledWhenCallingzelGetTracingLayerStateThenFalseIsReturned)
set_property(TEST tests_tracing_layer_state_not_enabled PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME tests_tracing_layer_state_enabled COMMAND tests --gtest_filter=*TracingLayerState.GivenTracingLayerEnabledWhenCallingzelGetTracingLayerStateThenTrueIsReturned)
set_property(TEST tests_tracing_layer_state_enabled PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME tests_tracing_layer_state_enabled_then_disabled COMMAND tests --gtest_filter=*TracingLayerState.GivenTracingLayerEnabledThenDisabledWhenCallingzelGetTracingLayerStateThenFalseIsReturned)
set_property(TEST tests_tracing_layer_state_enabled_then_disabled PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME tests_tracing_layer_state_multiple_enable COMMAND tests --gtest_filter=*TracingLayerState.GivenMultipleEnableCallsWhenCallingzelGetTracingLayerStateThenTrueIsReturned)
set_property(TEST tests_tracing_layer_state_multiple_enable PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME tests_tracing_layer_state_multiple_enable_partial_disable COMMAND tests --gtest_filter=*TracingLayerState.GivenMultipleEnableAndPartialDisableWhenCallingzelGetTracingLayerStateThenTrueIsReturned)
set_property(TEST tests_tracing_layer_state_multiple_enable_partial_disable PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME tests_tracing_layer_state_multiple_calls_enabled COMMAND tests --gtest_filter=*TracingLayerState.GivenMultipleCallsTozelGetTracingLayerStateWhenTracingEnabledThenAllReturnTrue)
set_property(TEST tests_tracing_layer_state_multiple_calls_enabled PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME tests_tracing_layer_state_multiple_calls_disabled COMMAND tests --gtest_filter=*TracingLayerState.GivenMultipleCallsTozelGetTracingLayerStateWhenTracingDisabledThenAllReturnFalse)
set_property(TEST tests_tracing_layer_state_multiple_calls_disabled PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME tests_tracing_layer_state_enabled_via_environment COMMAND tests --gtest_filter=*TracingLayerState.GivenTracingLayerEnabledViaEnvironmentWhenCallingzelGetTracingLayerStateThenTrueIsReturned)
set_property(TEST tests_tracing_layer_state_enabled_via_environment PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME tests_tracing_layer_state_enabled_via_environment_and_dynamic COMMAND tests --gtest_filter=*TracingLayerState.GivenTracingLayerEnabledViaEnvironmentWhenCallingzelEnableTracingLayerThenStateRemainsTrue)
set_property(TEST tests_tracing_layer_state_enabled_via_environment_and_dynamic PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME tests_tracing_layer_state_enabled_via_environment_disable_dynamic COMMAND tests --gtest_filter=*TracingLayerState.GivenTracingLayerEnabledViaEnvironmentAndDynamicallyWhenDisablingDynamicTracingThenStateRemainsTrue)
set_property(TEST tests_tracing_layer_state_enabled_via_environment_disable_dynamic PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1")

add_test(NAME test_zello_world_legacy COMMAND zello_world --enable_legacy_init --enable_null_driver --force_loader_intercepts --enable_validation_layer --enable_tracing_layer --enable_tracing_layer_runtime)
set_property(TEST test_zello_world_legacy PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1")

Expand Down Expand Up @@ -670,6 +706,8 @@ else()
set_property(TEST init_driver_unit_tests PROPERTY ENVIRONMENT "ZE_ENABLE_LOADER_DEBUG_TRACE=1;ZE_ENABLE_NULL_DRIVER=1;")
endif()



# These tests are currently not supported on Windows. The reason is that the std::cerr is not being redirected to a pipe in Windows to be then checked against the expected output.
if(NOT MSVC)
add_test(NAME tests_event_deadlock COMMAND tests --gtest_filter=*GivenLevelZeroLoaderPresentWhenCallingzeCommandListAppendMemoryCopyWithCircularDependencyOnEventsThenValidationLayerPrintsWarningOfDeadlock*)
Expand Down
215 changes: 215 additions & 0 deletions test/loader_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,221 @@ TEST(
EXPECT_FALSE(zelCheckIsLoaderInTearDown());
}

TEST(
TracingLayerState,
GivenNullPointerWhenCallingzelGetTracingLayerStateThenErrorInvalidNullPointerIsReturned) {

EXPECT_EQ(ZE_RESULT_ERROR_INVALID_NULL_POINTER, zelGetTracingLayerState(nullptr));
}

TEST(
TracingLayerState,
GivenValidPointerWhenCallingzelGetTracingLayerStateThenSuccessIsReturned) {

uint32_t pCount = 0;
ze_init_driver_type_desc_t desc = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
desc.flags = UINT32_MAX;
desc.pNext = nullptr;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&pCount, nullptr, &desc));
bool enabled = false;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
}

TEST(
TracingLayerState,
GivenTracingLayerNotEnabledWhenCallingzelGetTracingLayerStateThenFalseIsReturned) {

uint32_t pCount = 0;
ze_init_driver_type_desc_t desc = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
desc.flags = UINT32_MAX;
desc.pNext = nullptr;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&pCount, nullptr, &desc));
bool enabled = true;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_FALSE(enabled);
}

TEST(
TracingLayerState,
GivenTracingLayerEnabledWhenCallingzelGetTracingLayerStateThenTrueIsReturned) {

uint32_t pCount = 0;
ze_init_driver_type_desc_t desc = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
desc.flags = UINT32_MAX;
desc.pNext = nullptr;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&pCount, nullptr, &desc));
EXPECT_EQ(ZE_RESULT_SUCCESS, zelEnableTracingLayer());
bool enabled = false;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
EXPECT_EQ(ZE_RESULT_SUCCESS, zelDisableTracingLayer());
}

TEST(
TracingLayerState,
GivenTracingLayerEnabledThenDisabledWhenCallingzelGetTracingLayerStateThenFalseIsReturned) {

uint32_t pCount = 0;
ze_init_driver_type_desc_t desc = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
desc.flags = UINT32_MAX;
desc.pNext = nullptr;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&pCount, nullptr, &desc));
EXPECT_EQ(ZE_RESULT_SUCCESS, zelEnableTracingLayer());
bool enabled = false;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
EXPECT_EQ(ZE_RESULT_SUCCESS, zelDisableTracingLayer());
enabled = true;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_FALSE(enabled);
}

TEST(
TracingLayerState,
GivenMultipleEnableCallsWhenCallingzelGetTracingLayerStateThenTrueIsReturned) {

uint32_t pCount = 0;
ze_init_driver_type_desc_t desc = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
desc.flags = UINT32_MAX;
desc.pNext = nullptr;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&pCount, nullptr, &desc));
EXPECT_EQ(ZE_RESULT_SUCCESS, zelEnableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelEnableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelEnableTracingLayer());
bool enabled = false;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
EXPECT_EQ(ZE_RESULT_SUCCESS, zelDisableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelDisableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelDisableTracingLayer());
}

TEST(
TracingLayerState,
GivenMultipleEnableAndPartialDisableWhenCallingzelGetTracingLayerStateThenTrueIsReturned) {

uint32_t pCount = 0;
ze_init_driver_type_desc_t desc = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
desc.flags = UINT32_MAX;
desc.pNext = nullptr;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&pCount, nullptr, &desc));
EXPECT_EQ(ZE_RESULT_SUCCESS, zelEnableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelEnableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelEnableTracingLayer());
bool enabled = false;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
EXPECT_EQ(ZE_RESULT_SUCCESS, zelDisableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
EXPECT_EQ(ZE_RESULT_SUCCESS, zelDisableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
EXPECT_EQ(ZE_RESULT_SUCCESS, zelDisableTracingLayer());
enabled = true;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_FALSE(enabled);
}

TEST(
TracingLayerState,
GivenMultipleCallsTozelGetTracingLayerStateWhenTracingEnabledThenAllReturnTrue) {

uint32_t pCount = 0;
ze_init_driver_type_desc_t desc = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
desc.flags = UINT32_MAX;
desc.pNext = nullptr;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&pCount, nullptr, &desc));
EXPECT_EQ(ZE_RESULT_SUCCESS, zelEnableTracingLayer());
bool enabled1 = false, enabled2 = false, enabled3 = false;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled1));
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled2));
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled3));
EXPECT_TRUE(enabled1);
EXPECT_TRUE(enabled2);
EXPECT_TRUE(enabled3);
EXPECT_EQ(ZE_RESULT_SUCCESS, zelDisableTracingLayer());
}

TEST(
TracingLayerState,
GivenMultipleCallsTozelGetTracingLayerStateWhenTracingDisabledThenAllReturnFalse) {

uint32_t pCount = 0;
ze_init_driver_type_desc_t desc = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
desc.flags = UINT32_MAX;
desc.pNext = nullptr;
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&pCount, nullptr, &desc));
bool enabled1 = true, enabled2 = true, enabled3 = true;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled1));
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled2));
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled3));
EXPECT_FALSE(enabled1);
EXPECT_FALSE(enabled2);
EXPECT_FALSE(enabled3);
}

TEST(
TracingLayerState,
GivenTracingLayerEnabledViaEnvironmentWhenCallingzelGetTracingLayerStateThenTrueIsReturned) {

uint32_t pCount = 0;
ze_init_driver_type_desc_t desc = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
desc.flags = UINT32_MAX;
desc.pNext = nullptr;
putenv_safe( const_cast<char *>( "ZE_ENABLE_TRACING_LAYER=1" ) );
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&pCount, nullptr, &desc));
bool enabled = false;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
}

TEST(
TracingLayerState,
GivenTracingLayerEnabledViaEnvironmentWhenCallingzelEnableTracingLayerThenStateRemainsTrue) {

uint32_t pCount = 0;
ze_init_driver_type_desc_t desc = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
desc.flags = UINT32_MAX;
desc.pNext = nullptr;
putenv_safe( const_cast<char *>( "ZE_ENABLE_TRACING_LAYER=1" ) );
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&pCount, nullptr, &desc));
bool enabled = false;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
EXPECT_EQ(ZE_RESULT_SUCCESS, zelEnableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
EXPECT_EQ(ZE_RESULT_SUCCESS, zelDisableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
}

TEST(
TracingLayerState,
GivenTracingLayerEnabledViaEnvironmentAndDynamicallyWhenDisablingDynamicTracingThenStateRemainsTrue) {

uint32_t pCount = 0;
ze_init_driver_type_desc_t desc = {ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC};
desc.flags = UINT32_MAX;
desc.pNext = nullptr;
putenv_safe( const_cast<char *>( "ZE_ENABLE_TRACING_LAYER=1" ) );
EXPECT_EQ(ZE_RESULT_SUCCESS, zeInitDrivers(&pCount, nullptr, &desc));
EXPECT_EQ(ZE_RESULT_SUCCESS, zelEnableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelEnableTracingLayer());
bool enabled = false;
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
EXPECT_EQ(ZE_RESULT_SUCCESS, zelDisableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
EXPECT_EQ(ZE_RESULT_SUCCESS, zelDisableTracingLayer());
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetTracingLayerState(&enabled));
EXPECT_TRUE(enabled);
}



class CaptureOutput {
private:
int original_fd;
Expand Down
Loading