Skip to content

Commit 25476c3

Browse files
committed
[L0] Implement Support for zeInitDrivers
- As of v1.10 of the L0 spec, zeInit and zeDriverGet is the old init pathway and the desired init api is zeInitDrivers. This new api allows for multi heterogenous drivers to coexist in a single L0 Process. Signed-off-by: Neil R. Spruit <neil.r.spruit@intel.com>
1 parent e9d94b1 commit 25476c3

File tree

4 files changed

+166
-24
lines changed

4 files changed

+166
-24
lines changed

.github/workflows/build-fuzz-reusable.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141
4242
- name: Build level zero with gcc
4343
run: |
44-
git clone -b v1.17.6 --depth=1 https://github.com/oneapi-src/level-zero.git ${{github.workspace}}/level-zero
44+
git clone -b v1.18.5 --depth=1 https://github.com/oneapi-src/level-zero.git ${{github.workspace}}/level-zero
4545
cd ${{github.workspace}}/level-zero
4646
cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++
4747
cmake --build build -j $(nproc)

cmake/FetchLevelZero.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ if (NOT DEFINED LEVEL_ZERO_LIBRARY OR NOT DEFINED LEVEL_ZERO_INCLUDE_DIR)
4040
set(UR_LEVEL_ZERO_LOADER_REPO "https://github.com/oneapi-src/level-zero.git")
4141
endif()
4242
if (UR_LEVEL_ZERO_LOADER_TAG STREQUAL "")
43-
set(UR_LEVEL_ZERO_LOADER_TAG v1.18.5)
43+
set(UR_LEVEL_ZERO_LOADER_TAG v1.19.2)
4444
endif()
4545

4646
# Disable due to a bug https://github.com/oneapi-src/level-zero/issues/104

source/adapters/level_zero/adapter.cpp

Lines changed: 155 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -76,19 +76,91 @@ ur_result_t getZesDeviceHandle(zes_uuid_t coreDeviceUuid,
7676
return UR_RESULT_ERROR_INVALID_ARGUMENT;
7777
}
7878

79+
/**
80+
* @brief Initializes the platforms by querying Level Zero drivers and devices.
81+
*
82+
* This function initializes the platforms by querying the available Level Zero
83+
* drivers and devices. It handles different behaviors based on the presence of
84+
* drivers obtained through `zeDriverGet` and initialized drivers through
85+
* `zeInitDrivers`.
86+
*
87+
* @param platforms A vector to store the initialized platform handles.
88+
* @param ZesResult The result of a previous ZES (Level Zero System) operation.
89+
* @return ur_result_t The result of the initialization process.
90+
*
91+
* The function performs the following steps:
92+
* 1. Queries the number of Level Zero drivers using `zeDriverGet`.
93+
* 2. If drivers are found, it retrieves their handles.
94+
* 3. If no drivers are found in either `zeInitDrivers` or `zeDriverGet`,
95+
* it logs a message and returns success.
96+
* 4. If `zeInitDrivers` is supported by the global adapter, it retrieves
97+
* their handles and properties.
98+
* 5. It compares the drivers obtained from `zeDriverGet` and `zeInitDrivers`,
99+
* adding unique drivers to the list.
100+
* 6. If `zeInitDrivers` is not supported, it uses the drivers obtained
101+
* from `zeDriverGet`.
102+
* 7. For each driver, it queries the devices and checks if they are GPU
103+
* devices.
104+
* 8. If a GPU device is found, it initializes a platform for the driver and
105+
* adds it to the platforms vector.
106+
* 9. If ZES operations are successful, it populates the ZES/ZE device mapping
107+
* for the devices into the platform.
108+
* 10. The function handles exceptions and returns the appropriate result.
109+
*/
79110
ur_result_t initPlatforms(PlatformVec &platforms,
80111
ze_result_t ZesResult) noexcept try {
112+
std::vector<ze_driver_handle_t> ZeDrivers;
113+
std::vector<ze_driver_handle_t> ZeDriverGetHandles;
114+
std::vector<ze_driver_handle_t> ZeInitDriversHandles;
115+
std::vector<ze_device_handle_t> ZeDevices;
81116
uint32_t ZeDriverCount = 0;
82-
ZE2UR_CALL(zeDriverGet, (&ZeDriverCount, nullptr));
83-
if (ZeDriverCount == 0) {
117+
uint32_t ZeDriverGetCount = 0;
118+
119+
auto ZeDriverGetResult =
120+
ZE_CALL_NOCHECK(zeDriverGet, (&ZeDriverGetCount, nullptr));
121+
if (ZeDriverGetCount > 0 && ZeDriverGetResult == ZE_RESULT_SUCCESS) {
122+
ZeDriverGetHandles.resize(ZeDriverGetCount);
123+
ZE2UR_CALL(zeDriverGet, (&ZeDriverGetCount, ZeDriverGetHandles.data()));
124+
}
125+
if (ZeDriverGetCount == 0 && GlobalAdapter->ZeInitDriversCount == 0) {
126+
logger::debug("\nNo Valid L0 Drivers found.\n");
84127
return UR_RESULT_SUCCESS;
85128
}
86129

87-
std::vector<ze_driver_handle_t> ZeDrivers;
88-
std::vector<ze_device_handle_t> ZeDevices;
89-
ZeDrivers.resize(ZeDriverCount);
90-
91-
ZE2UR_CALL(zeDriverGet, (&ZeDriverCount, ZeDrivers.data()));
130+
if (GlobalAdapter->InitDriversSupported) {
131+
ZeInitDriversHandles.resize(GlobalAdapter->ZeInitDriversCount);
132+
ZeDrivers.resize(GlobalAdapter->ZeInitDriversCount);
133+
ZE2UR_CALL(GlobalAdapter->initDriversFunctionPtr,
134+
(&GlobalAdapter->ZeInitDriversCount, ZeInitDriversHandles.data(),
135+
&GlobalAdapter->InitDriversDesc));
136+
ZeDrivers.assign(ZeInitDriversHandles.begin(), ZeInitDriversHandles.end());
137+
if (ZeDriverGetCount > 0 && GlobalAdapter->ZeInitDriversCount > 0) {
138+
for (uint32_t X = 0; X < GlobalAdapter->ZeInitDriversCount; ++X) {
139+
for (uint32_t Y = 0; Y < ZeDriverGetCount; ++Y) {
140+
ZeStruct<ze_driver_properties_t> ZeDriverGetProperties;
141+
ZeStruct<ze_driver_properties_t> ZeInitDriverProperties;
142+
ZE2UR_CALL(zeDriverGetProperties,
143+
(ZeDriverGetHandles[Y], &ZeDriverGetProperties));
144+
ZE2UR_CALL(zeDriverGetProperties,
145+
(ZeInitDriversHandles[X], &ZeInitDriverProperties));
146+
// If zeDriverGet driver is different from zeInitDriver driver, add it
147+
// to the list. This allows for older drivers to be used alongside
148+
// newer drivers.
149+
if (ZeDriverGetProperties.driverVersion !=
150+
ZeInitDriverProperties.driverVersion) {
151+
logger::debug("\nzeDriverHandle {} added to the zeInitDrivers list "
152+
"of possible handles.\n",
153+
ZeDriverGetHandles[Y]);
154+
ZeDrivers.push_back(ZeDriverGetHandles[Y]);
155+
}
156+
}
157+
}
158+
}
159+
} else {
160+
ZeDriverCount = ZeDriverGetCount;
161+
ZeDrivers.resize(ZeDriverCount);
162+
ZeDrivers.assign(ZeDriverGetHandles.begin(), ZeDriverGetHandles.end());
163+
}
92164
for (uint32_t I = 0; I < ZeDriverCount; ++I) {
93165
// Keep track of the first platform init for this Driver
94166
bool DriverPlatformInit = false;
@@ -214,6 +286,15 @@ ur_adapter_handle_t_::ur_adapter_handle_t_()
214286
return std::atoi(UrRet);
215287
}();
216288

289+
// Dynamically load the new L0 apis separately.
290+
// This must be done to avoid attempting to use symbols that do
291+
// not exist in older loader runtimes.
292+
#ifdef _WIN32
293+
HMODULE processHandle = GetModuleHandle(NULL);
294+
#else
295+
HMODULE processHandle = nullptr;
296+
#endif
297+
217298
// initialize level zero only once.
218299
if (GlobalAdapter->ZeResult == std::nullopt) {
219300
// Setting these environment variables before running zeInit will enable
@@ -235,20 +316,80 @@ ur_adapter_handle_t_::ur_adapter_handle_t_()
235316
// called multiple times. Declaring the return value as "static" ensures
236317
// it's only called once.
237318

319+
// Set ZES_ENABLE_SYSMAN by default if the user has not set it.
320+
if (UrSysManEnvInitEnabled) {
321+
setEnvVar("ZES_ENABLE_SYSMAN", "1");
322+
}
323+
238324
// Init with all flags set to enable for all driver types to be init in
239325
// the application.
240326
ze_init_flags_t L0InitFlags = ZE_INIT_FLAG_GPU_ONLY;
241327
if (UrL0InitAllDrivers) {
242328
L0InitFlags |= ZE_INIT_FLAG_VPU_ONLY;
243329
}
244-
245-
// Set ZES_ENABLE_SYSMAN by default if the user has not set it.
246-
if (UrSysManEnvInitEnabled) {
247-
setEnvVar("ZES_ENABLE_SYSMAN", "1");
248-
}
249330
logger::debug("\nzeInit with flags value of {}\n",
250331
static_cast<int>(L0InitFlags));
251-
GlobalAdapter->ZeResult = ZE_CALL_NOCHECK(zeInit, (L0InitFlags));
332+
GlobalAdapter->ZeInitResult = ZE_CALL_NOCHECK(zeInit, (L0InitFlags));
333+
if (*GlobalAdapter->ZeInitResult != ZE_RESULT_SUCCESS) {
334+
logger::debug("\nzeInit failed with {}\n",
335+
*GlobalAdapter->ZeInitResult);
336+
}
337+
338+
bool useInitDrivers = false;
339+
zel_version_t loader_version = {};
340+
size_t num_components;
341+
auto result = zelLoaderGetVersions(&num_components, nullptr);
342+
if (result == ZE_RESULT_SUCCESS) {
343+
zel_component_version_t *versions =
344+
new zel_component_version_t[num_components];
345+
result = zelLoaderGetVersions(&num_components, versions);
346+
if (result == ZE_RESULT_SUCCESS) {
347+
for (size_t i = 0; i < num_components; ++i) {
348+
if (strncmp(versions[i].component_name, "loader",
349+
strlen("loader")) == 0) {
350+
loader_version = versions[i].component_lib_version;
351+
logger::debug("\nLevel Zero Loader Version: {}.{}.{}\n",
352+
loader_version.major, loader_version.minor,
353+
loader_version.patch);
354+
break;
355+
}
356+
}
357+
}
358+
delete[] versions;
359+
if (loader_version.major > 1 ||
360+
(loader_version.major == 1 && loader_version.minor > 19) ||
361+
(loader_version.major == 1 && loader_version.minor == 19 &&
362+
loader_version.patch >= 2)) {
363+
useInitDrivers = true;
364+
}
365+
}
366+
367+
if (useInitDrivers) {
368+
GlobalAdapter->initDriversFunctionPtr =
369+
(ze_pfnInitDrivers_t)ur_loader::LibLoader::getFunctionPtr(
370+
processHandle, "zeInitDrivers");
371+
if (GlobalAdapter->initDriversFunctionPtr) {
372+
logger::debug("\nzeInitDrivers with flags value of {}\n",
373+
static_cast<int>(GlobalAdapter->InitDriversDesc.flags));
374+
GlobalAdapter->ZeInitDriversResult =
375+
ZE_CALL_NOCHECK(GlobalAdapter->initDriversFunctionPtr,
376+
(&GlobalAdapter->ZeInitDriversCount, nullptr,
377+
&GlobalAdapter->InitDriversDesc));
378+
if (*GlobalAdapter->ZeInitDriversResult == ZE_RESULT_SUCCESS) {
379+
GlobalAdapter->InitDriversSupported = true;
380+
} else {
381+
logger::debug("\nzeInitDrivers failed with {}\n",
382+
*GlobalAdapter->ZeInitDriversResult);
383+
}
384+
}
385+
}
386+
387+
if (*GlobalAdapter->ZeInitResult == ZE_RESULT_SUCCESS ||
388+
*GlobalAdapter->ZeInitDriversResult == ZE_RESULT_SUCCESS) {
389+
GlobalAdapter->ZeResult = ZE_RESULT_SUCCESS;
390+
} else {
391+
GlobalAdapter->ZeResult = ZE_RESULT_ERROR_UNINITIALIZED;
392+
}
252393
}
253394
assert(GlobalAdapter->ZeResult !=
254395
std::nullopt); // verify that level-zero is initialized
@@ -260,19 +401,11 @@ ur_adapter_handle_t_::ur_adapter_handle_t_()
260401
return;
261402
}
262403
if (*GlobalAdapter->ZeResult != ZE_RESULT_SUCCESS) {
263-
logger::error("zeInit: Level Zero initialization failure\n");
404+
logger::error("Level Zero initialization failure\n");
264405
result = ze2urResult(*GlobalAdapter->ZeResult);
265406

266407
return;
267408
}
268-
// Dynamically load the new L0 SysMan separate init and new EXP apis
269-
// separately. This must be done to avoid attempting to use symbols that do
270-
// not exist in older loader runtimes.
271-
#ifdef _WIN32
272-
HMODULE processHandle = GetModuleHandle(NULL);
273-
#else
274-
HMODULE processHandle = nullptr;
275-
#endif
276409

277410
// Check if the user has enabled the default L0 SysMan initialization.
278411
const int UrSysmanZesinitEnable = [] {

source/adapters/level_zero/adapter.hpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <optional>
1818
#include <ur/ur.hpp>
1919
#include <ze_api.h>
20+
#include <ze_ddi.h>
2021
#include <zes_ddi.h>
2122

2223
using PlatformVec = std::vector<std::unique_ptr<ur_platform_handle_t_>>;
@@ -31,7 +32,15 @@ struct ur_adapter_handle_t_ {
3132
zes_pfnDriverGetDeviceByUuidExp_t getDeviceByUUIdFunctionPtr = nullptr;
3233
zes_pfnDriverGet_t getSysManDriversFunctionPtr = nullptr;
3334
zes_pfnInit_t sysManInitFunctionPtr = nullptr;
35+
ze_pfnInitDrivers_t initDriversFunctionPtr = nullptr;
36+
ze_init_driver_type_desc_t InitDriversDesc = {
37+
ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC, nullptr,
38+
ZE_INIT_DRIVER_TYPE_FLAG_GPU};
39+
uint32_t ZeInitDriversCount = 0;
40+
bool InitDriversSupported = false;
3441

42+
std::optional<ze_result_t> ZeInitDriversResult;
43+
std::optional<ze_result_t> ZeInitResult;
3544
std::optional<ze_result_t> ZeResult;
3645
std::optional<ze_result_t> ZesResult;
3746
ZeCache<Result<PlatformVec>> PlatformCache;

0 commit comments

Comments
 (0)