Skip to content

Commit 8525dd3

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 8525dd3

File tree

4 files changed

+103
-24
lines changed

4 files changed

+103
-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: 93 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,57 @@ 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, ZeDriverGetHandles.data()));
93+
}
94+
if (ZeDriverGetCount == 0 && GlobalAdapter->ZeInitDriversCount == 0) {
95+
logger::debug("\nNo Valid L0 Drivers found.\n");
8496
return UR_RESULT_SUCCESS;
8597
}
8698

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

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

287+
GlobalAdapter->initDriversFunctionPtr =
288+
(ze_pfnInitDrivers_t)ur_loader::LibLoader::getFunctionPtr(
289+
processHandle, "zeInitDrivers");
290+
291+
// Set ZES_ENABLE_SYSMAN by default if the user has not set it.
292+
if (UrSysManEnvInitEnabled) {
293+
setEnvVar("ZES_ENABLE_SYSMAN", "1");
294+
}
295+
296+
if (GlobalAdapter->initDriversFunctionPtr) {
297+
GlobalAdapter->InitDriversDesc.pNext = nullptr;
298+
GlobalAdapter->InitDriversDesc.flags = ZE_INIT_DRIVER_TYPE_FLAG_GPU;
299+
logger::debug("\nzeInitDrivers with flags value of {}\n",
300+
static_cast<int>(GlobalAdapter->InitDriversDesc.flags));
301+
GlobalAdapter->ZeInitDriversResult =
302+
ZE_CALL_NOCHECK(GlobalAdapter->initDriversFunctionPtr,
303+
(&GlobalAdapter->ZeInitDriversCount, nullptr,
304+
&GlobalAdapter->InitDriversDesc));
305+
if (*GlobalAdapter->ZeInitDriversResult == ZE_RESULT_SUCCESS) {
306+
GlobalAdapter->InitDriversSupported = true;
307+
} else {
308+
logger::debug("\nzeInitDrivers failed with {}\n",
309+
*GlobalAdapter->ZeInitDriversResult);
310+
}
311+
}
238312
// Init with all flags set to enable for all driver types to be init in
239313
// the application.
240314
ze_init_flags_t L0InitFlags = ZE_INIT_FLAG_GPU_ONLY;
241315
if (UrL0InitAllDrivers) {
242316
L0InitFlags |= ZE_INIT_FLAG_VPU_ONLY;
243317
}
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-
}
249318
logger::debug("\nzeInit with flags value of {}\n",
250319
static_cast<int>(L0InitFlags));
251-
GlobalAdapter->ZeResult = ZE_CALL_NOCHECK(zeInit, (L0InitFlags));
320+
GlobalAdapter->ZeInitResult = ZE_CALL_NOCHECK(zeInit, (L0InitFlags));
321+
if (*GlobalAdapter->ZeInitResult != ZE_RESULT_SUCCESS) {
322+
logger::debug("\nzeInit failed with {}\n",
323+
*GlobalAdapter->ZeInitResult);
324+
}
325+
if (*GlobalAdapter->ZeInitResult == ZE_RESULT_SUCCESS ||
326+
*GlobalAdapter->ZeInitDriversResult == ZE_RESULT_SUCCESS) {
327+
GlobalAdapter->ZeResult = ZE_RESULT_SUCCESS;
328+
} else {
329+
GlobalAdapter->ZeResult = ZE_RESULT_ERROR_UNINITIALIZED;
330+
}
252331
}
253332
assert(GlobalAdapter->ZeResult !=
254333
std::nullopt); // verify that level-zero is initialized
@@ -260,19 +339,11 @@ ur_adapter_handle_t_::ur_adapter_handle_t_()
260339
return;
261340
}
262341
if (*GlobalAdapter->ZeResult != ZE_RESULT_SUCCESS) {
263-
logger::error("zeInit: Level Zero initialization failure\n");
342+
logger::error("Level Zero initialization failure\n");
264343
result = ze2urResult(*GlobalAdapter->ZeResult);
265344

266345
return;
267346
}
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
276347

277348
// Check if the user has enabled the default L0 SysMan initialization.
278349
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)