Skip to content

Commit 3720ea2

Browse files
committed
Update the tracing of APIs in the validation layer with params
Signed-off-by: Neil R. Spruit <[email protected]>
1 parent 02b7655 commit 3720ea2

File tree

13 files changed

+15741
-2164
lines changed

13 files changed

+15741
-2164
lines changed

scripts/generate_code.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ def _mako_loader_cpp(path, namespace, tags, version, specs, meta):
182182
'handle_lifetime.h.mako' : ('handle_lifetime_tracking', 'handle_lifetime.h'),
183183
'handle_lifetime.cpp.mako' : ('handle_lifetime_tracking', 'handle_lifetime.cpp'),
184184
'certification.h.mako' : ('checkers/certification/generated', 'certification.h'),
185+
'to_string.h.mako' : ('../../utils', 'to_string.h'),
185186
}
186187

187188
def _mako_validation_layer_cpp(path, namespace, tags, version, specs, meta):
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
<%!
2+
import re
3+
from templates import helper as th
4+
%><%
5+
n=namespace
6+
N=n.upper()
7+
8+
x=tags['$x']
9+
X=x.upper()
10+
%>/*
11+
* ***THIS FILE IS GENERATED. ***
12+
* See to_string.h.mako for modifications
13+
*
14+
* Copyright (C) 2025 Intel Corporation
15+
*
16+
* SPDX-License-Identifier: MIT
17+
*
18+
* @file ${name}
19+
*
20+
* to_string functions for Level Zero types
21+
*/
22+
23+
#ifndef _${N}_TO_STRING_H
24+
#define _${N}_TO_STRING_H
25+
26+
#include "${x}_api.h"
27+
#include <string>
28+
#include <sstream>
29+
#include <iomanip>
30+
31+
%if n == 'ze':
32+
namespace loader {
33+
34+
// Forward declarations
35+
std::string to_string(const ${x}_result_t result);
36+
37+
// Pointer to_string
38+
template<typename T>
39+
inline std::string to_string(const T* ptr) {
40+
if (ptr == nullptr) {
41+
return "nullptr";
42+
}
43+
std::ostringstream oss;
44+
oss << "0x" << std::hex << reinterpret_cast<uintptr_t>(ptr);
45+
return oss.str();
46+
}
47+
48+
%else:
49+
// Include ze_to_string.h for common definitions
50+
#include "ze_to_string.h"
51+
52+
namespace loader {
53+
%endif
54+
%if n == 'ze':
55+
// Handle to_string functions
56+
%for obj in th.extract_objs(specs, r"handle"):
57+
inline std::string to_string(${th.make_type_name(n, tags, obj)} handle) {
58+
return to_string(reinterpret_cast<const void*>(handle));
59+
}
60+
61+
%endfor
62+
%endif
63+
%if n == 'ze':
64+
// For primitive types and Level Zero typedef'd types
65+
// Since most Level Zero types are typedef'd to uint32_t, we can't distinguish them by type
66+
inline std::string to_string(uint32_t value) { return std::to_string(value); }
67+
inline std::string to_string(uint64_t value) { return std::to_string(value); }
68+
inline std::string to_string(uint8_t value) { return std::to_string(static_cast<unsigned>(value)); }
69+
inline std::string to_string(uint16_t value) { return std::to_string(value); }
70+
inline std::string to_string(int32_t value) { return std::to_string(value); }
71+
inline std::string to_string(int64_t value) { return std::to_string(value); }
72+
#if SIZE_MAX != UINT64_MAX
73+
inline std::string to_string(size_t value) { return std::to_string(value); }
74+
#endif
75+
inline std::string to_string(double value) { return std::to_string(value); }
76+
inline std::string to_string(const char* str) {
77+
if (!str) return "nullptr";
78+
return std::string("\"") + str + "\"";
79+
}
80+
81+
// Pointer to primitive types - dereference and print value
82+
inline std::string to_string(const uint32_t* ptr) {
83+
if (!ptr) return "nullptr";
84+
return to_string(*ptr);
85+
}
86+
inline std::string to_string(const uint64_t* ptr) {
87+
if (!ptr) return "nullptr";
88+
return to_string(*ptr);
89+
}
90+
inline std::string to_string(const uint8_t* ptr) {
91+
if (!ptr) return "nullptr";
92+
return to_string(*ptr);
93+
}
94+
inline std::string to_string(const uint16_t* ptr) {
95+
if (!ptr) return "nullptr";
96+
return to_string(*ptr);
97+
}
98+
inline std::string to_string(const int32_t* ptr) {
99+
if (!ptr) return "nullptr";
100+
return to_string(*ptr);
101+
}
102+
inline std::string to_string(const int64_t* ptr) {
103+
if (!ptr) return "nullptr";
104+
return to_string(*ptr);
105+
}
106+
#if SIZE_MAX != UINT64_MAX
107+
inline std::string to_string(const size_t* ptr) {
108+
if (!ptr) return "nullptr";
109+
return to_string(*ptr);
110+
}
111+
#endif
112+
inline std::string to_string(const double* ptr) {
113+
if (!ptr) return "nullptr";
114+
return to_string(*ptr);
115+
}
116+
117+
%endif
118+
// Struct to_string functions
119+
%for obj in th.extract_objs(specs, r"struct"):
120+
<%
121+
struct_name = th.make_type_name(n, tags, obj)
122+
%>\
123+
inline std::string to_string(const ${struct_name}* desc) {
124+
if (!desc) return "nullptr";
125+
std::ostringstream oss;
126+
oss << "{";
127+
%for idx, member in enumerate(obj['members']):
128+
%if member['name'] != 'pNext':
129+
<%
130+
# Extract the actual member name without array brackets
131+
member_name_full = member['name']
132+
member_name = member_name_full.split('[')[0] if '[' in member_name_full else member_name_full
133+
is_array = '[' in member_name_full
134+
135+
# Check if member is a pointer or regular value
136+
member_type = member.get('type', '')
137+
if is_array:
138+
# For arrays, just pass the array name (decays to pointer)
139+
member_access = f"desc->{member_name}"
140+
elif '*' in member_type:
141+
# It's already a pointer - pass directly
142+
member_access = f"desc->{member_name}"
143+
else:
144+
# Check if it's a struct type by looking at the type name
145+
# If it contains a struct typename pattern, take its address
146+
if '_t' in member_type and 'uint' not in member_type and 'int' not in member_type and 'size_t' not in member_type:
147+
member_access = f"&desc->{member_name}"
148+
else:
149+
member_access = f"desc->{member_name}"
150+
%>\
151+
%if idx == 0 and member['name'] == 'stype':
152+
oss << "stype=" << to_string(${member_access});
153+
%elif idx == 0:
154+
oss << "${member_name}=" << to_string(${member_access});
155+
%else:
156+
oss << ", ${member_name}=" << to_string(${member_access});
157+
%endif
158+
%endif
159+
%endfor
160+
oss << "}";
161+
return oss.str();
162+
}
163+
164+
inline std::string to_string(const ${struct_name}& desc) {
165+
return to_string(&desc);
166+
}
167+
168+
%endfor
169+
} // namespace loader
170+
171+
#endif // _${N}_TO_STRING_H

scripts/templates/validation/valddi.cpp.mako

Lines changed: 81 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,18 @@ from templates import helper as th
1919
*
2020
*/
2121
#include "${x}_validation_layer.h"
22+
#include <sstream>
23+
24+
// Define a macro for marking potentially unused functions
25+
#if defined(_MSC_VER)
26+
// MSVC doesn't support __attribute__((unused)), just omit the marking
27+
#define VALIDATION_MAYBE_UNUSED
28+
#elif defined(__GNUC__) || defined(__clang__)
29+
// GCC and Clang support __attribute__((unused))
30+
#define VALIDATION_MAYBE_UNUSED __attribute__((unused))
31+
#else
32+
#define VALIDATION_MAYBE_UNUSED
33+
#endif
2234

2335
namespace validation_layer
2436
{
@@ -33,12 +45,68 @@ namespace validation_layer
3345
);
3446

3547
%endif
36-
static ze_result_t logAndPropagateResult(const char* fname, ze_result_t result) {
37-
if (result != ${X}_RESULT_SUCCESS) {
38-
context.logger->log_trace("Error (" + loader::to_string(result) + ") in " + std::string(fname));
39-
}
48+
// Generate specific logAndPropagateResult functions for each API function
49+
%for obj in th.extract_objs(specs, r"function"):
50+
<%
51+
func_name = th.make_func_name(n, tags, obj)
52+
param_lines = [line for line in th.make_param_lines(n, tags, obj, format=['name','delim'])]
53+
param_names = [line for line in th.make_param_lines(n, tags, obj, format=['name'])]
54+
is_void_params = len(param_lines) == 0
55+
%>\
56+
%if 'condition' in obj:
57+
#if ${th.subt(n, tags, obj['condition'])}
58+
%endif
59+
VALIDATION_MAYBE_UNUSED static ze_result_t logAndPropagateResult_${func_name}(
60+
ze_result_t result\
61+
%if not is_void_params:
62+
,
63+
%for line in th.make_param_lines(n, tags, obj):
64+
${line}
65+
%endfor
66+
%endif
67+
) {
68+
std::string status = (result == ${X}_RESULT_SUCCESS) ? "SUCCESS" : "ERROR";
69+
%if is_void_params:
70+
context.logger->log_trace(status + " (" + loader::to_string(result) + ") in ${func_name}()");
71+
%else:
72+
std::ostringstream oss;
73+
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'])]):
75+
%if i > 0:
76+
oss << ", ";
77+
%endif
78+
oss << "${param}=" << loader::to_string(${param});
79+
%endfor
80+
oss << ")";
81+
context.logger->log_trace(oss.str());
82+
%endif
83+
return result;
84+
}
85+
%if 'condition' in obj:
86+
#endif // ${th.subt(n, tags, obj['condition'])}
87+
%endif
88+
%endfor
89+
\
90+
%if n == 'ze':
91+
// Special function for zexCounterBasedEventCreate2
92+
VALIDATION_MAYBE_UNUSED static ze_result_t logAndPropagateResult_zexCounterBasedEventCreate2(
93+
ze_result_t result,
94+
ze_context_handle_t hContext,
95+
ze_device_handle_t hDevice,
96+
const void* desc,
97+
ze_event_handle_t* phEvent
98+
) {
99+
std::string status = (result == ${X}_RESULT_SUCCESS) ? "SUCCESS" : "ERROR";
100+
std::ostringstream oss;
101+
oss << status << " (" << loader::to_string(result) << ") in zexCounterBasedEventCreate2("
102+
<< "hContext=" << static_cast<const void*>(hContext) << ", "
103+
<< "hDevice=" << static_cast<const void*>(hDevice) << ", "
104+
<< "desc=" << desc << ", "
105+
<< "phEvent=" << static_cast<const void*>(phEvent) << ")";
106+
context.logger->log_trace(oss.str());
40107
return result;
41108
}
109+
%endif
42110

43111
%for obj in th.extract_objs(specs, r"function"):
44112
<%
@@ -66,7 +134,7 @@ namespace validation_layer
66134

67135
if( nullptr == ${th.make_pfn_name(n, tags, obj)} )
68136
%if ret_type == "ze_result_t":
69-
return logAndPropagateResult("${th.make_func_name(n, tags, obj)}", ${X}_RESULT_ERROR_UNSUPPORTED_FEATURE);
137+
return logAndPropagateResult_${th.make_func_name(n, tags, obj)}(${X}_RESULT_ERROR_UNSUPPORTED_FEATURE${', ' if not is_void_params else ''}${', '.join(th.make_param_lines(n, tags, obj, format=["name"]))});
70138
%else:
71139
return ${failure_return};
72140
%endif
@@ -80,7 +148,7 @@ ${line} \
80148
);
81149
if(result!=${X}_RESULT_SUCCESS) \
82150
%if ret_type == "ze_result_t":
83-
return logAndPropagateResult("${th.make_func_name(n, tags, obj)}", result);
151+
return logAndPropagateResult_${th.make_func_name(n, tags, obj)}(result${', ' if not is_void_params else ''}${', '.join(th.make_param_lines(n, tags, obj, format=["name"]))});
84152
%else:
85153
return ${failure_return};
86154
%endif
@@ -103,7 +171,7 @@ ${line} \
103171
);
104172
if(result!=${X}_RESULT_SUCCESS) \
105173
%if ret_type == "ze_result_t":
106-
return logAndPropagateResult("${th.make_func_name(n, tags, obj)}", result);
174+
return logAndPropagateResult_${th.make_func_name(n, tags, obj)}(result${', ' if not is_void_params else ''}${', '.join(th.make_param_lines(n, tags, obj, format=["name"]))});
107175
%else:
108176
return ${failure_return};
109177
%endif
@@ -134,7 +202,7 @@ driver_result );
134202
%endif
135203
if(result!=${X}_RESULT_SUCCESS) \
136204
%if ret_type == "ze_result_t":
137-
return logAndPropagateResult("${th.make_func_name(n, tags, obj)}", result);
205+
return logAndPropagateResult_${th.make_func_name(n, tags, obj)}(result${', ' if not is_void_params else ''}${', '.join(th.make_param_lines(n, tags, obj, format=["name"]))});
138206
%else:
139207
return ${failure_return};
140208
%endif
@@ -173,7 +241,7 @@ return ${failure_return};
173241
}
174242
%endif
175243
%if ret_type == "ze_result_t":
176-
return logAndPropagateResult("${th.make_func_name(n, tags, obj)}", driver_result);
244+
return logAndPropagateResult_${th.make_func_name(n, tags, obj)}(driver_result${', ' if not is_void_params else ''}${', '.join(th.make_param_lines(n, tags, obj, format=["name"]))});
177245
%else:
178246
return driver_result;
179247
%endif
@@ -203,7 +271,7 @@ return ${failure_return};
203271
auto numValHandlers = context.validationHandlers.size();
204272
for (size_t i = 0; i < numValHandlers; i++) {
205273
auto result = context.validationHandlers[i]->zeValidation->zexCounterBasedEventCreate2Prologue( hContext, hDevice, desc, phEvent );
206-
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult("zexCounterBasedEventCreate2", result);
274+
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult_zexCounterBasedEventCreate2(result, hContext, hDevice, desc, phEvent);
207275
}
208276

209277
if(context.enableThreadingValidation){
@@ -212,7 +280,7 @@ return ${failure_return};
212280

213281
if(context.enableHandleLifetime){
214282
auto result = context.handleLifetime->zeHandleLifetime.zexCounterBasedEventCreate2Prologue( hContext, hDevice, desc, phEvent );
215-
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult("zexCounterBasedEventCreate2", result);
283+
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult_zexCounterBasedEventCreate2(result, hContext, hDevice, desc, phEvent);
216284
}
217285

218286
// This is an experimental function that must be accessed through the extension mechanism
@@ -254,7 +322,7 @@ return ${failure_return};
254322

255323
for (size_t i = 0; i < numValHandlers; i++) {
256324
auto result = context.validationHandlers[i]->zeValidation->zexCounterBasedEventCreate2Epilogue( hContext, hDevice, desc, phEvent, driver_result);
257-
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult("zexCounterBasedEventCreate2", result);
325+
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult_zexCounterBasedEventCreate2(result, hContext, hDevice, desc, phEvent);
258326
}
259327

260328
if(driver_result == ZE_RESULT_SUCCESS && context.enableHandleLifetime){
@@ -263,7 +331,7 @@ return ${failure_return};
263331
// Note: counter-based events may not have a traditional event pool dependency
264332
}
265333
}
266-
return logAndPropagateResult("zexCounterBasedEventCreate2", driver_result);
334+
return logAndPropagateResult_zexCounterBasedEventCreate2(driver_result, hContext, hDevice, desc, phEvent);
267335
}
268336
%endif
269337
} // namespace validation_layer

0 commit comments

Comments
 (0)