From 50ec8966b8c5bf126cf6b12c40bdf3bea9ec4466 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 --- source/adapters/level_zero/adapter.cpp | 80 ++++++++++++++++++-------- source/adapters/level_zero/adapter.hpp | 5 ++ 2 files changed, 61 insertions(+), 24 deletions(-) diff --git a/source/adapters/level_zero/adapter.cpp b/source/adapters/level_zero/adapter.cpp index 9dd2a31268..1e6b417dbc 100644 --- a/source/adapters/level_zero/adapter.cpp +++ b/source/adapters/level_zero/adapter.cpp @@ -78,18 +78,25 @@ ur_result_t getZesDeviceHandle(zes_uuid_t coreDeviceUuid, ur_result_t initPlatforms(PlatformVec &platforms, ze_result_t ZesResult) noexcept try { - uint32_t ZeDriverCount = 0; - ZE2UR_CALL(zeDriverGet, (&ZeDriverCount, nullptr)); - if (ZeDriverCount == 0) { + if (!GlobalAdapter->initDriversFunctionPtr) { + ZE2UR_CALL(zeDriverGet, (&GlobalAdapter->ZeDriverCount, nullptr)); + } + if (GlobalAdapter->ZeDriverCount == 0) { return UR_RESULT_SUCCESS; } std::vector ZeDrivers; std::vector ZeDevices; - ZeDrivers.resize(ZeDriverCount); - - ZE2UR_CALL(zeDriverGet, (&ZeDriverCount, ZeDrivers.data())); - for (uint32_t I = 0; I < ZeDriverCount; ++I) { + ZeDrivers.resize(GlobalAdapter->ZeDriverCount); + + if (GlobalAdapter->initDriversFunctionPtr) { + ZE2UR_CALL(GlobalAdapter->initDriversFunctionPtr, + (&GlobalAdapter->ZeDriverCount, ZeDrivers.data(), + &GlobalAdapter->InitDriversDesc)); + } else { + ZE2UR_CALL(zeDriverGet, (&GlobalAdapter->ZeDriverCount, ZeDrivers.data())); + } + for (uint32_t I = 0; I < GlobalAdapter->ZeDriverCount; ++I) { // Keep track of the first platform init for this Driver bool DriverPlatformInit = false; ze_device_properties_t device_properties{}; @@ -184,6 +191,7 @@ Behavior Summary: ur_adapter_handle_t_::ur_adapter_handle_t_() : logger(logger::get_logger("level_zero")) { + printf("adapter handle\n"); if (UrL0Debug & UR_L0_DEBUG_BASIC) { logger.setLegacySink(std::make_unique()); }; @@ -194,6 +202,7 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() } PlatformCache.Compute = [](Result &result) { + printf("platform cache\n"); static std::once_flag ZeCallCountInitialized; try { std::call_once(ZeCallCountInitialized, []() { @@ -214,6 +223,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 +253,42 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() // called multiple times. Declaring the return value as "static" ensures // it's only called once. - // 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; - } + GlobalAdapter->initDriversFunctionPtr = + (ze_pfnInitDrivers_t)ur_loader::LibLoader::getFunctionPtr( + processHandle, "zeInitDrivers"); + printf("GlobalAdapter->initDriversFunctionPtr %p\n", + (void *)GlobalAdapter->initDriversFunctionPtr); // 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)); + printf("init drivers\n"); + + if (GlobalAdapter->initDriversFunctionPtr) { + printf("init drivers\n"); + 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->ZeResult = + ZE_CALL_NOCHECK(GlobalAdapter->initDriversFunctionPtr, + (&GlobalAdapter->ZeDriverCount, nullptr, + &GlobalAdapter->InitDriversDesc)); + } + + if (GlobalAdapter->ZeResult != ZE_RESULT_SUCCESS) { + printf("zeInit\n"); + // 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; + } + logger::debug("\nzeInit with flags value of {}\n", + static_cast(L0InitFlags)); + GlobalAdapter->ZeResult = ZE_CALL_NOCHECK(zeInit, (L0InitFlags)); + } } assert(GlobalAdapter->ZeResult != std::nullopt); // verify that level-zero is initialized @@ -265,14 +305,6 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() 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..159c217e73 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,6 +32,10 @@ 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 ZeDriverCount = 0; std::optional ZeResult; std::optional ZesResult;