Skip to content

Commit a6208a3

Browse files
authored
Add performance validation layer (#427)
Signed-off-by: Michal Mrozek <michal.mrozek@intel.com>
1 parent b3567ec commit a6208a3

6 files changed

Lines changed: 115 additions & 1 deletion

File tree

source/layers/validation/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,22 @@ Validates:
9090
When this mode is enabled, the certification checker validates API usage against the version supported by the driver or an explicitly specified version.
9191
If an API is used that was introduced in a version higher than the supported version, the checker will return `ZE_RESULT_ERROR_UNSUPPORTED_VERSION`.
9292

93+
### `ZEL_ENABLE_PERFORMANCE_CHECKER`
94+
95+
When this mode is enabled, the performance checker validates API usage against known performance best practices. It can be used to identify potential performance issues in an application and provide recommendations for improvement.
96+
To enable use following environment variable:
97+
```bash
98+
export ZEL_ENABLE_PERFORMANCE_CHECKER=1
99+
export ZEL_ENABLE_LOADER_LOGGING=1
100+
export ZE_ENABLE_VALIDATION_LAYER=1
101+
export ZEL_LOADER_LOG_CONSOLE=1 # Optional: enable console logging for immediate feedback
102+
```
103+
104+
Currently checked things:
105+
- check whether created immediate command lists are not synchrnous
106+
- check whether created immediate command lists are using in order queues
107+
- check whether in order command lists are using copy offload
108+
93109
### `ZEL_ENABLE_SYSTEM_RESOURCE_TRACKER_CHECKER` (Linux Only)
94110

95111
The System Resource Tracker monitors both Level Zero API resources and system resources in real-time. It tracks:

source/layers/validation/checkers/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
add_subdirectory(basic_leak)
22
add_subdirectory(certification)
33
add_subdirectory(events_checker)
4+
add_subdirectory(performance)
45
add_subdirectory(parameter_validation)
56
add_subdirectory(template)
67

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
target_sources(${TARGET_NAME}
2+
PRIVATE
3+
${CMAKE_CURRENT_LIST_DIR}/zel_performance_checker.h
4+
${CMAKE_CURRENT_LIST_DIR}/zel_performance_checker.cpp
5+
)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (C) 2026 Intel Corporation
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*
6+
* @file zel_performance_checker.cpp
7+
*
8+
*/
9+
#include "zel_performance_checker.h"
10+
11+
namespace validation_layer
12+
{
13+
class performanceChecker performance_checker;
14+
15+
performanceChecker::performanceChecker() {
16+
enableperformance = getenv_tobool( "ZEL_ENABLE_PERFORMANCE_CHECKER" );
17+
if(enableperformance) {
18+
performanceChecker::ZEperformanceChecker *zeChecker = new performanceChecker::ZEperformanceChecker;
19+
performanceChecker::ZESperformanceChecker *zesChecker = new performanceChecker::ZESperformanceChecker;
20+
performanceChecker::ZETperformanceChecker *zetChecker = new performanceChecker::ZETperformanceChecker;
21+
performance_checker.zeValidation = zeChecker;
22+
performance_checker.zetValidation = zetChecker;
23+
performance_checker.zesValidation = zesChecker;
24+
validation_layer::context.validationHandlers.push_back(&performance_checker);
25+
}
26+
}
27+
28+
performanceChecker::~performanceChecker() {
29+
if(enableperformance) {
30+
delete performance_checker.zeValidation;
31+
delete performance_checker.zetValidation;
32+
delete performance_checker.zesValidation;
33+
}
34+
}
35+
ze_result_t performanceChecker::ZEperformanceChecker::zeCommandListCreateImmediateEpilogue(ze_context_handle_t, ze_device_handle_t, const ze_command_queue_desc_t* descriptor, ze_command_list_handle_t*, ze_result_t result)
36+
{
37+
if (result == ZE_RESULT_SUCCESS) {
38+
if (descriptor->mode & ZE_COMMAND_QUEUE_MODE_SYNCHRONOUS) {
39+
context.logger->log_performance("Synchronous command queue may cause performance degradation. Consider using asynchronous mode.");
40+
}
41+
if (descriptor->flags & ZE_COMMAND_QUEUE_FLAG_IN_ORDER) {
42+
if (!(descriptor->flags & ZE_COMMAND_QUEUE_FLAG_COPY_OFFLOAD_HINT)) {
43+
context.logger->log_performance("In-order command list created without copy offload hint. Consider using copy offload hint for better performance of copy operations.");
44+
}
45+
}
46+
else {
47+
context.logger->log_performance("Out-of-order command list created. Consider using in-order command lists for better performance.");
48+
}
49+
}
50+
return result;
51+
}
52+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
*
3+
* Copyright (C) 2026 Intel Corporation
4+
*
5+
* SPDX-License-Identifier: MIT
6+
*
7+
* @file zel_performance_checker.h
8+
*
9+
*/
10+
11+
#pragma once
12+
13+
#include <string>
14+
#include "ze_api.h"
15+
#include "ze_validation_layer.h"
16+
17+
namespace validation_layer
18+
{
19+
class __zedlllocal performanceChecker : public validationChecker{
20+
public:
21+
performanceChecker();
22+
~performanceChecker();
23+
24+
class ZEperformanceChecker : public ZEValidationEntryPoints {
25+
ze_result_t zeCommandListCreateImmediateEpilogue(ze_context_handle_t, ze_device_handle_t, const ze_command_queue_desc_t*, ze_command_list_handle_t*, ze_result_t result) override;
26+
};
27+
class ZESperformanceChecker : public ZESValidationEntryPoints {};
28+
class ZETperformanceChecker : public ZETValidationEntryPoints {};
29+
30+
31+
bool enableperformance = false;
32+
};
33+
extern class performanceChecker performance_checker;
34+
}

source/utils/logging.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
*
3-
* Copyright (C) 2024 Intel Corporation
3+
* Copyright (C) 2024-2026 Intel Corporation
44
*
55
* SPDX-License-Identifier: MIT
66
*
@@ -137,6 +137,12 @@ class Logger {
137137
_logger->critical(msg);
138138
}
139139

140+
void log_performance(std::string msg) {
141+
if (!logging_enabled)
142+
return;
143+
_logger->warn("[performance] " + msg);
144+
}
145+
140146
std::shared_ptr<spdlog::logger> get_base_logger(){
141147
return _logger;
142148
}

0 commit comments

Comments
 (0)