Skip to content

Commit 50789b1

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 <[email protected]>
1 parent 9a209aa commit 50789b1

File tree

4 files changed

+102
-24
lines changed

4 files changed

+102
-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 0a681d7642c06d76b3b8d4aab16d4af0b5cabb68)
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: 92 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,56 @@ ur_result_t getZesDeviceHandle(zes_uuid_t coreDeviceUuid,
7878

7979
ur_result_t initPlatforms(PlatformVec &platforms,
8080
ze_result_t ZesResult) noexcept try {
81+
std::vector<ze_driver_handle_t> ZeDrivers;
82+
std::vector<ze_driver_handle_t> ZeDriverGetHandles;
83+
std::vector<ze_driver_handle_t> ZeInitDriversHandles;
84+
std::vector<ze_device_handle_t> ZeDevices;
8185
uint32_t ZeDriverCount = 0;
82-
ZE2UR_CALL(zeDriverGet, (&ZeDriverCount, nullptr));
83-
if (ZeDriverCount == 0) {
86+
uint32_t ZeDriverGetCount = 0;
87+
88+
auto ZeDriverGetResult =
89+
ZE_CALL_NOCHECK(zeDriverGet, (&ZeDriverGetCount, nullptr));
90+
if (ZeDriverGetCount > 0 && ZeDriverGetResult == ZE_RESULT_SUCCESS) {
91+
ZeDriverGetHandles.resize(ZeDriverGetCount);
92+
ZE2UR_CALL(zeDriverGet, (&ZeDriverGetCount, ZeDrivers.data()));
93+
}
94+
if (ZeDriverGetCount == 0 && GlobalAdapter->ZeInitDriversCount == 0) {
8495
return UR_RESULT_SUCCESS;
8596
}
8697

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()));
98+
if (GlobalAdapter->InitDriversSupported) {
99+
ZE2UR_CALL(GlobalAdapter->initDriversFunctionPtr,
100+
(&GlobalAdapter->ZeInitDriversCount, ZeDrivers.data(),
101+
&GlobalAdapter->InitDriversDesc));
102+
ZeInitDriversHandles.resize(GlobalAdapter->ZeInitDriversCount);
103+
ZeDrivers.resize(GlobalAdapter->ZeInitDriversCount);
104+
ZeDrivers.assign(ZeInitDriversHandles.begin(), ZeInitDriversHandles.end());
105+
if (ZeDriverGetCount > 0 && GlobalAdapter->ZeInitDriversCount > 0) {
106+
for (uint32_t X = 0; X < GlobalAdapter->ZeInitDriversCount; ++X) {
107+
for (uint32_t Y = 0; Y < ZeDriverGetCount; ++Y) {
108+
ZeStruct<ze_driver_properties_t> ZeDriverGetProperties;
109+
ZeStruct<ze_driver_properties_t> ZeInitDriverProperties;
110+
ZE2UR_CALL(zeDriverGetProperties,
111+
(ZeDriverGetHandles[Y], &ZeDriverGetProperties));
112+
ZE2UR_CALL(zeDriverGetProperties,
113+
(ZeInitDriversHandles[X], &ZeInitDriverProperties));
114+
// If zeDriverGet driver is different from zeInitDriver driver, add it
115+
// to the list. This allows for older drivers to be used alingside
116+
// newer drivers.
117+
if (ZeDriverGetProperties.uuid.id != ZeInitDriverProperties.uuid.id) {
118+
logger::debug("\nzeDriverHandle {} added to the zeInitDrivers list "
119+
"of possible handles.\n",
120+
ZeDriverGetHandles[Y]);
121+
ZeDrivers.push_back(ZeDriverGetHandles[Y]);
122+
}
123+
}
124+
}
125+
}
126+
} else {
127+
ZeDriverCount = ZeDriverGetCount;
128+
ZeDrivers.resize(ZeDriverCount);
129+
ZeDrivers.assign(ZeDriverGetHandles.begin(), ZeDriverGetHandles.end());
130+
}
92131
for (uint32_t I = 0; I < ZeDriverCount; ++I) {
93132
// Keep track of the first platform init for this Driver
94133
bool DriverPlatformInit = false;
@@ -214,6 +253,15 @@ ur_adapter_handle_t_::ur_adapter_handle_t_()
214253
return std::atoi(UrRet);
215254
}();
216255

256+
// Dynamically load the new L0 apis separately.
257+
// This must be done to avoid attempting to use symbols that do
258+
// not exist in older loader runtimes.
259+
#ifdef _WIN32
260+
HMODULE processHandle = GetModuleHandle(NULL);
261+
#else
262+
HMODULE processHandle = nullptr;
263+
#endif
264+
217265
// initialize level zero only once.
218266
if (GlobalAdapter->ZeResult == std::nullopt) {
219267
// Setting these environment variables before running zeInit will enable
@@ -235,20 +283,50 @@ ur_adapter_handle_t_::ur_adapter_handle_t_()
235283
// called multiple times. Declaring the return value as "static" ensures
236284
// it's only called once.
237285

286+
GlobalAdapter->initDriversFunctionPtr =
287+
(ze_pfnInitDrivers_t)ur_loader::LibLoader::getFunctionPtr(
288+
processHandle, "zeInitDrivers");
289+
290+
// Set ZES_ENABLE_SYSMAN by default if the user has not set it.
291+
if (UrSysManEnvInitEnabled) {
292+
setEnvVar("ZES_ENABLE_SYSMAN", "1");
293+
}
294+
295+
if (GlobalAdapter->initDriversFunctionPtr) {
296+
GlobalAdapter->InitDriversDesc.pNext = nullptr;
297+
GlobalAdapter->InitDriversDesc.flags = ZE_INIT_DRIVER_TYPE_FLAG_GPU;
298+
logger::debug("\nzeInitDrivers with flags value of {}\n",
299+
static_cast<int>(GlobalAdapter->InitDriversDesc.flags));
300+
GlobalAdapter->ZeInitDriversResult =
301+
ZE_CALL_NOCHECK(GlobalAdapter->initDriversFunctionPtr,
302+
(&GlobalAdapter->ZeInitDriversCount, nullptr,
303+
&GlobalAdapter->InitDriversDesc));
304+
if (*GlobalAdapter->ZeInitDriversResult == ZE_RESULT_SUCCESS) {
305+
GlobalAdapter->InitDriversSupported = true;
306+
} else {
307+
logger::debug("\nzeInitDrivers failed with {}\n",
308+
*GlobalAdapter->ZeInitDriversResult);
309+
}
310+
}
238311
// Init with all flags set to enable for all driver types to be init in
239312
// the application.
240313
ze_init_flags_t L0InitFlags = ZE_INIT_FLAG_GPU_ONLY;
241314
if (UrL0InitAllDrivers) {
242315
L0InitFlags |= ZE_INIT_FLAG_VPU_ONLY;
243316
}
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-
}
249317
logger::debug("\nzeInit with flags value of {}\n",
250318
static_cast<int>(L0InitFlags));
251-
GlobalAdapter->ZeResult = ZE_CALL_NOCHECK(zeInit, (L0InitFlags));
319+
GlobalAdapter->ZeInitResult = ZE_CALL_NOCHECK(zeInit, (L0InitFlags));
320+
if (*GlobalAdapter->ZeInitResult != ZE_RESULT_SUCCESS) {
321+
logger::debug("\nzeInit failed with {}\n",
322+
*GlobalAdapter->ZeInitResult);
323+
}
324+
if (*GlobalAdapter->ZeInitResult == ZE_RESULT_SUCCESS ||
325+
*GlobalAdapter->ZeInitDriversResult == ZE_RESULT_SUCCESS) {
326+
GlobalAdapter->ZeResult = ZE_RESULT_SUCCESS;
327+
} else {
328+
GlobalAdapter->ZeResult = ZE_RESULT_ERROR_UNINITIALIZED;
329+
}
252330
}
253331
assert(GlobalAdapter->ZeResult !=
254332
std::nullopt); // verify that level-zero is initialized
@@ -260,19 +338,11 @@ ur_adapter_handle_t_::ur_adapter_handle_t_()
260338
return;
261339
}
262340
if (*GlobalAdapter->ZeResult != ZE_RESULT_SUCCESS) {
263-
logger::error("zeInit: Level Zero initialization failure\n");
341+
logger::error("Level Zero initialization failure\n");
264342
result = ze2urResult(*GlobalAdapter->ZeResult);
265343

266344
return;
267345
}
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
276346

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

source/adapters/level_zero/adapter.hpp

Lines changed: 8 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,14 @@ 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, 0};
38+
uint32_t ZeInitDriversCount = 0;
39+
bool InitDriversSupported = false;
3440

41+
std::optional<ze_result_t> ZeInitDriversResult;
42+
std::optional<ze_result_t> ZeInitResult;
3543
std::optional<ze_result_t> ZeResult;
3644
std::optional<ze_result_t> ZesResult;
3745
ZeCache<Result<PlatformVec>> PlatformCache;

0 commit comments

Comments
 (0)