From 50789b1b29080bdb380015491dcaa8a9f043ba2a Mon Sep 17 00:00:00 2001 From: "Neil R. Spruit" Date: Fri, 8 Nov 2024 08:54:15 -0800 Subject: [PATCH] [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 --- .github/workflows/build-fuzz-reusable.yml | 2 +- cmake/FetchLevelZero.cmake | 2 +- source/adapters/level_zero/adapter.cpp | 114 +++++++++++++++++----- source/adapters/level_zero/adapter.hpp | 8 ++ 4 files changed, 102 insertions(+), 24 deletions(-) diff --git a/.github/workflows/build-fuzz-reusable.yml b/.github/workflows/build-fuzz-reusable.yml index ae589540fb..2cbd1b87ff 100644 --- a/.github/workflows/build-fuzz-reusable.yml +++ b/.github/workflows/build-fuzz-reusable.yml @@ -41,7 +41,7 @@ jobs: - name: Build level zero with gcc run: | - git clone -b v1.17.6 --depth=1 https://github.com/oneapi-src/level-zero.git ${{github.workspace}}/level-zero + git clone -b v1.18.5 --depth=1 https://github.com/oneapi-src/level-zero.git ${{github.workspace}}/level-zero cd ${{github.workspace}}/level-zero cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DCMAKE_C_COMPILER=gcc -DCMAKE_CXX_COMPILER=g++ cmake --build build -j $(nproc) diff --git a/cmake/FetchLevelZero.cmake b/cmake/FetchLevelZero.cmake index 564cff22fe..266d190e9a 100644 --- a/cmake/FetchLevelZero.cmake +++ b/cmake/FetchLevelZero.cmake @@ -40,7 +40,7 @@ if (NOT DEFINED LEVEL_ZERO_LIBRARY OR NOT DEFINED LEVEL_ZERO_INCLUDE_DIR) set(UR_LEVEL_ZERO_LOADER_REPO "https://github.com/oneapi-src/level-zero.git") endif() if (UR_LEVEL_ZERO_LOADER_TAG STREQUAL "") - set(UR_LEVEL_ZERO_LOADER_TAG v1.18.5) + set(UR_LEVEL_ZERO_LOADER_TAG 0a681d7642c06d76b3b8d4aab16d4af0b5cabb68) endif() # Disable due to a bug https://github.com/oneapi-src/level-zero/issues/104 diff --git a/source/adapters/level_zero/adapter.cpp b/source/adapters/level_zero/adapter.cpp index 9dd2a31268..db83dbb5e9 100644 --- a/source/adapters/level_zero/adapter.cpp +++ b/source/adapters/level_zero/adapter.cpp @@ -78,17 +78,56 @@ ur_result_t getZesDeviceHandle(zes_uuid_t coreDeviceUuid, ur_result_t initPlatforms(PlatformVec &platforms, ze_result_t ZesResult) noexcept try { + std::vector ZeDrivers; + std::vector ZeDriverGetHandles; + std::vector ZeInitDriversHandles; + std::vector ZeDevices; uint32_t ZeDriverCount = 0; - ZE2UR_CALL(zeDriverGet, (&ZeDriverCount, nullptr)); - if (ZeDriverCount == 0) { + uint32_t ZeDriverGetCount = 0; + + auto ZeDriverGetResult = + ZE_CALL_NOCHECK(zeDriverGet, (&ZeDriverGetCount, nullptr)); + if (ZeDriverGetCount > 0 && ZeDriverGetResult == ZE_RESULT_SUCCESS) { + ZeDriverGetHandles.resize(ZeDriverGetCount); + ZE2UR_CALL(zeDriverGet, (&ZeDriverGetCount, ZeDrivers.data())); + } + if (ZeDriverGetCount == 0 && GlobalAdapter->ZeInitDriversCount == 0) { return UR_RESULT_SUCCESS; } - std::vector ZeDrivers; - std::vector ZeDevices; - ZeDrivers.resize(ZeDriverCount); - - ZE2UR_CALL(zeDriverGet, (&ZeDriverCount, ZeDrivers.data())); + if (GlobalAdapter->InitDriversSupported) { + ZE2UR_CALL(GlobalAdapter->initDriversFunctionPtr, + (&GlobalAdapter->ZeInitDriversCount, ZeDrivers.data(), + &GlobalAdapter->InitDriversDesc)); + ZeInitDriversHandles.resize(GlobalAdapter->ZeInitDriversCount); + ZeDrivers.resize(GlobalAdapter->ZeInitDriversCount); + ZeDrivers.assign(ZeInitDriversHandles.begin(), ZeInitDriversHandles.end()); + if (ZeDriverGetCount > 0 && GlobalAdapter->ZeInitDriversCount > 0) { + for (uint32_t X = 0; X < GlobalAdapter->ZeInitDriversCount; ++X) { + for (uint32_t Y = 0; Y < ZeDriverGetCount; ++Y) { + ZeStruct ZeDriverGetProperties; + ZeStruct ZeInitDriverProperties; + ZE2UR_CALL(zeDriverGetProperties, + (ZeDriverGetHandles[Y], &ZeDriverGetProperties)); + ZE2UR_CALL(zeDriverGetProperties, + (ZeInitDriversHandles[X], &ZeInitDriverProperties)); + // If zeDriverGet driver is different from zeInitDriver driver, add it + // to the list. This allows for older drivers to be used alingside + // newer drivers. + if (ZeDriverGetProperties.uuid.id != ZeInitDriverProperties.uuid.id) { + logger::debug("\nzeDriverHandle {} added to the zeInitDrivers list " + "of possible handles.\n", + ZeDriverGetHandles[Y]); + ZeDrivers.push_back(ZeDriverGetHandles[Y]); + } + } + } + } + } else { + ZeDriverCount = ZeDriverGetCount; + ZeDrivers.resize(ZeDriverCount); + ZeDrivers.assign(ZeDriverGetHandles.begin(), ZeDriverGetHandles.end()); + } for (uint32_t I = 0; I < ZeDriverCount; ++I) { // Keep track of the first platform init for this Driver bool DriverPlatformInit = false; @@ -214,6 +253,15 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() return std::atoi(UrRet); }(); + // Dynamically load the new L0 apis separately. + // This must be done to avoid attempting to use symbols that do + // not exist in older loader runtimes. +#ifdef _WIN32 + HMODULE processHandle = GetModuleHandle(NULL); +#else + HMODULE processHandle = nullptr; +#endif + // initialize level zero only once. if (GlobalAdapter->ZeResult == std::nullopt) { // Setting these environment variables before running zeInit will enable @@ -235,20 +283,50 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() // called multiple times. Declaring the return value as "static" ensures // it's only called once. + GlobalAdapter->initDriversFunctionPtr = + (ze_pfnInitDrivers_t)ur_loader::LibLoader::getFunctionPtr( + processHandle, "zeInitDrivers"); + + // Set ZES_ENABLE_SYSMAN by default if the user has not set it. + if (UrSysManEnvInitEnabled) { + setEnvVar("ZES_ENABLE_SYSMAN", "1"); + } + + if (GlobalAdapter->initDriversFunctionPtr) { + GlobalAdapter->InitDriversDesc.pNext = nullptr; + GlobalAdapter->InitDriversDesc.flags = ZE_INIT_DRIVER_TYPE_FLAG_GPU; + logger::debug("\nzeInitDrivers with flags value of {}\n", + static_cast(GlobalAdapter->InitDriversDesc.flags)); + GlobalAdapter->ZeInitDriversResult = + ZE_CALL_NOCHECK(GlobalAdapter->initDriversFunctionPtr, + (&GlobalAdapter->ZeInitDriversCount, nullptr, + &GlobalAdapter->InitDriversDesc)); + if (*GlobalAdapter->ZeInitDriversResult == ZE_RESULT_SUCCESS) { + GlobalAdapter->InitDriversSupported = true; + } else { + logger::debug("\nzeInitDrivers failed with {}\n", + *GlobalAdapter->ZeInitDriversResult); + } + } // Init with all flags set to enable for all driver types to be init in // the application. ze_init_flags_t L0InitFlags = ZE_INIT_FLAG_GPU_ONLY; if (UrL0InitAllDrivers) { L0InitFlags |= ZE_INIT_FLAG_VPU_ONLY; } - - // Set ZES_ENABLE_SYSMAN by default if the user has not set it. - if (UrSysManEnvInitEnabled) { - setEnvVar("ZES_ENABLE_SYSMAN", "1"); - } logger::debug("\nzeInit with flags value of {}\n", static_cast(L0InitFlags)); - GlobalAdapter->ZeResult = ZE_CALL_NOCHECK(zeInit, (L0InitFlags)); + GlobalAdapter->ZeInitResult = ZE_CALL_NOCHECK(zeInit, (L0InitFlags)); + if (*GlobalAdapter->ZeInitResult != ZE_RESULT_SUCCESS) { + logger::debug("\nzeInit failed with {}\n", + *GlobalAdapter->ZeInitResult); + } + if (*GlobalAdapter->ZeInitResult == ZE_RESULT_SUCCESS || + *GlobalAdapter->ZeInitDriversResult == ZE_RESULT_SUCCESS) { + GlobalAdapter->ZeResult = ZE_RESULT_SUCCESS; + } else { + GlobalAdapter->ZeResult = ZE_RESULT_ERROR_UNINITIALIZED; + } } assert(GlobalAdapter->ZeResult != std::nullopt); // verify that level-zero is initialized @@ -260,19 +338,11 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() return; } if (*GlobalAdapter->ZeResult != ZE_RESULT_SUCCESS) { - logger::error("zeInit: Level Zero initialization failure\n"); + logger::error("Level Zero initialization failure\n"); result = ze2urResult(*GlobalAdapter->ZeResult); return; } - // Dynamically load the new L0 SysMan separate init and new EXP apis - // separately. This must be done to avoid attempting to use symbols that do - // not exist in older loader runtimes. -#ifdef _WIN32 - HMODULE processHandle = GetModuleHandle(NULL); -#else - HMODULE processHandle = nullptr; -#endif // Check if the user has enabled the default L0 SysMan initialization. const int UrSysmanZesinitEnable = [] { diff --git a/source/adapters/level_zero/adapter.hpp b/source/adapters/level_zero/adapter.hpp index 53a58793e5..85f2eaac8e 100644 --- a/source/adapters/level_zero/adapter.hpp +++ b/source/adapters/level_zero/adapter.hpp @@ -17,6 +17,7 @@ #include #include #include +#include #include using PlatformVec = std::vector>; @@ -31,7 +32,14 @@ struct ur_adapter_handle_t_ { zes_pfnDriverGetDeviceByUuidExp_t getDeviceByUUIdFunctionPtr = nullptr; zes_pfnDriverGet_t getSysManDriversFunctionPtr = nullptr; zes_pfnInit_t sysManInitFunctionPtr = nullptr; + ze_pfnInitDrivers_t initDriversFunctionPtr = nullptr; + ze_init_driver_type_desc_t InitDriversDesc = { + ZE_STRUCTURE_TYPE_INIT_DRIVER_TYPE_DESC, nullptr, 0}; + uint32_t ZeInitDriversCount = 0; + bool InitDriversSupported = false; + std::optional ZeInitDriversResult; + std::optional ZeInitResult; std::optional ZeResult; std::optional ZesResult; ZeCache> PlatformCache;