From 5c67c72b63b49ccb2e89fb6c5f810da23b0260b3 Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Fri, 30 Oct 2026 08:33:22 +0100 Subject: [PATCH 1/2] [cmake] Skip unrequested CUDA compiler detection CUDA compiler discovery starts a separate CMake configuration even when neither CUDA feature is requested. This can add substantial overhead on slow I/O and NFS-backed filesystems. Only discover CUDA for explicit requests or when all needs availability information to select defaults. Preserve explicit OFF settings and gminimal defaults, and cover these combinations with regression tests. Assisted-by: Codex:GPT-6 --- cmake/modules/CheckCompiler.cmake | 17 ++++--- test/CMakeLists.txt | 9 ++++ test/cmake/cuda/CMakeLists.txt | 72 +++++++++++++++++++++++++++++ test/cmake/cuda/CheckLanguage.cmake | 22 +++++++++ 4 files changed, 114 insertions(+), 6 deletions(-) create mode 100644 test/cmake/cuda/CMakeLists.txt create mode 100644 test/cmake/cuda/CheckLanguage.cmake diff --git a/cmake/modules/CheckCompiler.cmake b/cmake/modules/CheckCompiler.cmake index c09183ffed443..3c1c11ee47e2b 100644 --- a/cmake/modules/CheckCompiler.cmake +++ b/cmake/modules/CheckCompiler.cmake @@ -56,12 +56,17 @@ else() set(CMAKE_Fortran_COMPILER CMAKE_Fortran_COMPILER-NOTFOUND) endif() -#---Enable CUDA if found on the system--- -check_language(CUDA) -if (CMAKE_CUDA_COMPILER) - enable_language(CUDA) - if(NOT DEFINED CMAKE_CUDA_STANDARD) - set(CMAKE_CUDA_STANDARD ${CMAKE_CXX_STANDARD}) +#---Check CUDA only for requested features or to select their defaults with 'all'---------------- +# Both CUDA options default to OFF. With 'all', discover availability unless both are explicitly +# disabled or 'gminimal' will disable their defaults again. +if(cuda OR tmva-gpu OR + (all AND NOT gminimal AND (NOT DEFINED cuda OR NOT DEFINED tmva-gpu))) + check_language(CUDA) + if(CMAKE_CUDA_COMPILER) + enable_language(CUDA) + if(NOT DEFINED CMAKE_CUDA_STANDARD) + set(CMAKE_CUDA_STANDARD ${CMAKE_CXX_STANDARD}) + endif() endif() endif() diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c4d75e93b327a..5cfefd251bcba 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -12,6 +12,15 @@ set(root_exe $) #---environment------------------------------------------------------------------------------- ROOT_ADD_TEST(show-environment COMMAND ${CMAKE_COMMAND} -E environment) +#---CUDA compiler detection-------------------------------------------------------------------- +foreach(case default disabled cached-disabled cuda tmva-gpu all all-disabled all-cuda-disabled + all-tmva-disabled minimal gminimal all-gminimal unavailable) + ROOT_ADD_TEST(cmake-cuda-${case} + COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cuda + -B ${CMAKE_CURRENT_BINARY_DIR}/cmake/cuda-${case} + -DROOT_SOURCE_DIR=${CMAKE_SOURCE_DIR} -DCASE=${case}) +endforeach() + #---hworld------------------------------------------------------------------------------------ ROOT_EXECUTABLE(hworld hworld.cxx LIBRARIES Gpad) diff --git a/test/cmake/cuda/CMakeLists.txt b/test/cmake/cuda/CMakeLists.txt new file mode 100644 index 0000000000000..8d8b8f7fc94d8 --- /dev/null +++ b/test/cmake/cuda/CMakeLists.txt @@ -0,0 +1,72 @@ +cmake_minimum_required(VERSION 3.20) +project(CheckCUDA LANGUAGES C CXX) + +list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" "${ROOT_SOURCE_DIR}/cmake/modules") +# Keep repeated CTest runs independent of options cached by the previous configure. +foreach(opt cuda tmva-gpu all minimal gminimal CMAKE_CUDA_COMPILER) + unset(${opt} CACHE) +endforeach() +set(fortran OFF) +set(expect_cuda OFF) +set(cuda_available ON) +set(expect_cuda_option OFF) +set(expect_tmva_gpu_option OFF) + +if(CASE STREQUAL "disabled" OR CASE STREQUAL "cached-disabled" OR CASE STREQUAL "all-disabled") + set(cuda OFF CACHE BOOL "") + set(tmva-gpu OFF CACHE BOOL "") + if(CASE STREQUAL "cached-disabled") + set(CMAKE_CUDA_COMPILER mock-cuda-compiler CACHE FILEPATH "") + elseif(CASE STREQUAL "all-disabled") + set(all ON) + endif() +elseif(CASE STREQUAL "cuda") + set(cuda ON CACHE BOOL "") + set(expect_cuda ON) + set(expect_cuda_option ON) +elseif(CASE STREQUAL "tmva-gpu") + set(tmva-gpu ON CACHE BOOL "") + set(expect_cuda ON) + set(expect_tmva_gpu_option ON) +elseif(CASE STREQUAL "all" OR CASE STREQUAL "all-cuda-disabled" OR CASE STREQUAL "all-tmva-disabled") + set(all ON) + set(expect_cuda ON) + set(expect_cuda_option ON) + set(expect_tmva_gpu_option ON) + if(CASE STREQUAL "all-cuda-disabled") + set(cuda OFF CACHE BOOL "") + set(expect_cuda_option OFF) + elseif(CASE STREQUAL "all-tmva-disabled") + set(tmva-gpu OFF CACHE BOOL "") + set(expect_tmva_gpu_option OFF) + endif() +elseif(CASE STREQUAL "minimal") + set(minimal ON) +elseif(CASE STREQUAL "gminimal" OR CASE STREQUAL "all-gminimal") + set(gminimal ON) + if(CASE STREQUAL "all-gminimal") + set(all ON) + endif() +elseif(CASE STREQUAL "unavailable") + set(all ON) + set(expect_cuda ON) + set(cuda_available OFF) +elseif(NOT CASE STREQUAL "default") + message(FATAL_ERROR "Unknown test case: ${CASE}") +endif() + +include(CheckCompiler) +include(RootBuildOptions) + +if(expect_cuda AND NOT cuda_checked) + message(FATAL_ERROR "CUDA compiler detection was skipped") +endif() +if(expect_cuda AND cuda_available AND NOT cuda_enabled) + message(FATAL_ERROR "The CUDA language was not initialized") +endif() +if(NOT "${cuda}" STREQUAL "${expect_cuda_option}") + message(FATAL_ERROR "Expected cuda=${expect_cuda_option}, got ${cuda}") +endif() +if(NOT "${tmva-gpu}" STREQUAL "${expect_tmva_gpu_option}") + message(FATAL_ERROR "Expected tmva-gpu=${expect_tmva_gpu_option}, got ${tmva-gpu}") +endif() diff --git a/test/cmake/cuda/CheckLanguage.cmake b/test/cmake/cuda/CheckLanguage.cmake new file mode 100644 index 0000000000000..febec470c11b6 --- /dev/null +++ b/test/cmake/cuda/CheckLanguage.cmake @@ -0,0 +1,22 @@ +# Simulate CUDA availability so these tests do not require a CUDA installation. +function(check_language language) + if(NOT language STREQUAL "CUDA") + message(FATAL_ERROR "Unexpected compiler check for ${language}") + endif() + if(NOT expect_cuda) + message(FATAL_ERROR "CUDA compiler detection was not requested") + endif() + set(cuda_checked TRUE PARENT_SCOPE) + if(cuda_available) + set(CMAKE_CUDA_COMPILER mock-cuda-compiler PARENT_SCOPE) + else() + set(CMAKE_CUDA_COMPILER CMAKE_CUDA_COMPILER-NOTFOUND PARENT_SCOPE) + endif() +endfunction() + +function(enable_language language) + if(NOT language STREQUAL "CUDA" OR NOT expect_cuda OR NOT cuda_available) + message(FATAL_ERROR "Unexpected language initialization for ${language}") + endif() + set(cuda_enabled TRUE PARENT_SCOPE) +endfunction() From 33f50fc5bfeb9b21ff9b3aacd6a204f645928ff6 Mon Sep 17 00:00:00 2001 From: Juan Miguel Carceller Date: Mon, 2 Nov 2026 08:25:01 +0100 Subject: [PATCH 2/2] [cmake] Require explicit CUDA feature selection Keep CUDA features opt-in even with all enabled, including when CUDA compiler information is already cached. Simplify compiler discovery and remove the configuration test suite as requested in review. Validate option combinations using a temporary external harness. Assisted-by: Codex:GPT-6 --- cmake/modules/CheckCompiler.cmake | 7 +-- cmake/modules/RootBuildOptions.cmake | 4 -- test/CMakeLists.txt | 9 ---- test/cmake/cuda/CMakeLists.txt | 72 ---------------------------- test/cmake/cuda/CheckLanguage.cmake | 22 --------- 5 files changed, 2 insertions(+), 112 deletions(-) delete mode 100644 test/cmake/cuda/CMakeLists.txt delete mode 100644 test/cmake/cuda/CheckLanguage.cmake diff --git a/cmake/modules/CheckCompiler.cmake b/cmake/modules/CheckCompiler.cmake index 3c1c11ee47e2b..bab91fd76e5f3 100644 --- a/cmake/modules/CheckCompiler.cmake +++ b/cmake/modules/CheckCompiler.cmake @@ -56,11 +56,8 @@ else() set(CMAKE_Fortran_COMPILER CMAKE_Fortran_COMPILER-NOTFOUND) endif() -#---Check CUDA only for requested features or to select their defaults with 'all'---------------- -# Both CUDA options default to OFF. With 'all', discover availability unless both are explicitly -# disabled or 'gminimal' will disable their defaults again. -if(cuda OR tmva-gpu OR - (all AND NOT gminimal AND (NOT DEFINED cuda OR NOT DEFINED tmva-gpu))) +#---Check CUDA only for requested features ---------------- +if(cuda OR tmva-gpu) check_language(CUDA) if(CMAKE_CUDA_COMPILER) enable_language(CUDA) diff --git a/cmake/modules/RootBuildOptions.cmake b/cmake/modules/RootBuildOptions.cmake index 951464c75809a..5d0360e471eb1 100644 --- a/cmake/modules/RootBuildOptions.cmake +++ b/cmake/modules/RootBuildOptions.cmake @@ -243,10 +243,6 @@ if(all) set(x11_defvalue ON) set(xml_defvalue ON) set(xrootd_defvalue ON) - if(CMAKE_CUDA_COMPILER) - set(cuda_defvalue ON) - set(tmva-gpu_defvalue ON) - endif() endif() #--- The 'builtin_all' option switches ON all the built in options but GPL------------------------------- diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 5cfefd251bcba..c4d75e93b327a 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -12,15 +12,6 @@ set(root_exe $) #---environment------------------------------------------------------------------------------- ROOT_ADD_TEST(show-environment COMMAND ${CMAKE_COMMAND} -E environment) -#---CUDA compiler detection-------------------------------------------------------------------- -foreach(case default disabled cached-disabled cuda tmva-gpu all all-disabled all-cuda-disabled - all-tmva-disabled minimal gminimal all-gminimal unavailable) - ROOT_ADD_TEST(cmake-cuda-${case} - COMMAND ${CMAKE_COMMAND} -S ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cuda - -B ${CMAKE_CURRENT_BINARY_DIR}/cmake/cuda-${case} - -DROOT_SOURCE_DIR=${CMAKE_SOURCE_DIR} -DCASE=${case}) -endforeach() - #---hworld------------------------------------------------------------------------------------ ROOT_EXECUTABLE(hworld hworld.cxx LIBRARIES Gpad) diff --git a/test/cmake/cuda/CMakeLists.txt b/test/cmake/cuda/CMakeLists.txt deleted file mode 100644 index 8d8b8f7fc94d8..0000000000000 --- a/test/cmake/cuda/CMakeLists.txt +++ /dev/null @@ -1,72 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(CheckCUDA LANGUAGES C CXX) - -list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}" "${ROOT_SOURCE_DIR}/cmake/modules") -# Keep repeated CTest runs independent of options cached by the previous configure. -foreach(opt cuda tmva-gpu all minimal gminimal CMAKE_CUDA_COMPILER) - unset(${opt} CACHE) -endforeach() -set(fortran OFF) -set(expect_cuda OFF) -set(cuda_available ON) -set(expect_cuda_option OFF) -set(expect_tmva_gpu_option OFF) - -if(CASE STREQUAL "disabled" OR CASE STREQUAL "cached-disabled" OR CASE STREQUAL "all-disabled") - set(cuda OFF CACHE BOOL "") - set(tmva-gpu OFF CACHE BOOL "") - if(CASE STREQUAL "cached-disabled") - set(CMAKE_CUDA_COMPILER mock-cuda-compiler CACHE FILEPATH "") - elseif(CASE STREQUAL "all-disabled") - set(all ON) - endif() -elseif(CASE STREQUAL "cuda") - set(cuda ON CACHE BOOL "") - set(expect_cuda ON) - set(expect_cuda_option ON) -elseif(CASE STREQUAL "tmva-gpu") - set(tmva-gpu ON CACHE BOOL "") - set(expect_cuda ON) - set(expect_tmva_gpu_option ON) -elseif(CASE STREQUAL "all" OR CASE STREQUAL "all-cuda-disabled" OR CASE STREQUAL "all-tmva-disabled") - set(all ON) - set(expect_cuda ON) - set(expect_cuda_option ON) - set(expect_tmva_gpu_option ON) - if(CASE STREQUAL "all-cuda-disabled") - set(cuda OFF CACHE BOOL "") - set(expect_cuda_option OFF) - elseif(CASE STREQUAL "all-tmva-disabled") - set(tmva-gpu OFF CACHE BOOL "") - set(expect_tmva_gpu_option OFF) - endif() -elseif(CASE STREQUAL "minimal") - set(minimal ON) -elseif(CASE STREQUAL "gminimal" OR CASE STREQUAL "all-gminimal") - set(gminimal ON) - if(CASE STREQUAL "all-gminimal") - set(all ON) - endif() -elseif(CASE STREQUAL "unavailable") - set(all ON) - set(expect_cuda ON) - set(cuda_available OFF) -elseif(NOT CASE STREQUAL "default") - message(FATAL_ERROR "Unknown test case: ${CASE}") -endif() - -include(CheckCompiler) -include(RootBuildOptions) - -if(expect_cuda AND NOT cuda_checked) - message(FATAL_ERROR "CUDA compiler detection was skipped") -endif() -if(expect_cuda AND cuda_available AND NOT cuda_enabled) - message(FATAL_ERROR "The CUDA language was not initialized") -endif() -if(NOT "${cuda}" STREQUAL "${expect_cuda_option}") - message(FATAL_ERROR "Expected cuda=${expect_cuda_option}, got ${cuda}") -endif() -if(NOT "${tmva-gpu}" STREQUAL "${expect_tmva_gpu_option}") - message(FATAL_ERROR "Expected tmva-gpu=${expect_tmva_gpu_option}, got ${tmva-gpu}") -endif() diff --git a/test/cmake/cuda/CheckLanguage.cmake b/test/cmake/cuda/CheckLanguage.cmake deleted file mode 100644 index febec470c11b6..0000000000000 --- a/test/cmake/cuda/CheckLanguage.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# Simulate CUDA availability so these tests do not require a CUDA installation. -function(check_language language) - if(NOT language STREQUAL "CUDA") - message(FATAL_ERROR "Unexpected compiler check for ${language}") - endif() - if(NOT expect_cuda) - message(FATAL_ERROR "CUDA compiler detection was not requested") - endif() - set(cuda_checked TRUE PARENT_SCOPE) - if(cuda_available) - set(CMAKE_CUDA_COMPILER mock-cuda-compiler PARENT_SCOPE) - else() - set(CMAKE_CUDA_COMPILER CMAKE_CUDA_COMPILER-NOTFOUND PARENT_SCOPE) - endif() -endfunction() - -function(enable_language language) - if(NOT language STREQUAL "CUDA" OR NOT expect_cuda OR NOT cuda_available) - message(FATAL_ERROR "Unexpected language initialization for ${language}") - endif() - set(cuda_enabled TRUE PARENT_SCOPE) -endfunction()