Skip to content

Commit 230d371

Browse files
authored
feature: Improve API Call Tracing and add ults (#425)
- Updated API Call Tracing to dereference [out] parameters when the api call succeeds for tracking output structures. - Updated spdlog trace to output the thread id in the log string and have the log string to be configurable. - Add ULTs for the validation layer api tracing to ensure stability. Signed-off-by: Neil R. Spruit <neil.r.spruit@intel.com>
1 parent e3749a1 commit 230d371

File tree

12 files changed

+5456
-1356
lines changed

12 files changed

+5456
-1356
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# Level zero loader changelog
2+
## v1.28.1
3+
* feature: Improve API Call Tracing and add ults
4+
* add performance validation layer checker
25
## v1.28.0
36
* feature: Update to support L0 Spec v1.15.31
47
* Loader Driver Interaction conformance tests for Sysman Exp and Ext APIs (#418)

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ if(MSVC AND (MSVC_VERSION LESS 1900))
1313
endif()
1414

1515
# This project follows semantic versioning (https://semver.org/)
16-
project(level-zero VERSION 1.28.0)
16+
project(level-zero VERSION 1.28.1)
1717
include(GNUInstallDirs)
1818

1919
find_package(Git)

PRODUCT_GUID.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
1.28.0
2-
152a1567-448a-42b3-9cdd-83c1bdc21421
1+
1.28.1
2+
3622767c-2b40-4af8-961d-06eda1231409

README.md

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,26 @@ The Level Zero Loader uses spdlog logging and can be controlled via environment
5858

5959
`ZEL_ENABLE_LOADER_LOGGING=1`
6060

61-
[DEPRECATED] `ZEL_LOADER_LOG_FILE=/path/to/logfile`
62-
6361
`ZEL_LOADER_LOG_DIR='/directory/path'`
6462

6563
`ZEL_LOADER_LOGGING_LEVEL=debug`
6664

65+
Default Log Pattern (Does not need to be set, please see below):
66+
`ZEL_LOADER_LOG_PATTERN='[%Y-%m-%d %H:%M:%S.%e] [thread-id: %t] [%^%l%$] %v'`
67+
6768
Valid logging levels are trace, debug, info, warn, error, critical, off.
6869
Logging is disabled by default but when enabled the default level is 'warn'.
6970
The default log file is 'ze_loader.log' in '.oneapi_logs' in the current
7071
user's home directory.
7172

73+
The default log pattern includes timestamps, thread IDs, log levels, and messages.
74+
You can customize the pattern using `ZEL_LOADER_LOG_PATTERN`. Common pattern flags:
75+
- `%t` - thread id
76+
- `%Y-%m-%d %H:%M:%S.%e` - timestamp with milliseconds
77+
- `%l` - log level
78+
- `%v` - the actual log message
79+
See spdlog documentation for more pattern options.
80+
7281
This feature is in early development and is preview only.
7382

7483
# Logging API calls
@@ -84,29 +93,28 @@ validation layer is enabled. Following variables need to be set to enable API lo
8493
By default logs will be written to the log file, as described above. To print the logs
8594
to stderr instead, `ZEL_LOADER_LOG_CONSOLE=1` needs to be set.
8695

87-
The API logging output format includes both function entry and exit information, showing parameter names on entry and parameter values with the result code on exit. Each log entry is timestamped and includes the logger name and log level. Example output:
96+
The API logging output format includes both function entry and exit information, showing parameter names on entry and parameter values with the result code on exit. Each log entry is timestamped and includes the thread-id, logger name, log level. Example output:
8897

8998
```
90-
[2026-01-14 09:01:38.951] [ze_loader] [trace] zeContextCreate(hDriver, desc, phContext)
91-
[2026-01-14 09:01:38.951] [ze_loader] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeContextCreate(hDriver=0x5b261fa70588, desc={stype=0x7ffdd20fe1e0, flags=0}, phContext=0x7ffdd20fe148)
92-
[2026-01-14 09:01:38.951] [ze_loader] [trace] zeCommandListCreateImmediate(hContext, hDevice, altdesc, phCommandList)
93-
[2026-01-14 09:01:38.951] [ze_loader] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeCommandListCreateImmediate(hContext=0x5b261fa74228, hDevice=0x5b261fa708b8, altdesc={stype=0x7ffdd20fe240, ordinal=0, index=0, flags=0, mode=0x7ffdd20fe25c, priority=0x7ffdd20fe260}, phCommandList=0x7ffdd20fe150)
94-
[2026-01-14 09:01:38.951] [ze_loader] [trace] zeEventPoolCreate(hContext, desc, numDevices, phDevicesLocal, phEventPool)
95-
[2026-01-14 09:01:38.951] [ze_loader] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeEventPoolCreate(hContext=0x5b261fa74228, desc={stype=0x7ffdd20fe200, flags=1, count=1}, numDevices=1, phDevices=0x7ffdd20fe138, phEventPool=0x7ffdd20fe160)
96-
[2026-01-14 09:01:38.951] [ze_loader] [trace] zeEventCreate(hEventPool, desc, phEvent)
97-
[2026-01-14 09:01:38.951] [ze_loader] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeEventCreate(hEventPool=0x5b261fa19c18, desc={stype=0x7ffdd20fe220, index=0, signal=4, wait=4}, phEvent=0x7ffdd20fe158)
98-
[2026-01-14 09:01:38.951] [ze_loader] [trace] zeCommandListAppendSignalEvent(hCommandList, hEvent)
99-
[2026-01-14 09:01:38.952] [ze_loader] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeCommandListAppendSignalEvent(hCommandList=0x5b261fa743c8, hEvent=0x5b261c69e5d8)
100-
[2026-01-14 09:01:38.952] [ze_loader] [trace] zeEventHostSynchronize(hEvent, timeout)
101-
[2026-01-14 09:01:38.954] [ze_loader] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeEventHostSynchronize(hEvent=0x5b261c69e5d8, timeout=18446744073709551615)
102-
[2026-01-14 09:01:38.954] [ze_loader] [trace] zeContextDestroy(hContext)
103-
[2026-01-14 09:01:38.954] [ze_loader] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeContextDestroy(hContext=0x5b261fa74228)
104-
[2026-01-14 09:01:38.954] [ze_loader] [trace] zeCommandListDestroy(hCommandList)
105-
[2026-01-14 09:01:38.955] [ze_loader] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeCommandListDestroy(hCommandList=0x5b261fa743c8)
106-
[2026-01-14 09:01:38.955] [ze_loader] [trace] zeEventDestroy(hEvent)
107-
[2026-01-14 09:01:38.955] [ze_loader] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeEventDestroy(hEvent=0x5b261c69e5d8)
108-
[2026-01-14 09:01:38.955] [ze_loader] [trace] zeEventPoolDestroy(hEventPool)
109-
[2026-01-14 09:01:38.955] [ze_loader] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeEventPoolDestroy(hEventPool=0x5b261fa19c18)
99+
[2026-02-13 18:51:29.960] [thread-id: 3139] [trace] zeDriverGet(pCount, phDrivers)
100+
[2026-02-13 18:51:29.960] [thread-id: 3139] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeDriverGet(pCount=1, phDrivers=nullptr)
101+
[2026-02-13 18:51:29.960] [thread-id: 3139] [trace] zeDriverGet(pCount, phDrivers)
102+
[2026-02-13 18:51:29.960] [thread-id: 3139] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeDriverGet(pCount=1, phDrivers=0x5651c11920f0)
103+
[2026-02-13 18:51:29.961010] [0x00007f5d45f57780] [info] Default Driver retrieved at index 0
104+
[2026-02-13 18:51:29.961] [thread-id: 3139] [trace] zeContextCreate(hDriver, desc, phContext)
105+
[2026-02-13 18:51:29.961] [thread-id: 3139] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeContextCreate(hDriver=0x5651c1166418, desc={stype=0x7ffdb52dc060, flags=0}, phContext=0x5651c0276c48)
106+
[2026-02-13 18:51:29.962] [thread-id: 3139] [trace] zeDeviceGet(hDriver, pCount, phDevices)
107+
[2026-02-13 18:51:29.962] [thread-id: 3139] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeDeviceGet(hDriver=0x5651c1166418, pCount=2, phDevices=nullptr)
108+
[2026-02-13 18:51:29.962] [thread-id: 3139] [trace] zeDeviceGet(hDriver, pCount, phDevices)
109+
[2026-02-13 18:51:29.962] [thread-id: 3139] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeDeviceGet(hDriver=0x5651c1166418, pCount=2, phDevices=0x5651c1192230)
110+
[2026-02-13 18:51:29.962] [thread-id: 3139] [trace] zeDeviceGet(hDriver, pCount, phDevices)
111+
[2026-02-13 18:51:29.962] [thread-id: 3139] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeDeviceGet(hDriver=0x5651c1166418, pCount=2, phDevices=nullptr)
112+
[2026-02-13 18:51:29.962692] [0x00007f5d45f57780] [info] Default Device retrieved at index 0
113+
[2026-02-13 18:51:29.963] [thread-id: 3139] [trace] zeCommandQueueCreate(hContext, hDevice, desc, phCommandQueue)
114+
[2026-02-13 18:51:29.963] [thread-id: 3139] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeCommandQueueCreate(hContext=0x5651c0276c48, hDevice=0x5651c1166778, desc={stype=0x7ffdb52dbf90, ordinal=0, index=0, flags=0, mode=0x7ffdb52dbfac, priority=0x7ffdb52dbfb0}, phCommandQueue=0x5651c1192748)
115+
[2026-02-13 18:51:29.963] [thread-id: 3139] [trace] zeCommandListCreate(hContext, hDevice, desc, phCommandList)
116+
[2026-02-13 18:51:29.964] [thread-id: 3139] [trace] SUCCESS (ZE_RESULT_SUCCESS) in zeCommandListCreate(hContext=0x5651c0276c48, hDevice=0x5651c1166778, desc={stype=0x7ffdb52dbf70, commandQueueGroupOrdinal=0, flags=0}, phCommandList=0x5651c119af68)
117+
[2026-02-13 18:51:29.965] [thread-id: 3139] [trace] zeMemOpenIpcHandle(hContext, hDevice, handle, flags, pptr)
110118
```
111119

112120

scripts/templates/validation/valddi.cpp.mako

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,32 @@ namespace validation_layer
7171
%else:
7272
std::ostringstream oss;
7373
oss << status << " (" << loader::to_string(result) << ") in ${func_name}(";
74-
%for i, param in enumerate([p for p in th.make_param_lines(n, tags, obj, format=['name'])]):
74+
<%
75+
params_list = obj.get('params', [])
76+
%>
77+
%for i, param_name in enumerate([p for p in th.make_param_lines(n, tags, obj, format=['name'])]):
78+
<%
79+
# Get parameter metadata
80+
param_obj = params_list[i] if i < len(params_list) else None
81+
param_type = param_obj.get('type', '') if param_obj else ''
82+
param_desc = param_obj.get('desc', '') if param_obj else ''
83+
is_output_param = '[out]' in param_desc
84+
is_pointer = '*' in param_type and param_type.strip().endswith('*')
85+
%>
7586
%if i > 0:
7687
oss << ", ";
7788
%endif
78-
oss << "${param}=" << loader::to_string(${param});
89+
oss << "${param_name}=";
90+
%if is_output_param and is_pointer:
91+
// Dereference output parameter if not null and result is success
92+
if (result == ${X}_RESULT_SUCCESS && ${param_name} != nullptr) {
93+
oss << loader::to_string(*${param_name});
94+
} else {
95+
oss << loader::to_string(${param_name});
96+
}
97+
%else:
98+
oss << loader::to_string(${param_name});
99+
%endif
79100
%endfor
80101
oss << ")";
81102
context.logger->log_trace(oss.str());
@@ -102,7 +123,14 @@ namespace validation_layer
102123
<< "hContext=" << static_cast<const void*>(hContext) << ", "
103124
<< "hDevice=" << static_cast<const void*>(hDevice) << ", "
104125
<< "desc=" << desc << ", "
105-
<< "phEvent=" << static_cast<const void*>(phEvent) << ")";
126+
<< "phEvent=";
127+
// Dereference output parameter if not null and result is success
128+
if (result == ${X}_RESULT_SUCCESS && phEvent != nullptr) {
129+
oss << loader::to_string(*phEvent);
130+
} else {
131+
oss << static_cast<const void*>(phEvent);
132+
}
133+
oss << ")";
106134
context.logger->log_trace(oss.str());
107135
return result;
108136
}

0 commit comments

Comments
 (0)