Skip to content

Commit 5187acd

Browse files
authored
update leak checker for experimental function (#376)
* update leak checker for experimental function Signed-off-by: Mateusz P. Nowak <mateusz.p.nowak@intel.com>
1 parent 7ae9d18 commit 5187acd

10 files changed

Lines changed: 260 additions & 1 deletion

File tree

scripts/templates/validation/entry_points.h.mako

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ ${line} \
3838
%endfor
3939
, ze_result_t result) {return ZE_RESULT_SUCCESS;}
4040
%endfor
41+
%if n == 'ze':
42+
// Experimental Intel extension for counter-based events
43+
virtual ze_result_t zexCounterBasedEventCreate2Prologue( ze_context_handle_t hContext, ze_device_handle_t hDevice, const void* desc, ze_event_handle_t* phEvent ) {return ZE_RESULT_SUCCESS;}
44+
virtual ze_result_t zexCounterBasedEventCreate2Epilogue( ze_context_handle_t hContext, ze_device_handle_t hDevice, const void* desc, ze_event_handle_t* phEvent , ze_result_t result) {return ZE_RESULT_SUCCESS;}
45+
%endif
4146
virtual ~${N}ValidationEntryPoints() {}
4247
};
4348
}

scripts/templates/validation/handle_lifetime.cpp.mako

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,4 +91,21 @@ namespace validation_layer
9191
}
9292
%endif
9393
%endfor
94+
%if n == 'ze':
95+
ze_result_t ZEHandleLifetimeValidation::zexCounterBasedEventCreate2Prologue(
96+
ze_context_handle_t hContext, ///< [in] handle of the context object
97+
ze_device_handle_t hDevice, ///< [in] handle of the device
98+
const void *desc, ///< [in] pointer to counter-based event descriptor
99+
ze_event_handle_t *phEvent ///< [out] pointer to handle of event object created
100+
)
101+
{
102+
if (!context.handleLifetime->isHandleValid(hContext)) {
103+
return ZE_RESULT_ERROR_INVALID_NULL_HANDLE;
104+
}
105+
if (!context.handleLifetime->isHandleValid(hDevice)) {
106+
return ZE_RESULT_ERROR_INVALID_NULL_HANDLE;
107+
}
108+
return ZE_RESULT_SUCCESS;
109+
}
110+
%endif
94111
}

scripts/templates/validation/handle_lifetime.h.mako

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ ${line} \
3838
%endfor
3939
) override;
4040
%endfor
41+
%if n == 'ze':
42+
// Experimental function for Intel counter-based events
43+
ze_result_t zexCounterBasedEventCreate2Prologue(ze_context_handle_t hContext, ze_device_handle_t hDevice, const void *desc, ze_event_handle_t *phEvent) override;
44+
%endif
4145
};
4246

4347
}

scripts/templates/validation/valddi.cpp.mako

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@ from templates import helper as th
2222

2323
namespace validation_layer
2424
{
25+
%if n == 'ze':
26+
// Forward declaration for Intel experimental extension
27+
// This is needed because zeDriverGetExtensionFunctionAddress needs to reference zexCounterBasedEventCreate2
28+
__zedlllocal ze_result_t ZE_APICALL zexCounterBasedEventCreate2(
29+
ze_context_handle_t hContext,
30+
ze_device_handle_t hDevice,
31+
const void *desc,
32+
ze_event_handle_t *phEvent
33+
);
34+
35+
%endif
2536
static ze_result_t logAndPropagateResult(const char* fname, ze_result_t result) {
2637
if (result != ${X}_RESULT_SUCCESS) {
2738
context.logger->log_trace("Error (" + loader::to_string(result) + ") in " + std::string(fname));
@@ -78,6 +89,17 @@ ${line} \
7889
}
7990

8091
auto driver_result = ${th.make_pfn_name(n, tags, obj)}( ${", ".join(th.make_param_lines(n, tags, obj, format=["name"]))} );
92+
%if 'ppFunctionAddress' in [p.get('name', '') for p in obj.get('params', [])] and n == 'ze':
93+
94+
// For Intel experimental extensions, we need to return our validation layer function
95+
// instead of the raw driver function so that validation/leak tracking works
96+
if (driver_result == ZE_RESULT_SUCCESS && ppFunctionAddress && name) {
97+
if (strcmp(name, "zexCounterBasedEventCreate2") == 0) {
98+
// Return our validation layer intercept function instead of the raw driver function
99+
*ppFunctionAddress = (void*)zexCounterBasedEventCreate2;
100+
}
101+
}
102+
%endif
81103

82104
for (size_t i = 0; i < numValHandlers; i++) {
83105
auto result = context.validationHandlers[i]->${n}Validation->${th.make_func_name(n, tags, obj)}Epilogue( \
@@ -127,6 +149,89 @@ ${line} \
127149
%endif
128150

129151
%endfor
152+
%if n == 'ze':
153+
///////////////////////////////////////////////////////////////////////////////
154+
/// @brief Intercept function for zexCounterBasedEventCreate2
155+
__zedlllocal ze_result_t ZE_APICALL zexCounterBasedEventCreate2(
156+
ze_context_handle_t hContext, ///< [in] handle of the context object
157+
ze_device_handle_t hDevice, ///< [in] handle of the device
158+
const void* desc, ///< [in] pointer to counter-based event descriptor
159+
ze_event_handle_t* phEvent ///< [out] pointer to handle of event object created
160+
)
161+
{
162+
context.logger->log_trace("zexCounterBasedEventCreate2(hContext, hDevice, desc, phEvent)");
163+
164+
// Note: This is an experimental function that may not have a DDI table entry.
165+
// For now, we'll return unsupported feature as this function should be
166+
// accessed through zeDriverGetExtensionFunctionAddress mechanism, but we
167+
// still want to track it in the validation layers for leak checking purposes.
168+
169+
auto numValHandlers = context.validationHandlers.size();
170+
for (size_t i = 0; i < numValHandlers; i++) {
171+
auto result = context.validationHandlers[i]->zeValidation->zexCounterBasedEventCreate2Prologue( hContext, hDevice, desc, phEvent );
172+
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult("zexCounterBasedEventCreate2", result);
173+
}
174+
175+
if(context.enableThreadingValidation){
176+
//Unimplemented
177+
}
178+
179+
if(context.enableHandleLifetime){
180+
auto result = context.handleLifetime->zeHandleLifetime.zexCounterBasedEventCreate2Prologue( hContext, hDevice, desc, phEvent );
181+
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult("zexCounterBasedEventCreate2", result);
182+
}
183+
184+
// This is an experimental function that must be accessed through the extension mechanism
185+
// We need to get the function pointer through zeDriverGetExtensionFunctionAddress
186+
ze_result_t driver_result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
187+
188+
// Get the real Intel experimental function through the extension mechanism
189+
auto pfnGetExtensionFunctionAddress = context.zeDdiTable.Driver.pfnGetExtensionFunctionAddress;
190+
191+
if (pfnGetExtensionFunctionAddress) {
192+
// Get the driver handle - use the first available driver
193+
ze_driver_handle_t hDriver = nullptr;
194+
195+
if (context.zeDdiTable.Driver.pfnGet) {
196+
uint32_t driverCount = 1;
197+
ze_driver_handle_t drivers[1] = {nullptr};
198+
auto result = context.zeDdiTable.Driver.pfnGet(&driverCount, drivers);
199+
if (result == ZE_RESULT_SUCCESS && driverCount > 0) {
200+
hDriver = drivers[0];
201+
}
202+
}
203+
204+
if (hDriver) {
205+
// Get the real Intel experimental function
206+
typedef ze_result_t (*zexCounterBasedEventCreate2_t)(ze_context_handle_t, ze_device_handle_t, const void*, ze_event_handle_t*);
207+
zexCounterBasedEventCreate2_t pfnRealFunction = nullptr;
208+
209+
auto ext_result = pfnGetExtensionFunctionAddress(hDriver, "zexCounterBasedEventCreate2", (void**)&pfnRealFunction);
210+
211+
if (ext_result == ZE_RESULT_SUCCESS && pfnRealFunction) {
212+
// Call the real Intel experimental function
213+
driver_result = pfnRealFunction(hContext, hDevice, desc, phEvent);
214+
} else {
215+
// Extension not available in this driver
216+
driver_result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
217+
}
218+
}
219+
}
220+
221+
for (size_t i = 0; i < numValHandlers; i++) {
222+
auto result = context.validationHandlers[i]->zeValidation->zexCounterBasedEventCreate2Epilogue( hContext, hDevice, desc, phEvent, driver_result);
223+
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult("zexCounterBasedEventCreate2", result);
224+
}
225+
226+
if(driver_result == ZE_RESULT_SUCCESS && context.enableHandleLifetime){
227+
if (phEvent){
228+
context.handleLifetime->addHandle( *phEvent );
229+
// Note: counter-based events may not have a traditional event pool dependency
230+
}
231+
}
232+
return logAndPropagateResult("zexCounterBasedEventCreate2", driver_result);
233+
}
234+
%endif
130235
} // namespace validation_layer
131236

132237
#if defined(__cplusplus)

source/layers/validation/checkers/basic_leak/zel_basic_leak_checker.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ namespace validation_layer
5151
{{"zeKernelCreate"}, {"zeKernelDestroy"}},
5252
{{"zeEventPoolCreate"}, {"zeEventPoolDestroy"}},
5353
{{"zeCommandListCreateImmediate", "zeCommandListCreate"}, {"zeCommandListDestroy"}},
54-
{{"zeEventCreate"}, {"zeEventDestroy"}},
54+
{{"zeEventCreate", "zexCounterBasedEventCreate2"}, {"zeEventDestroy"}},
5555
{{"zeFenceCreate"}, {"zeFenceDestroy"}},
5656
{{"zeImageCreate", "zeImageViewCreateExt"}, {"zeImageDestroy"}},
5757
{{"zeSamplerCreate"}, {"zeSamplerDestroy"}},
@@ -177,6 +177,13 @@ namespace validation_layer
177177
return result;
178178
}
179179

180+
ze_result_t basic_leakChecker::ZEbasic_leakChecker::zexCounterBasedEventCreate2Epilogue(ze_context_handle_t, ze_device_handle_t, const void *, ze_event_handle_t *, ze_result_t result) {
181+
if (result == ZE_RESULT_SUCCESS) {
182+
countFunctionCall("zexCounterBasedEventCreate2");
183+
}
184+
return result;
185+
}
186+
180187
ze_result_t basic_leakChecker::ZEbasic_leakChecker::zeFenceCreateEpilogue(ze_command_queue_handle_t, const ze_fence_desc_t *, ze_fence_handle_t*, ze_result_t result) {
181188
if (result == ZE_RESULT_SUCCESS) {
182189
countFunctionCall("zeFenceCreate");

source/layers/validation/checkers/basic_leak/zel_basic_leak_checker.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ namespace validation_layer
8080
ze_result_t zeMemAllocSharedEpilogue(ze_context_handle_t, const ze_device_mem_alloc_desc_t *, const ze_host_mem_alloc_desc_t *, size_t, size_t, ze_device_handle_t, void **, ze_result_t result) override;
8181
ze_result_t zeMemFreeEpilogue(ze_context_handle_t, void *, ze_result_t result) override;
8282
ze_result_t zeMemFreeExtEpilogue(ze_context_handle_t, const ze_memory_free_ext_desc_t*, void *, ze_result_t result) override;
83+
// Experimental function for Intel counter-based events
84+
ze_result_t zexCounterBasedEventCreate2Epilogue(ze_context_handle_t, ze_device_handle_t, const void *, ze_event_handle_t *, ze_result_t result) override;
8385
private:
8486
void countFunctionCall(const std::string &functionName);
8587
std::unordered_map<std::string, std::atomic<int64_t>> counts;

source/layers/validation/common/ze_entry_points.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,9 @@ class ZEValidationEntryPoints {
423423
virtual ze_result_t zeCommandListUpdateMutableCommandWaitEventsExpEpilogue( ze_command_list_handle_t hCommandList, uint64_t commandId, uint32_t numWaitEvents, ze_event_handle_t* phWaitEvents , ze_result_t result) {return ZE_RESULT_SUCCESS;}
424424
virtual ze_result_t zeCommandListUpdateMutableCommandKernelsExpPrologue( ze_command_list_handle_t hCommandList, uint32_t numKernels, uint64_t* pCommandId, ze_kernel_handle_t* phKernels ) {return ZE_RESULT_SUCCESS;}
425425
virtual ze_result_t zeCommandListUpdateMutableCommandKernelsExpEpilogue( ze_command_list_handle_t hCommandList, uint32_t numKernels, uint64_t* pCommandId, ze_kernel_handle_t* phKernels , ze_result_t result) {return ZE_RESULT_SUCCESS;}
426+
// Experimental Intel extension for counter-based events
427+
virtual ze_result_t zexCounterBasedEventCreate2Prologue( ze_context_handle_t hContext, ze_device_handle_t hDevice, const void* desc, ze_event_handle_t* phEvent ) {return ZE_RESULT_SUCCESS;}
428+
virtual ze_result_t zexCounterBasedEventCreate2Epilogue( ze_context_handle_t hContext, ze_device_handle_t hDevice, const void* desc, ze_event_handle_t* phEvent , ze_result_t result) {return ZE_RESULT_SUCCESS;}
426429
virtual ~ZEValidationEntryPoints() {}
427430
};
428431
}

source/layers/validation/handle_lifetime_tracking/ze_handle_lifetime.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3494,4 +3494,19 @@ namespace validation_layer
34943494
}
34953495
return ZE_RESULT_SUCCESS;
34963496
}
3497+
ze_result_t ZEHandleLifetimeValidation::zexCounterBasedEventCreate2Prologue(
3498+
ze_context_handle_t hContext, ///< [in] handle of the context object
3499+
ze_device_handle_t hDevice, ///< [in] handle of the device
3500+
const void *desc, ///< [in] pointer to counter-based event descriptor
3501+
ze_event_handle_t *phEvent ///< [out] pointer to handle of event object created
3502+
)
3503+
{
3504+
if (!context.handleLifetime->isHandleValid(hContext)) {
3505+
return ZE_RESULT_ERROR_INVALID_NULL_HANDLE;
3506+
}
3507+
if (!context.handleLifetime->isHandleValid(hDevice)) {
3508+
return ZE_RESULT_ERROR_INVALID_NULL_HANDLE;
3509+
}
3510+
return ZE_RESULT_SUCCESS;
3511+
}
34973512
}

source/layers/validation/handle_lifetime_tracking/ze_handle_lifetime.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ namespace validation_layer
219219
ze_result_t zeCommandListUpdateMutableCommandSignalEventExpPrologue( ze_command_list_handle_t hCommandList, uint64_t commandId, ze_event_handle_t hSignalEvent ) override;
220220
ze_result_t zeCommandListUpdateMutableCommandWaitEventsExpPrologue( ze_command_list_handle_t hCommandList, uint64_t commandId, uint32_t numWaitEvents, ze_event_handle_t* phWaitEvents ) override;
221221
ze_result_t zeCommandListUpdateMutableCommandKernelsExpPrologue( ze_command_list_handle_t hCommandList, uint32_t numKernels, uint64_t* pCommandId, ze_kernel_handle_t* phKernels ) override;
222+
// Experimental function for Intel counter-based events
223+
ze_result_t zexCounterBasedEventCreate2Prologue(ze_context_handle_t hContext, ze_device_handle_t hDevice, const void *desc, ze_event_handle_t *phEvent) override;
222224
};
223225

224226
}

source/layers/validation/ze_valddi.cpp

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@
1313

1414
namespace validation_layer
1515
{
16+
// Forward declaration for Intel experimental extension
17+
// This is needed because zeDriverGetExtensionFunctionAddress needs to reference zexCounterBasedEventCreate2
18+
__zedlllocal ze_result_t ZE_APICALL zexCounterBasedEventCreate2(
19+
ze_context_handle_t hContext,
20+
ze_device_handle_t hDevice,
21+
const void *desc,
22+
ze_event_handle_t *phEvent
23+
);
24+
1625
static ze_result_t logAndPropagateResult(const char* fname, ze_result_t result) {
1726
if (result != ZE_RESULT_SUCCESS) {
1827
context.logger->log_trace("Error (" + loader::to_string(result) + ") in " + std::string(fname));
@@ -382,6 +391,15 @@ namespace validation_layer
382391

383392
auto driver_result = pfnGetExtensionFunctionAddress( hDriver, name, ppFunctionAddress );
384393

394+
// For Intel experimental extensions, we need to return our validation layer function
395+
// instead of the raw driver function so that validation/leak tracking works
396+
if (driver_result == ZE_RESULT_SUCCESS && ppFunctionAddress && name) {
397+
if (strcmp(name, "zexCounterBasedEventCreate2") == 0) {
398+
// Return our validation layer intercept function instead of the raw driver function
399+
*ppFunctionAddress = (void*)zexCounterBasedEventCreate2;
400+
}
401+
}
402+
385403
for (size_t i = 0; i < numValHandlers; i++) {
386404
auto result = context.validationHandlers[i]->zeValidation->zeDriverGetExtensionFunctionAddressEpilogue( hDriver, name, ppFunctionAddress ,driver_result);
387405
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult("zeDriverGetExtensionFunctionAddress", result);
@@ -9412,6 +9430,87 @@ namespace validation_layer
94129430
return logAndPropagateResult("zeCommandListUpdateMutableCommandKernelsExp", driver_result);
94139431
}
94149432

9433+
///////////////////////////////////////////////////////////////////////////////
9434+
/// @brief Intercept function for zexCounterBasedEventCreate2
9435+
__zedlllocal ze_result_t ZE_APICALL zexCounterBasedEventCreate2(
9436+
ze_context_handle_t hContext, ///< [in] handle of the context object
9437+
ze_device_handle_t hDevice, ///< [in] handle of the device
9438+
const void* desc, ///< [in] pointer to counter-based event descriptor
9439+
ze_event_handle_t* phEvent ///< [out] pointer to handle of event object created
9440+
)
9441+
{
9442+
context.logger->log_trace("zexCounterBasedEventCreate2(hContext, hDevice, desc, phEvent)");
9443+
9444+
// Note: This is an experimental function that may not have a DDI table entry.
9445+
// For now, we'll return unsupported feature as this function should be
9446+
// accessed through zeDriverGetExtensionFunctionAddress mechanism, but we
9447+
// still want to track it in the validation layers for leak checking purposes.
9448+
9449+
auto numValHandlers = context.validationHandlers.size();
9450+
for (size_t i = 0; i < numValHandlers; i++) {
9451+
auto result = context.validationHandlers[i]->zeValidation->zexCounterBasedEventCreate2Prologue( hContext, hDevice, desc, phEvent );
9452+
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult("zexCounterBasedEventCreate2", result);
9453+
}
9454+
9455+
if(context.enableThreadingValidation){
9456+
//Unimplemented
9457+
}
9458+
9459+
if(context.enableHandleLifetime){
9460+
auto result = context.handleLifetime->zeHandleLifetime.zexCounterBasedEventCreate2Prologue( hContext, hDevice, desc, phEvent );
9461+
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult("zexCounterBasedEventCreate2", result);
9462+
}
9463+
9464+
// This is an experimental function that must be accessed through the extension mechanism
9465+
// We need to get the function pointer through zeDriverGetExtensionFunctionAddress
9466+
ze_result_t driver_result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
9467+
9468+
// Get the real Intel experimental function through the extension mechanism
9469+
auto pfnGetExtensionFunctionAddress = context.zeDdiTable.Driver.pfnGetExtensionFunctionAddress;
9470+
9471+
if (pfnGetExtensionFunctionAddress) {
9472+
// Get the driver handle - use the first available driver
9473+
ze_driver_handle_t hDriver = nullptr;
9474+
9475+
if (context.zeDdiTable.Driver.pfnGet) {
9476+
uint32_t driverCount = 1;
9477+
ze_driver_handle_t drivers[1] = {nullptr};
9478+
auto result = context.zeDdiTable.Driver.pfnGet(&driverCount, drivers);
9479+
if (result == ZE_RESULT_SUCCESS && driverCount > 0) {
9480+
hDriver = drivers[0];
9481+
}
9482+
}
9483+
9484+
if (hDriver) {
9485+
// Get the real Intel experimental function
9486+
typedef ze_result_t (*zexCounterBasedEventCreate2_t)(ze_context_handle_t, ze_device_handle_t, const void*, ze_event_handle_t*);
9487+
zexCounterBasedEventCreate2_t pfnRealFunction = nullptr;
9488+
9489+
auto ext_result = pfnGetExtensionFunctionAddress(hDriver, "zexCounterBasedEventCreate2", (void**)&pfnRealFunction);
9490+
9491+
if (ext_result == ZE_RESULT_SUCCESS && pfnRealFunction) {
9492+
// Call the real Intel experimental function
9493+
driver_result = pfnRealFunction(hContext, hDevice, desc, phEvent);
9494+
} else {
9495+
// Extension not available in this driver
9496+
driver_result = ZE_RESULT_ERROR_UNSUPPORTED_FEATURE;
9497+
}
9498+
}
9499+
}
9500+
9501+
for (size_t i = 0; i < numValHandlers; i++) {
9502+
auto result = context.validationHandlers[i]->zeValidation->zexCounterBasedEventCreate2Epilogue( hContext, hDevice, desc, phEvent, driver_result);
9503+
if(result!=ZE_RESULT_SUCCESS) return logAndPropagateResult("zexCounterBasedEventCreate2", result);
9504+
}
9505+
9506+
if(driver_result == ZE_RESULT_SUCCESS && context.enableHandleLifetime){
9507+
if (phEvent){
9508+
context.handleLifetime->addHandle( *phEvent );
9509+
// Note: counter-based events may not have a traditional event pool dependency
9510+
}
9511+
}
9512+
return logAndPropagateResult("zexCounterBasedEventCreate2", driver_result);
9513+
}
94159514
} // namespace validation_layer
94169515

94179516
#if defined(__cplusplus)

0 commit comments

Comments
 (0)