Skip to content

Commit bb8ce34

Browse files
committed
fix static loader to work with new api
Signed-off-by: Neil R. Spruit <neil.r.spruit@intel.com>
1 parent 207589a commit bb8ce34

File tree

4 files changed

+65
-24
lines changed

4 files changed

+65
-24
lines changed

doc/loader_api.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,25 @@ This document does not cover APIs specific to individual layers (ie. tracing) or
99

1010
Exposed Loader APIs will be defined in header files located in this repository at `include/loader`, and installed to `<prefix>/include/level_zero/loader`
1111

12+
### zelGetLoaderVersion
13+
14+
This API is used to retrieve the version information of the loader itself. Unlike `zelLoaderGetVersions`, this API provides a simplified interface to get only the loader's version without needing to query all components.
15+
16+
- __*version__ Pointer to a `zel_component_version_t` structure that will be filled with the loader's version information. Must be a valid, non-null pointer.
17+
18+
This function:
19+
- Returns `ZE_RESULT_SUCCESS` on successful retrieval of the loader version
20+
- Returns `ZE_RESULT_ERROR_INVALID_NULL_POINTER` if `version` is `nullptr`
21+
- Returns `ZE_RESULT_ERROR_UNINITIALIZED` if the loader library cannot be found or loaded (only possible in static builds with misconfigured library paths)
22+
- Does not require `zeInit()` or `zeInitDrivers()` to be called prior to invocation
23+
- Works with both static and dynamic loader builds without initialization
24+
- Is thread-safe and can be called from multiple threads
25+
26+
The returned `zel_component_version_t` structure contains:
27+
- `component_name`: Set to `"loader"`
28+
- `spec_version`: The Level Zero API specification version (`ZE_API_VERSION_CURRENT`)
29+
- `component_lib_version`: The loader library version with `major`, `minor`, and `patch` fields
30+
1231
### zelLoaderGetVersions
1332

1433
This API is used to retreive the version information of the loader itself and of any layers that are enabled.
@@ -50,3 +69,5 @@ Disables the tracing layer intercepts at runtime by restoring the previous call
5069
This does not unload the tracing layer library such that one can call `zelEnableTracingLayer` and `zelDisableTracingLayer` as many times one needs to during the application.
5170

5271
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`.
72+
73+

include/loader/ze_loader.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,10 @@ zelLoaderGetVersions(
7878
* version details (e.g., major, minor, patch), allowing applications to
7979
* query and validate the loader's compatibility at runtime.
8080
*
81-
* Does not require zeInitDrivers to be called prior to invocation unless the
82-
* application is using a static build of the loader.
81+
* Does not require zeInit() or zeInitDrivers() to be called prior to invocation.
82+
* Works with both static and dynamic loader builds without initialization.
8383
*
84-
* Thread-safety: This function is typically safe to call from multiple threads.
84+
* Thread-safety: This function is safe to call from multiple threads.
8585
* The implementation does not modify global state other than filling the
8686
* supplied version structure.
8787
*
@@ -92,8 +92,8 @@ zelLoaderGetVersions(
9292
* @return
9393
* - ZE_RESULT_SUCCESS on successful retrieval of the loader version.
9494
* - ZE_RESULT_ERROR_INVALID_NULL_POINTER if version is nullptr.
95-
* - ZE_RESULT_ERROR_UNINITIALIZED if the loader is not properly initialized.
96-
* NOTE: this error only occurs with a static loader build.
95+
* - ZE_RESULT_ERROR_UNINITIALIZED if the loader library cannot be found or loaded
96+
* (only possible in static builds with misconfigured library paths).
9797
* - Other ze_result_t error codes on failure conditions as defined by the API.
9898
*
9999
* @note The caller owns the memory for the version structure and must ensure

source/lib/ze_lib.cpp

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -394,12 +394,44 @@ zelGetLoaderVersion(
394394
zel_component_version_t *version) //Pointer to version structure to be filled with loader version information
395395
{
396396
#ifdef L0_STATIC_LOADER_BUILD
397-
if(!ze_lib::context || nullptr == ze_lib::context->loader)
398-
return ZE_RESULT_ERROR_UNINITIALIZED;
397+
// zelLoaderGetVersion doesn't require initialization, so we can load the library temporarily if needed
398+
HMODULE loaderHandle = nullptr;
399+
bool temporaryLoad = false;
400+
401+
if(ze_lib::context && ze_lib::context->loader) {
402+
// Use existing loader
403+
loaderHandle = ze_lib::context->loader;
404+
} else {
405+
// Temporarily load the loader library to get version info
406+
std::string loaderLibraryPath;
407+
auto loaderLibraryPathEnv = getenv_string("ZEL_LIBRARY_PATH");
408+
if (!loaderLibraryPathEnv.empty()) {
409+
loaderLibraryPath = loaderLibraryPathEnv;
410+
}
411+
#ifdef _WIN32
412+
else {
413+
loaderLibraryPath = readLevelZeroLoaderLibraryPath();
414+
}
415+
#endif
416+
std::string loaderFullLibraryPath = create_library_path(MAKE_LIBRARY_NAME( "ze_loader", L0_LOADER_VERSION), loaderLibraryPath.c_str());
417+
loaderHandle = LOAD_DRIVER_LIBRARY(loaderFullLibraryPath.c_str());
418+
if (nullptr == loaderHandle) {
419+
return ZE_RESULT_ERROR_UNINITIALIZED;
420+
}
421+
temporaryLoad = true;
422+
}
423+
399424
typedef ze_result_t (ZE_APICALL *zelLoaderGetVersion_t)(zel_component_version_t *version);
400425
auto getVersion = reinterpret_cast<zelLoaderGetVersion_t>(
401-
GET_FUNCTION_PTR(ze_lib::context->loader, "zelLoaderGetVersion") );
402-
return getVersion(version);
426+
GET_FUNCTION_PTR(loaderHandle, "zelLoaderGetVersion") );
427+
ze_result_t result = getVersion(version);
428+
429+
// Clean up temporary load
430+
if (temporaryLoad && loaderHandle) {
431+
FREE_DRIVER_LIBRARY(loaderHandle);
432+
}
433+
434+
return result;
403435
#else
404436
return zelLoaderGetVersion(version);
405437
#endif

test/loader_api.cpp

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -136,19 +136,14 @@ TEST(
136136

137137
zel_component_version_t version = {};
138138

139-
#ifdef L0_STATIC_LOADER_BUILD
140-
// Static build: requires initialization
141-
EXPECT_EQ(ZE_RESULT_ERROR_UNINITIALIZED, zelGetLoaderVersion(&version));
142-
#else
143-
// Dynamic build: works without initialization
139+
// Both static and dynamic builds: works without initialization
144140
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetLoaderVersion(&version));
145141

146142
EXPECT_STREQ(version.component_name, "loader");
147143
EXPECT_GT(version.spec_version, 0);
148144
EXPECT_GE(version.component_lib_version.major, 0);
149145
EXPECT_GE(version.component_lib_version.minor, 0);
150146
EXPECT_GE(version.component_lib_version.patch, 0);
151-
#endif
152147
}
153148

154149
TEST(
@@ -158,13 +153,8 @@ TEST(
158153
// Get version before initialization
159154
zel_component_version_t version_before = {};
160155

161-
#ifdef L0_STATIC_LOADER_BUILD
162-
// Static build: should fail before init
163-
EXPECT_EQ(ZE_RESULT_ERROR_UNINITIALIZED, zelGetLoaderVersion(&version_before));
164-
#else
165-
// Dynamic build: should work before init
156+
// Both static and dynamic builds: should work before init
166157
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetLoaderVersion(&version_before));
167-
#endif
168158

169159
// Initialize drivers
170160
uint32_t pCount = 0;
@@ -177,14 +167,12 @@ TEST(
177167
zel_component_version_t version_after = {};
178168
EXPECT_EQ(ZE_RESULT_SUCCESS, zelGetLoaderVersion(&version_after));
179169

180-
#ifndef L0_STATIC_LOADER_BUILD
181-
// Dynamic build: verify both versions match
170+
// Verify both versions match
182171
EXPECT_STREQ(version_before.component_name, version_after.component_name);
183172
EXPECT_EQ(version_before.spec_version, version_after.spec_version);
184173
EXPECT_EQ(version_before.component_lib_version.major, version_after.component_lib_version.major);
185174
EXPECT_EQ(version_before.component_lib_version.minor, version_after.component_lib_version.minor);
186175
EXPECT_EQ(version_before.component_lib_version.patch, version_after.component_lib_version.patch);
187-
#endif
188176
}
189177

190178
TEST(

0 commit comments

Comments
 (0)