From 608fbb75aa0dbe36a4528b86d1727f4f0c4c001e Mon Sep 17 00:00:00 2001 From: "Delisle, Thierry" Date: Mon, 19 Oct 2026 10:29:51 -0400 Subject: [PATCH 1/2] [SYCL][UR] Improve diagnostics for missing platforms in sycl-ls When a backend's platforms or devices fail to show up in sycl-ls, users currently get little indication of where in the stack things went wrong. This change adds some logging and guidance to help narrow it down: * UR loader: log each adapter that is loaded (statically or dynamically) and the total number of adapters loaded. * UR adapters (CUDA, HIP, Level Zero, OpenCL, Native CPU, Offload): log the number of platforms each adapter initializes at INFO level. The Level Zero message is raised from DEBUG to INFO for consistency. * OpenCL adapter: log an error when clGetPlatformIDs fails or returns no platforms, and when a platform reports CL_DEVICE_NOT_FOUND. * sycl-ls --verbose: print backend-specific hints at the end of the output (clinfo, nvidia-smi, rocminfo/amd-smi, ZE_ENABLE_LOADER_DEBUG_TRACE, /dev/dri/renderD* permissions, strace), and say which UR logger messages point to a configuration problem. The new messages can be seen with UR_LOG_LOADER / UR_LOG_ set to "level:info;output:stdout" (or similar). This doesn't fully resolve the issue, since sycl-ls still can't tell users *why* a backend is missing, but it should make the cause much easier to find. Refs: https://github.com/intel/llvm/issues/22313 Signed-off-by: Delisle, Thierry --- sycl/tools/sycl-ls/sycl-ls.cpp | 52 +++++++++++++++++-- .../source/adapters/cuda/platform.cpp | 1 + .../source/adapters/hip/platform.cpp | 1 + .../adapters/level_zero/common/adapter.cpp | 2 +- .../source/adapters/native_cpu/platform.cpp | 1 + .../source/adapters/offload/platform.cpp | 1 + .../source/adapters/opencl/adapter.cpp | 1 + .../source/adapters/opencl/platform.cpp | 1 + unified-runtime/source/loader/ur_loader.cpp | 6 +++ 9 files changed, 60 insertions(+), 6 deletions(-) diff --git a/sycl/tools/sycl-ls/sycl-ls.cpp b/sycl/tools/sycl-ls/sycl-ls.cpp index cd46ae917535d..4fc3f7b562bf4 100644 --- a/sycl/tools/sycl-ls/sycl-ls.cpp +++ b/sycl/tools/sycl-ls/sycl-ls.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -467,14 +468,25 @@ int main(int argc, char **argv) { // In verbose mode, if UR logging has not already been enabled by the user, // enable the printing of any errors related to adapter loading. - const char *ur_log_loader_var = std::getenv("UR_LOG_LOADER"); - if (verbose && ur_log_loader_var == nullptr) - setenv("UR_LOG_LOADER", "level:info;output:stderr", 1); + constexpr const char *Loggers[] = {"UR_LOG_LOADER", "UR_LOG_CUDA", + "UR_LOG_HIP", "UR_LOG_NATIVE_CPU", + "UR_LOG_OFFLOAD", "UR_LOG_OPENCL"}; + std::vector SetLoggers; + + if (verbose) { + for (const auto &Logger : Loggers) + if (nullptr == std::getenv(Logger)) { + SetLoggers.push_back(Logger); + setenv(Logger, "level:info;output:stderr", 1); + } + } const auto &Platforms = platform::get_platforms(); - if (verbose && ur_log_loader_var == nullptr) { - unsetenv("UR_LOG_LOADER"); + if (verbose) { + for (const auto &Logger : SetLoggers) { + unsetenv(Logger); + } } else if (Platforms.size() == 0) { std::cout << "No platforms found - run with '--verbose' to get more details." @@ -512,6 +524,7 @@ int main(int argc, char **argv) { if (verbose) { std::cout << "\nPlatforms: " << Platforms.size() << std::endl; uint32_t PlatformNum = 0; + std::set SeenBackends; if (!SuppressNumberPrinting) DeviceNums.clear(); for (const auto &Platform : Platforms) { @@ -535,7 +548,36 @@ int main(int argc, char **argv) { } printDeviceInfo(Device, true, " "); } + if (!Devices.empty()) + SeenBackends.insert(Backend); + } + + if (SeenBackends.count(backend::opencl) == 0) { + std::cout + << "Missing OpenCL platforms or devices can be diagnosed using " + "the clinfo tool." + << std::endl; + } + if (SeenBackends.count(backend::ext_oneapi_cuda) == 0) { + std::cout << "Missing CUDA platforms or devices can be diagnosed using " + "nvidia-smi." + << std::endl; + } + if (SeenBackends.count(backend::ext_oneapi_hip) == 0) { + std::cout << "Missing HIP platforms or devices can be diagnosed using " + "rocminfo or amd-smi." + << std::endl; + } + if (SeenBackends.count(backend::ext_oneapi_level_zero) == 0) { + std::cout << "Missing Level Zero platforms or devices can be diagnosed " + "by setting ZE_ENABLE_LOADER_DEBUG_TRACE=1." + << std::endl; } +#ifdef __linux__ + std::cout + << "strace can be used to diagnose any missing shared libraries." + << std::endl; +#endif } else { return EXIT_SUCCESS; } diff --git a/unified-runtime/source/adapters/cuda/platform.cpp b/unified-runtime/source/adapters/cuda/platform.cpp index 0261ff20dd33d..dac8518b3fd6f 100644 --- a/unified-runtime/source/adapters/cuda/platform.cpp +++ b/unified-runtime/source/adapters/cuda/platform.cpp @@ -101,6 +101,7 @@ urPlatformGet(ur_adapter_handle_t, uint32_t, ur_platform_handle_t *phPlatforms, Device, Context, UMF_MEMORY_TYPE_SHARED, &dev->MemoryProviderShared, &dev->MemoryPoolShared)); } + UR_LOG(INFO, "CUDA Initialized {} platforms", NumPlatforms); } catch (const std::bad_alloc &) { // Signal out-of-memory situation for (int i = 0; i < NumDevices; ++i) { diff --git a/unified-runtime/source/adapters/hip/platform.cpp b/unified-runtime/source/adapters/hip/platform.cpp index 1ed8b81d6cb69..1551020abc8ee 100644 --- a/unified-runtime/source/adapters/hip/platform.cpp +++ b/unified-runtime/source/adapters/hip/platform.cpp @@ -88,6 +88,7 @@ urPlatformGet(ur_adapter_handle_t, uint32_t, ur_platform_handle_t *phPlatforms, ScopedDevice Active( ur::hip::adapter->Platform->Devices.front().get()); } + UR_LOG(INFO, "HIP Initialized {} platforms", NumPlatforms); } catch (const std::bad_alloc &) { // Signal out-of-memory situation ur::hip::adapter->Platform->Devices.clear(); diff --git a/unified-runtime/source/adapters/level_zero/common/adapter.cpp b/unified-runtime/source/adapters/level_zero/common/adapter.cpp index 2afdb0399e81c..f554438d77824 100644 --- a/unified-runtime/source/adapters/level_zero/common/adapter.cpp +++ b/unified-runtime/source/adapters/level_zero/common/adapter.cpp @@ -613,7 +613,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()); + UR_LOG(INFO, "LZ Initialized {} platforms", platforms.size()); Platforms = std::move(platforms); } else { UR_LOG(ERR, "Failed to initialize Platforms"); diff --git a/unified-runtime/source/adapters/native_cpu/platform.cpp b/unified-runtime/source/adapters/native_cpu/platform.cpp index 51d41e4a09c3a..703fc775ae999 100644 --- a/unified-runtime/source/adapters/native_cpu/platform.cpp +++ b/unified-runtime/source/adapters/native_cpu/platform.cpp @@ -23,6 +23,7 @@ urPlatformGet(ur_adapter_handle_t, uint32_t NumEntries, UR_ASSERT(pNumPlatforms || phPlatforms, UR_RESULT_ERROR_INVALID_VALUE); if (pNumPlatforms) { + UR_LOG(INFO, "NATIVE_CPU: 1 platform available"); *pNumPlatforms = 1; } diff --git a/unified-runtime/source/adapters/offload/platform.cpp b/unified-runtime/source/adapters/offload/platform.cpp index 6b81c672c4f39..a8dbf416f68c4 100644 --- a/unified-runtime/source/adapters/offload/platform.cpp +++ b/unified-runtime/source/adapters/offload/platform.cpp @@ -21,6 +21,7 @@ urPlatformGet(ur_adapter_handle_t, uint32_t NumEntries, ur_platform_handle_t *phPlatforms, uint32_t *pNumPlatforms) { if (pNumPlatforms) { + UR_LOG(INFO, "OFFLOAD: {} platforms available", Adapter->Platforms.size()); *pNumPlatforms = Adapter->Platforms.size(); } diff --git a/unified-runtime/source/adapters/opencl/adapter.cpp b/unified-runtime/source/adapters/opencl/adapter.cpp index 49d5e32ddeeb0..f82ef12697b7e 100644 --- a/unified-runtime/source/adapters/opencl/adapter.cpp +++ b/unified-runtime/source/adapters/opencl/adapter.cpp @@ -33,6 +33,7 @@ ur::opencl::ur_adapter_handle_t_::ur_adapter_handle_t_() : handle_base() { cl_uint NumPlatforms = 0; cl_int Result = ocl::clGetPlatformIDs_ptr(0, nullptr, &NumPlatforms); if (Result != CL_SUCCESS || NumPlatforms == 0) { + UR_LOG(INFO, "CL No platforms found (Result = {})", Result); // No platforms found — unload immediately. This adapter never escapes // urAdapterGet, so no teardown paths can hold function pointers yet. ocl::unloadOCLLibrary(); diff --git a/unified-runtime/source/adapters/opencl/platform.cpp b/unified-runtime/source/adapters/opencl/platform.cpp index 5429db9120462..2352440cf7757 100644 --- a/unified-runtime/source/adapters/opencl/platform.cpp +++ b/unified-runtime/source/adapters/opencl/platform.cpp @@ -166,6 +166,7 @@ ur_result_t urPlatformGet(ur_adapter_handle_t, uint32_t NumEntries, } Adapter->NumPlatforms = static_cast(Adapter->URPlatforms.size()); + UR_LOG(INFO, "CL Initialized {} platforms", Adapter->NumPlatforms); } catch (std::bad_alloc &) { return UR_RESULT_ERROR_OUT_OF_RESOURCES; } catch (...) { diff --git a/unified-runtime/source/loader/ur_loader.cpp b/unified-runtime/source/loader/ur_loader.cpp index 9fc1f891fd33d..e86f395c7e74f 100644 --- a/unified-runtime/source/loader/ur_loader.cpp +++ b/unified-runtime/source/loader/ur_loader.cpp @@ -45,6 +45,7 @@ ur_result_t context_t::init() { if (!adapter_registry.adaptersForceLoaded()) { #ifdef UR_STATIC_ADAPTER_LEVEL_ZERO if (adapter_registry.includesAdapter("ur_adapter_level_zero")) { + UR_LOG(INFO, "Statically loaded adapter: ur_adapter_level_zero"); auto &level_zero = platforms.emplace_back(nullptr); ur::level_zero::v1::urAdapterGetDdiTables(&level_zero.dditable); adapter_registry.markAdapterAsStaticallyLoaded("ur_adapter_level_zero"); @@ -52,6 +53,7 @@ ur_result_t context_t::init() { #endif #ifdef UR_STATIC_ADAPTER_LEVEL_ZERO_V2 if (adapter_registry.includesAdapter("ur_adapter_level_zero_v2")) { + UR_LOG(INFO, "Statically loaded adapter: ur_adapter_level_zero_v2"); auto &level_zero_v2 = platforms.emplace_back(nullptr); ur::level_zero::v2::urAdapterGetDdiTables(&level_zero_v2.dditable); adapter_registry.markAdapterAsStaticallyLoaded( @@ -60,6 +62,7 @@ ur_result_t context_t::init() { #endif #ifdef UR_STATIC_ADAPTER_OPENCL if (adapter_registry.includesAdapter("ur_adapter_opencl")) { + UR_LOG(INFO, "Statically loaded adapter: ur_adapter_opencl"); auto &opencl = platforms.emplace_back(nullptr); ur::opencl::urAdapterGetDdiTables(&opencl.dditable); adapter_registry.markAdapterAsStaticallyLoaded("ur_adapter_opencl"); @@ -78,6 +81,7 @@ ur_result_t context_t::init() { for (const auto &path : adapterPaths) { auto handle = LibLoader::loadAdapterLibrary(path.string().c_str()); if (handle) { + UR_LOG(INFO, "Successfully loaded adapter: {}", path.string()); platforms.emplace_back(std::move(handle)); break; } @@ -88,6 +92,8 @@ ur_result_t context_t::init() { (void)SetErrorMode(SavedMode); #endif + UR_LOG(INFO, "{} adapters loaded", platforms.size()); + forceIntercept = getenv_tobool("UR_ENABLE_LOADER_INTERCEPT"); if (forceIntercept || platforms.size() > 1) { From 44ed92c9d98fca9dbb834150d27a9a9a23edbe75 Mon Sep 17 00:00:00 2001 From: "Delisle, Thierry" Date: Tue, 20 Oct 2026 09:12:11 -0400 Subject: [PATCH 2/2] Address review comments. Signed-off-by: Delisle, Thierry --- sycl/tools/sycl-ls/sycl-ls.cpp | 28 +++++++++++-------- .../source/adapters/cuda/platform.cpp | 2 +- .../source/adapters/hip/platform.cpp | 2 +- .../adapters/level_zero/common/adapter.cpp | 2 +- .../source/adapters/native_cpu/platform.cpp | 6 +++- .../source/adapters/offload/adapter.cpp | 4 +++ .../source/adapters/offload/platform.cpp | 1 - .../source/adapters/opencl/adapter.cpp | 2 +- .../source/adapters/opencl/platform.cpp | 2 +- 9 files changed, 30 insertions(+), 19 deletions(-) diff --git a/sycl/tools/sycl-ls/sycl-ls.cpp b/sycl/tools/sycl-ls/sycl-ls.cpp index 4fc3f7b562bf4..e7846f633e54b 100644 --- a/sycl/tools/sycl-ls/sycl-ls.cpp +++ b/sycl/tools/sycl-ls/sycl-ls.cpp @@ -468,9 +468,10 @@ int main(int argc, char **argv) { // In verbose mode, if UR logging has not already been enabled by the user, // enable the printing of any errors related to adapter loading. - constexpr const char *Loggers[] = {"UR_LOG_LOADER", "UR_LOG_CUDA", - "UR_LOG_HIP", "UR_LOG_NATIVE_CPU", - "UR_LOG_OFFLOAD", "UR_LOG_OPENCL"}; + constexpr const char *Loggers[] = {"UR_LOG_LOADER", "UR_LOG_CUDA", + "UR_LOG_HIP", "UR_LOG_NATIVE_CPU", + "UR_LOG_OFFLOAD", "UR_LOG_OPENCL", + "UR_LOG_LEVEL_ZERO"}; std::vector SetLoggers; if (verbose) { @@ -554,23 +555,26 @@ int main(int argc, char **argv) { if (SeenBackends.count(backend::opencl) == 0) { std::cout - << "Missing OpenCL platforms or devices can be diagnosed using " - "the clinfo tool." + << "If you expect OpenCL devices to be present, the clinfo " + "tool can be used to diagnose configuration issues with OpenCL." << std::endl; } if (SeenBackends.count(backend::ext_oneapi_cuda) == 0) { - std::cout << "Missing CUDA platforms or devices can be diagnosed using " - "nvidia-smi." - << std::endl; + std::cout + << "If you expect CUDA devices to be present, the nvidia-smi tool " + "can be used to diagnose configuration issues with CUDA." + << std::endl; } if (SeenBackends.count(backend::ext_oneapi_hip) == 0) { - std::cout << "Missing HIP platforms or devices can be diagnosed using " - "rocminfo or amd-smi." + std::cout << "If you expect HIP devices to be present, the rocminfo or " + "amd-smi tools can be used to diagnose configuration " + "issues with HIP." << std::endl; } if (SeenBackends.count(backend::ext_oneapi_level_zero) == 0) { - std::cout << "Missing Level Zero platforms or devices can be diagnosed " - "by setting ZE_ENABLE_LOADER_DEBUG_TRACE=1." + std::cout << "If you expect Level Zero devices to be present, setting " + "ZE_ENABLE_LOADER_DEBUG_TRACE=1 can be used to diagnose " + "configuration issues by the loader." << std::endl; } #ifdef __linux__ diff --git a/unified-runtime/source/adapters/cuda/platform.cpp b/unified-runtime/source/adapters/cuda/platform.cpp index dac8518b3fd6f..33e3b0ab066cd 100644 --- a/unified-runtime/source/adapters/cuda/platform.cpp +++ b/unified-runtime/source/adapters/cuda/platform.cpp @@ -101,7 +101,7 @@ urPlatformGet(ur_adapter_handle_t, uint32_t, ur_platform_handle_t *phPlatforms, Device, Context, UMF_MEMORY_TYPE_SHARED, &dev->MemoryProviderShared, &dev->MemoryPoolShared)); } - UR_LOG(INFO, "CUDA Initialized {} platforms", NumPlatforms); + UR_LOG(INFO, "CUDA: found {} platforms", NumPlatforms); } catch (const std::bad_alloc &) { // Signal out-of-memory situation for (int i = 0; i < NumDevices; ++i) { diff --git a/unified-runtime/source/adapters/hip/platform.cpp b/unified-runtime/source/adapters/hip/platform.cpp index 1551020abc8ee..a909dcfdd9a65 100644 --- a/unified-runtime/source/adapters/hip/platform.cpp +++ b/unified-runtime/source/adapters/hip/platform.cpp @@ -88,7 +88,7 @@ urPlatformGet(ur_adapter_handle_t, uint32_t, ur_platform_handle_t *phPlatforms, ScopedDevice Active( ur::hip::adapter->Platform->Devices.front().get()); } - UR_LOG(INFO, "HIP Initialized {} platforms", NumPlatforms); + UR_LOG(INFO, "HIP: found {} platforms", NumPlatforms); } catch (const std::bad_alloc &) { // Signal out-of-memory situation ur::hip::adapter->Platform->Devices.clear(); diff --git a/unified-runtime/source/adapters/level_zero/common/adapter.cpp b/unified-runtime/source/adapters/level_zero/common/adapter.cpp index f554438d77824..1404a893bd154 100644 --- a/unified-runtime/source/adapters/level_zero/common/adapter.cpp +++ b/unified-runtime/source/adapters/level_zero/common/adapter.cpp @@ -613,7 +613,7 @@ ur_adapter_handle_t_::ur_adapter_handle_t_() ur_result_t err = initPlatforms(this, platforms, ZesResult); if (err == UR_RESULT_SUCCESS) { - UR_LOG(INFO, "LZ Initialized {} platforms", platforms.size()); + UR_LOG(INFO, "L0: found {} platforms", platforms.size()); Platforms = std::move(platforms); } else { UR_LOG(ERR, "Failed to initialize Platforms"); diff --git a/unified-runtime/source/adapters/native_cpu/platform.cpp b/unified-runtime/source/adapters/native_cpu/platform.cpp index 703fc775ae999..1e60627b600c1 100644 --- a/unified-runtime/source/adapters/native_cpu/platform.cpp +++ b/unified-runtime/source/adapters/native_cpu/platform.cpp @@ -22,8 +22,12 @@ urPlatformGet(ur_adapter_handle_t, uint32_t NumEntries, UR_ASSERT(pNumPlatforms || phPlatforms, UR_RESULT_ERROR_INVALID_VALUE); + [[maybe_unused]] static const bool Logged = [] { + UR_LOG(INFO, "NATIVE_CPU: found 1 platform"); + return true; + }(); + if (pNumPlatforms) { - UR_LOG(INFO, "NATIVE_CPU: 1 platform available"); *pNumPlatforms = 1; } diff --git a/unified-runtime/source/adapters/offload/adapter.cpp b/unified-runtime/source/adapters/offload/adapter.cpp index d8fee77b63527..7435f75cc4dc6 100644 --- a/unified-runtime/source/adapters/offload/adapter.cpp +++ b/unified-runtime/source/adapters/offload/adapter.cpp @@ -59,6 +59,10 @@ ur_result_t ur_adapter_handle_t_::init() { }, &Adapter->Platforms); + if (Res == OL_SUCCESS) { + UR_LOG(INFO, "OFFLOAD: found {} platforms", Adapter->Platforms.size()); + } + return offloadResultToUR(Res); } diff --git a/unified-runtime/source/adapters/offload/platform.cpp b/unified-runtime/source/adapters/offload/platform.cpp index a8dbf416f68c4..6b81c672c4f39 100644 --- a/unified-runtime/source/adapters/offload/platform.cpp +++ b/unified-runtime/source/adapters/offload/platform.cpp @@ -21,7 +21,6 @@ urPlatformGet(ur_adapter_handle_t, uint32_t NumEntries, ur_platform_handle_t *phPlatforms, uint32_t *pNumPlatforms) { if (pNumPlatforms) { - UR_LOG(INFO, "OFFLOAD: {} platforms available", Adapter->Platforms.size()); *pNumPlatforms = Adapter->Platforms.size(); } diff --git a/unified-runtime/source/adapters/opencl/adapter.cpp b/unified-runtime/source/adapters/opencl/adapter.cpp index f82ef12697b7e..73b531bf3ed5d 100644 --- a/unified-runtime/source/adapters/opencl/adapter.cpp +++ b/unified-runtime/source/adapters/opencl/adapter.cpp @@ -33,7 +33,7 @@ ur::opencl::ur_adapter_handle_t_::ur_adapter_handle_t_() : handle_base() { cl_uint NumPlatforms = 0; cl_int Result = ocl::clGetPlatformIDs_ptr(0, nullptr, &NumPlatforms); if (Result != CL_SUCCESS || NumPlatforms == 0) { - UR_LOG(INFO, "CL No platforms found (Result = {})", Result); + UR_LOG(INFO, "OpenCL: No platforms found (Result = {})", Result); // No platforms found — unload immediately. This adapter never escapes // urAdapterGet, so no teardown paths can hold function pointers yet. ocl::unloadOCLLibrary(); diff --git a/unified-runtime/source/adapters/opencl/platform.cpp b/unified-runtime/source/adapters/opencl/platform.cpp index 2352440cf7757..627ea443c1b82 100644 --- a/unified-runtime/source/adapters/opencl/platform.cpp +++ b/unified-runtime/source/adapters/opencl/platform.cpp @@ -166,7 +166,7 @@ ur_result_t urPlatformGet(ur_adapter_handle_t, uint32_t NumEntries, } Adapter->NumPlatforms = static_cast(Adapter->URPlatforms.size()); - UR_LOG(INFO, "CL Initialized {} platforms", Adapter->NumPlatforms); + UR_LOG(INFO, "OpenCL: found {} platforms", Adapter->NumPlatforms); } catch (std::bad_alloc &) { return UR_RESULT_ERROR_OUT_OF_RESOURCES; } catch (...) {