diff --git a/sycl/doc/EnvironmentVariables.md b/sycl/doc/EnvironmentVariables.md index 9f2336441745..db1889ea819f 100644 --- a/sycl/doc/EnvironmentVariables.md +++ b/sycl/doc/EnvironmentVariables.md @@ -160,6 +160,8 @@ For a description of parallel for range rounding in DPC++ see | `SYCL_PI_LEVEL_ZERO_DISABLE_USM_ALLOCATOR` | Any(\*) | Disable USM allocator in Level Zero adapter (each memory request will go directly to Level Zero runtime) | | `SYCL_PI_LEVEL_ZERO_TRACK_INDIRECT_ACCESS_MEMORY` | Any(\*) | Enable support of the kernels with indirect access and corresponding deferred release of memory allocations in the Level Zero adapter. | | `SYCL_UR_USE_LEVEL_ZERO_V2` | Integer | Enable ('1') or disable ('0') the use of the Level Zero V2 adapter, which features a redesigned architecture aimed at optimizing performance for different queue modes (immediate/batched, in-order/out-of-order). This version is expected to reduce runtime overhead and currently only support immediate command lists. By default, this adapter is used on platforms with GPUs based on the Xe2 architecture or later, such as Battlemage, Lunar Lake, and Arrow Lake. If you experience any performance or functional issues with this adapter enabled, please report them on GitHub, specifying the adapter used. | +| `SYCL_UR_L0_LOADER_SKIPLIST` | String | Comma-separated list of L0 loader versions. Skips loading the L0 adapter if the version of the L0 loader found during runtime initialization on the system matches an entry in this list. | +| `SYCL_UR_L0_DRIVER_SKIPLIST` | String | Comma-separated list of L0 driver versions. Skips loading the L0 adapter if the version of the L0 driver found during runtime initialization on the system matches an entry in this list. | `(*) Note: Any means this environment variable is effective when set to any non-null value.` diff --git a/unified-runtime/source/adapters/level_zero/adapter.cpp b/unified-runtime/source/adapters/level_zero/adapter.cpp index 37366d50da58..9a2c8f317efe 100644 --- a/unified-runtime/source/adapters/level_zero/adapter.cpp +++ b/unified-runtime/source/adapters/level_zero/adapter.cpp @@ -13,6 +13,10 @@ #include "ur_level_zero.hpp" #include +// The default value of the loader versions skiplist +// (SYCL_UR_L0_LOADER_SKIPLIST) +static const std::vector LoaderSkiplistDefault = {}; + // As windows order of unloading dlls is reversed from linux, windows will call // umfTearDown before it could release umf objects in level_zero, so we call // umfInit on urAdapterGet and umfAdapterTearDown to enforce the teardown of umf @@ -187,8 +191,8 @@ ur_result_t initPlatforms(ur_adapter_handle_t_ *adapter, PlatformVec &platforms, if (ZeDriverGetProperties.driverVersion == ZeInitDriverProperties.driverVersion) { UR_LOG(DEBUG, - "\nzeDriverHandle {} matched between zeDriverGet and " - "zeInitDrivers. Not adding duplicate driver to list\n", + "zeDriverHandle {} matched between zeDriverGet and " + "zeInitDrivers. Not adding duplicate driver to list", ZeDriverGetHandles[Y]); unMatchedDriverHandle = false; break; @@ -196,8 +200,8 @@ ur_result_t initPlatforms(ur_adapter_handle_t_ *adapter, PlatformVec &platforms, } if (unMatchedDriverHandle) { UR_LOG(DEBUG, - "\nzeDriverHandle {} not found in zeInitDrivers. Adding to " - "driver list.\n", + "zeDriverHandle {} not found in zeInitDrivers. Adding to " + "driver list.", driverGetHandle); ZeDrivers.push_back(driverGetHandle); } @@ -208,7 +212,7 @@ ur_result_t initPlatforms(ur_adapter_handle_t_ *adapter, PlatformVec &platforms, ZeDrivers.assign(ZeDriverGetHandles.begin(), ZeDriverGetHandles.end()); } ZeDriverCount = ZeDrivers.size(); - UR_LOG(DEBUG, "\n{} L0 Drivers found.\n", ZeDriverCount); + UR_LOG(DEBUG, "{} L0 Drivers found.", ZeDriverCount); for (uint32_t I = 0; I < ZeDriverCount; ++I) { // Keep track of the first platform init for this Driver bool DriverPlatformInit = false; @@ -226,7 +230,17 @@ ur_result_t initPlatforms(ur_adapter_handle_t_ *adapter, PlatformVec &platforms, // Check if this driver's platform has already been init. if (!DriverPlatformInit) { // If this Driver is a GPU, save it as a usable platform. - UR_CALL(platform->initialize()); + ur_result_t Result; + UR_CALL_NOCHECK(Result = platform->initialize()); + + // Forget platform with L0 driver version listed in the skiplist + if (platform->IsDriverVersionSkipListed) { + break; + } + + if (Result != UR_RESULT_SUCCESS) { + return Result; + } // Save a copy in the cache for future uses. platforms.push_back(std::move(platform)); @@ -436,13 +450,12 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() if (UrL0InitAllDrivers) { L0InitFlags |= ZE_INIT_FLAG_VPU_ONLY; } - UR_LOG(DEBUG, "\nzeInit with flags value of {}\n", - static_cast(L0InitFlags)); + UR_LOG(DEBUG, "zeInit with flags value of {}", static_cast(L0InitFlags)); ZeInitResult = ZE_CALL_NOCHECK(zeInit, (L0InitFlags)); if (ZeInitResult != ZE_RESULT_SUCCESS) { const char *ErrorString = "Unknown"; zeParseError(ZeInitResult, ErrorString); - UR_LOG(ERR, "\nzeInit failed with {}\n", ErrorString); + UR_LOG(ERR, "zeInit failed with {}", ErrorString); } bool useInitDrivers = false; @@ -458,7 +471,7 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() if (strncmp(versions[i].component_name, "loader", strlen("loader")) == 0) { loader_version = versions[i].component_lib_version; - UR_LOG(DEBUG, "\nLevel Zero Loader Version: {}.{}.{}\n", + UR_LOG(DEBUG, "Level Zero Loader version: {}.{}.{}", loader_version.major, loader_version.minor, loader_version.patch); break; @@ -466,6 +479,40 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() } } delete[] versions; + + auto LoaderSkiplist = getenv_to_vec("SYCL_UR_L0_LOADER_SKIPLIST"); + if (!LoaderSkiplist.has_value()) { + LoaderSkiplist = LoaderSkiplistDefault; + + if ((loader_version.major == 1 && loader_version.minor < 8)) { + UR_LOG(ERR, + "ERROR: Level Zero Loader version older than 1.8.0 is not " + "supported (current version: {}.{}.{}). Please update Intel GPU " + "compute drivers.", + loader_version.major, loader_version.minor, + loader_version.patch); + // Return 0 platforms as the loader is too old to be supported. + return; + } + } + + auto LoaderVersionString = std::to_string(loader_version.major) + "." + + std::to_string(loader_version.minor) + "." + + std::to_string(loader_version.patch); + for (const auto &version : LoaderSkiplist.value()) { + UR_LOG(DEBUG, "Checking loader version {} against skiplist entry {}", + LoaderVersionString, version); + if (version == LoaderVersionString) { + UR_LOG(WARN, + "Skipping Level Zero adapter due to the loader version: {} " + "matches a skiplist entry (set SYCL_UR_L0_LOADER_SKIPLIST to " + "override)", + version); + // Return 0 platforms + return; + } + } + if (loader_version.major > 1 || (loader_version.major == 1 && loader_version.minor > 19) || (loader_version.major == 1 && loader_version.minor == 19 && @@ -478,7 +525,7 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() loader_version.patch < 2)) { UR_LOG(WARN, "WARNING: Level Zero Loader version is older than 1.21.2. " - "Please update to the latest version for API logging support.\n"); + "Please update to the latest version for API logging support."); } } @@ -491,7 +538,7 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() processHandle, "zeInitDrivers"); #endif if (initDriversFunctionPtr) { - UR_LOG(DEBUG, "\nzeInitDrivers with flags value of {}\n", + UR_LOG(DEBUG, "zeInitDrivers with flags value of {}", static_cast(InitDriversDesc.flags)); ZeInitDriversResult = ZE_CALL_NOCHECK(initDriversFunctionPtr, @@ -501,7 +548,7 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() } else { const char *ErrorString = "Unknown"; zeParseError(ZeInitDriversResult, ErrorString); - UR_LOG(ERR, "\nzeInitDrivers failed with {}\n", ErrorString); + UR_LOG(ERR, "zeInitDrivers failed with {}", ErrorString); } } } @@ -509,7 +556,7 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() if (ZeInitResult != ZE_RESULT_SUCCESS && ZeInitDriversResult != ZE_RESULT_SUCCESS) { // Absorb the ZE_RESULT_ERROR_UNINITIALIZED and just return 0 Platforms. - UR_LOG(ERR, "Level Zero Uninitialized\n"); + UR_LOG(ERR, "Level Zero Uninitialized"); return; } @@ -581,6 +628,7 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() ur_result_t err = initPlatforms(this, platforms, ZesResult); if (err == UR_RESULT_SUCCESS) { + UR_LOG(DEBUG, "Initialized {} platforms", platforms.size()); Platforms = std::move(platforms); } else { UR_LOG(ERR, "Failed to initialize Platforms"); diff --git a/unified-runtime/source/adapters/level_zero/platform.cpp b/unified-runtime/source/adapters/level_zero/platform.cpp index dccf31164672..ea3ee39945b0 100644 --- a/unified-runtime/source/adapters/level_zero/platform.cpp +++ b/unified-runtime/source/adapters/level_zero/platform.cpp @@ -12,6 +12,10 @@ #include "adapter.hpp" #include "ur_level_zero.hpp" +// The default value of the driver versions skiplist +// (SYCL_UR_L0_DRIVER_SKIPLIST) +static const std::vector DriverSkiplistDefault = {}; + namespace ur::level_zero { ur_result_t urPlatformGet( @@ -323,6 +327,26 @@ ur_result_t ur_platform_handle_t_::initialize() { &sizeOfDriverString); } + auto DriverSkiplist = getenv_to_vec("SYCL_UR_L0_DRIVER_SKIPLIST"); + if (!DriverSkiplist.has_value()) { + DriverSkiplist = DriverSkiplistDefault; + } + + UR_LOG(DEBUG, "Level Zero Driver version: {}", ZeDriverVersion); + for (const auto &version : DriverSkiplist.value()) { + UR_LOG(DEBUG, "Checking driver version {} against skiplist entry {}", + ZeDriverVersion, version); + if (version == ZeDriverVersion) { + UR_LOG(WARN, + "Skipping Level Zero driver due to the driver version: {} " + "matches a skiplist entry (set SYCL_UR_L0_DRIVER_SKIPLIST to " + "override)", + version); + IsDriverVersionSkipListed = true; + return UR_RESULT_ERROR_UNINITIALIZED; + } + } + // Check if import user ptr into USM feature has been requested. // If yes, then set up L0 API pointers if the platform supports it. ZeUSMImport.setZeUSMImport(this); diff --git a/unified-runtime/source/adapters/level_zero/platform.hpp b/unified-runtime/source/adapters/level_zero/platform.hpp index a556673d90a1..94e713f66d14 100644 --- a/unified-runtime/source/adapters/level_zero/platform.hpp +++ b/unified-runtime/source/adapters/level_zero/platform.hpp @@ -59,6 +59,8 @@ struct ur_platform_handle_t_ : ur::handle_base, std::string ZeDriverApiVersion; ze_api_version_t ZeApiVersion; + bool IsDriverVersionSkipListed{false}; + // Cache driver extensions std::unordered_map zeDriverExtensionMap;