From d091311219c2ba6f4c3c60c695d632a46729b62f Mon Sep 17 00:00:00 2001 From: Krzysztof Filipek Date: Wed, 21 Oct 2026 13:50:44 +0200 Subject: [PATCH 1/3] [UR] Build the adapter registry tests from their sources Since the move to lit these tests passed the undefined TEST_SOURCES, so the binaries contained no tests and always passed. All 17 tests pass now. --- .../test/loader/adapter_registry/CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/unified-runtime/test/loader/adapter_registry/CMakeLists.txt b/unified-runtime/test/loader/adapter_registry/CMakeLists.txt index 5dc8ef6fdad1b..7eaf376bea098 100644 --- a/unified-runtime/test/loader/adapter_registry/CMakeLists.txt +++ b/unified-runtime/test/loader/adapter_registry/CMakeLists.txt @@ -4,7 +4,7 @@ function(add_adapter_reg_search_test name) set(TEST_TARGET_NAME ${name}-test) - add_gtest_test(${name} ${TEST_SOURCES}) + add_gtest_test(${name} ${ARGN}) if(WIN32) target_sources(${TEST_TARGET_NAME} PRIVATE @@ -18,7 +18,7 @@ function(add_adapter_reg_search_test name) ${PROJECT_SOURCE_DIR}/source/loader) endfunction() -add_adapter_reg_search_test(search-with-env) -add_adapter_reg_search_test(search-no-env) -add_adapter_reg_search_test(search-order) -add_adapter_reg_search_test(prefilter) +add_adapter_reg_search_test(search-with-env search_with_env.cpp) +add_adapter_reg_search_test(search-no-env search_no_env.cpp) +add_adapter_reg_search_test(search-order search_order.cpp) +add_adapter_reg_search_test(prefilter prefilter.cpp) From c600ebbb0e4b1755fe20cd503eee94b93331354e Mon Sep 17 00:00:00 2001 From: Krzysztof Filipek Date: Fri, 23 Oct 2026 16:03:28 +0200 Subject: [PATCH 2/3] [UR][CI] Run the loader test suite in the UR workflow CI only ran the adapter-specific and conformance suites, so the loader tests, including the adapter registry tests, never ran in CI. --- .github/workflows/ur-build-hw.yml | 7 +++++++ devops/actions/run-tests/ur/action.yml | 2 +- devops/scripts/ur_test_tools/constants.py | 1 + devops/scripts/ur_test_tools/test_runner.py | 6 ++++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ur-build-hw.yml b/.github/workflows/ur-build-hw.yml index 7870cb85f1b34..398d34dfde6a5 100644 --- a/.github/workflows/ur-build-hw.yml +++ b/.github/workflows/ur-build-hw.yml @@ -200,6 +200,13 @@ jobs: build_dir: build artifact_name: 'ur-${{matrix.adapter.name}}-${{steps.artifact_suffix.outputs.suffix}}-conformance' + - name: Test loader + uses: ./devops/actions/run-tests/ur + with: + test_type: 'loader' + build_dir: build + artifact_name: 'ur-${{matrix.adapter.name}}-${{steps.artifact_suffix.outputs.suffix}}-loader' + - name: Debug CI platform information if: ${{ always() }} run: ./devops/scripts/get_system_info.sh diff --git a/devops/actions/run-tests/ur/action.yml b/devops/actions/run-tests/ur/action.yml index 0e161f6970846..5fa91a772eb57 100644 --- a/devops/actions/run-tests/ur/action.yml +++ b/devops/actions/run-tests/ur/action.yml @@ -2,7 +2,7 @@ name: 'Run UR Tests' inputs: test_type: - description: 'Type of tests to run (adapter-specific or conformance)' + description: 'Type of tests to run (adapter-specific, conformance or loader)' required: true build_dir: required: false diff --git a/devops/scripts/ur_test_tools/constants.py b/devops/scripts/ur_test_tools/constants.py index 396574d62516c..672746ab4c5b3 100644 --- a/devops/scripts/ur_test_tools/constants.py +++ b/devops/scripts/ur_test_tools/constants.py @@ -29,6 +29,7 @@ TEST_TYPE_ADAPTER_SPECIFIC = "adapter-specific" TEST_TYPE_CONFORMANCE = "conformance" +TEST_TYPE_LOADER = "loader" # These tests cause timeouts on CI and are excluded from adapter-specific runs LIT_FILTER_OUT_ADAPTER_SPECIFIC = ( diff --git a/devops/scripts/ur_test_tools/test_runner.py b/devops/scripts/ur_test_tools/test_runner.py index f46f3101b0998..97021414747be 100644 --- a/devops/scripts/ur_test_tools/test_runner.py +++ b/devops/scripts/ur_test_tools/test_runner.py @@ -13,6 +13,7 @@ LIT_CI_OPTIONS, TEST_TYPE_ADAPTER_SPECIFIC, TEST_TYPE_CONFORMANCE, + TEST_TYPE_LOADER, LIT_FILTER_OUT_ADAPTER_SPECIFIC, MAX_LINES_TO_SCAN, ) @@ -33,6 +34,11 @@ def get_test_config(test_type: str) -> TestConfig: target="check-unified-runtime-conformance", log_file="conformance_tests.log", ) + elif test_type == TEST_TYPE_LOADER: + return TestConfig( + target="check-unified-runtime-loader", + log_file="loader_tests.log", + ) else: raise ValueError(f"Invalid test_type: {test_type}") From e85136aa8871d1298307aecac8ec4e3fdd2b4340 Mon Sep 17 00:00:00 2001 From: Krzysztof Filipek Date: Mon, 26 Oct 2026 09:12:01 +0100 Subject: [PATCH 3/3] [UR] Balance the loader's static UMF reference urLoaderTearDown released the UMF reference on every successful call, not only when the last one deleted the context, so it also dropped UMF's own reference. UMF was then re-initialized repeatedly, overflowing its CTL node table after ~100 cycles and crashing loader_lifetime.test. Co-Authored-By: Claude Opus 5.5 --- unified-runtime/source/loader/ur_lib.cpp | 11 +++++++---- unified-runtime/source/loader/ur_lib.hpp | 3 +++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/unified-runtime/source/loader/ur_lib.cpp b/unified-runtime/source/loader/ur_lib.cpp index 947f837255d65..c37bb3bdf088d 100644 --- a/unified-runtime/source/loader/ur_lib.cpp +++ b/unified-runtime/source/loader/ur_lib.cpp @@ -102,7 +102,7 @@ __urdlllocal ur_result_t context_t::Init( #if defined(UR_STATIC_UMF) if (UR_RESULT_SUCCESS == result) { - umfInit(); + holdsUmfRef = umfInit() == UMF_RESULT_SUCCESS; } #endif @@ -220,15 +220,18 @@ ur_result_t UR_APICALL urLoaderInit(ur_device_init_flags_t device_flags, } ur_result_t urLoaderTearDown() { - int ret = ur_lib::context_t::release([](context_t *context) { + bool releaseUmf = false; + int ret = ur_lib::context_t::release([&releaseUmf](context_t *context) { context->tearDownLayers(); ur_loader::context_t::forceDelete(); + releaseUmf = context->holdsUmfRef; delete context; }); #if defined(UR_STATIC_UMF) - // Release the Init reference only after the layers are torn down above. - if (ret == 0) { + // Release the Init reference only after the layers are torn down above, and + // only when the last urLoaderTearDown deleted the context that took it. + if (releaseUmf) { umfTearDown(); } #endif diff --git a/unified-runtime/source/loader/ur_lib.hpp b/unified-runtime/source/loader/ur_lib.hpp index 0ec380e72d80c..c52f402c8d2bf 100644 --- a/unified-runtime/source/loader/ur_lib.hpp +++ b/unified-runtime/source/loader/ur_lib.hpp @@ -110,6 +110,9 @@ class __urdlllocal context_t : public AtomicSingleton { codeloc_data codelocData; + // Set when Init took a umfInit reference that teardown must release. + bool holdsUmfRef = false; + void parseEnvEnabledLayers(); ur_result_t initLayers(); void tearDownLayers() const;