From a9a290a752ad56be5a23da2de565377aa5cc3bc4 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Sun, 9 Nov 2025 14:43:07 +0100 Subject: [PATCH 1/2] [CMake] Extend ROOT_FIND_PYTHON_MODULE to also save version info This is useful to steer testing depending on the version of Python modules, or give errors/warnings if a module has a version unsupported by ROOT. (cherry picked from commit 763ee06ed4ee5c128f8227361af09a29a693d836) --- cmake/modules/RootMacros.cmake | 36 +++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/cmake/modules/RootMacros.cmake b/cmake/modules/RootMacros.cmake index 9fbb326405df4..a636be0cbd5d5 100644 --- a/cmake/modules/RootMacros.cmake +++ b/cmake/modules/RootMacros.cmake @@ -2083,14 +2083,16 @@ endmacro() # ROOT_FIND_PYTHON_MODULE(module [REQUIRED] [QUIET]) # Try importing the python dependency and cache the result in # ROOT_TEST_ (all upper case). -# Also set ROOT__FOUND (all upper case) as well as ROOT__FOUND -# (the original spelling of the argument) in the parent scope of this function -# for convenient testing in subsequent if(). +# Also set ROOT__FOUND and ROOT__FOUND (the original spelling) +# in the parent scope for convenient testing in subsequent if() statements. +# Additionally, sets ROOT__VERSION (and ROOT__VERSION) +# if the version could be determined. #---------------------------------------------------------------------------- function(ROOT_FIND_PYTHON_MODULE module) CMAKE_PARSE_ARGUMENTS(ARG "REQUIRED;QUIET" "" "" ${ARGN}) string(TOUPPER ${module} module_upper) set(CACHE_VAR ROOT_TEST_${module_upper}) + set(CACHE_VAR_VERSION "${CACHE_VAR}_VERSION") if(NOT DEFINED ${CACHE_VAR}) execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "import ${module}" @@ -2099,8 +2101,23 @@ function(ROOT_FIND_PYTHON_MODULE module) if(${status} EQUAL 0) set(${CACHE_VAR} ON CACHE BOOL "Enable tests depending on '${module}'") + # Only cache a non-empty, non-'unknown' version string. + if(module_version AND NOT module_version STREQUAL "unknown") + set(${CACHE_VAR_VERSION} "${module_version}" CACHE STRING "Detected version of python module ${module}") + else() + # ensure no stale version remains in cache + if(DEFINED ${CACHE_VAR_VERSION}) + unset(${CACHE_VAR_VERSION} CACHE) + endif() + unset(module_version) + endif() else() set(${CACHE_VAR} OFF CACHE BOOL "Enable tests depending on '${module}'") + # ensure version cache entry is removed on failure + if(DEFINED ${CACHE_VAR_VERSION}) + unset(${CACHE_VAR_VERSION} CACHE) + endif() + unset(module_version) endif() if(NOT ARG_QUIET) @@ -2110,12 +2127,25 @@ function(ROOT_FIND_PYTHON_MODULE module) message(STATUS "Could NOT find Python module ${module}. Corresponding tests will be disabled.") endif() endif() + else() + # Cache exists: if a cached version string exists, read it into module_version. + if(DEFINED ${CACHE_VAR_VERSION}) + set(module_version ${${CACHE_VAR_VERSION}}) + endif() endif() # Set the ROOT_xxx_FOUND to the (cached) result of the search: set(ROOT_${module_upper}_FOUND ${${CACHE_VAR}} PARENT_SCOPE) set(ROOT_${module}_FOUND ${${CACHE_VAR}} PARENT_SCOPE) + # Expose version only if module was found and a version string is available. + if(${CACHE_VAR}) + if(DEFINED module_version AND NOT module_version STREQUAL "" AND NOT module_version STREQUAL "unknown") + set(ROOT_${module_upper}_VERSION "${module_version}" PARENT_SCOPE) + set(ROOT_${module}_VERSION "${module_version}" PARENT_SCOPE) + endif() + endif() + if(ARG_REQUIRED AND NOT ${CACHE_VAR}) message(FATAL_ERROR "Python module ${module} is required.") endif() From 7e6535b8bd8a2160a1415239142ea32f51b3d8c9 Mon Sep 17 00:00:00 2001 From: Jonas Rembser Date: Sun, 30 Nov 2025 11:27:20 +0100 Subject: [PATCH 2/2] [tmva][sofie] Require `onnx!=1.19.0` for tests The Python package onnx 1.19.0 has a bug that makes this version unusable: https://github.com/onnx/onnx/issues/7249 In that case, we have to disable the "TestSofieModels" and "TestRModelParserPyTorch" tests, which import onnx indirectly via `torch.onnx`. We should also consider to require `onnx!=1.19.1` in our `requirements.txt` in the future, so our users don't face similar trouble from exporting PyTorch models to onnx. But this should only be done once we are sure that it can also be installed on macOS without breaking something else. Closes #20571. --- tmva/sofie/test/CMakeLists.txt | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/tmva/sofie/test/CMakeLists.txt b/tmva/sofie/test/CMakeLists.txt index cc43b588ad103..7339bb618c54b 100644 --- a/tmva/sofie/test/CMakeLists.txt +++ b/tmva/sofie/test/CMakeLists.txt @@ -127,7 +127,28 @@ endif() # gtest # Look for needed python modules ROOT_FIND_PYTHON_MODULE(torch) -if (ROOT_TORCH_FOUND) + +# onnx 1.19.0 has a bug that makes this version unusable: + + +# https://github.com/onnx/onnx/issues/7249 + + +# In that case, we have to disable the "TestSofieModels" and + + +# "TestRModelParserPyTorch" tests, which import onnx indirectly via torch.onnx + + +ROOT_FIND_PYTHON_MODULE(onnx) +if (ROOT_ONNX_FOUND AND DEFINED ROOT_ONNX_VERSION) + if(ROOT_ONNX_VERSION VERSION_EQUAL "1.19.0") + message(WARNING "Found broken onnx version ${ROOT_ONNX_VERSION} (see https://github.com/onnx/onnx/issues/7249). Some TMVA SOFIE tests will be disabled.") + set(broken_onnx TRUE) + endif() +endif() + +if (ROOT_TORCH_FOUND AND ROOT_ONNX_FOUND AND NOT broken_onnx) configure_file(Conv1dModelGenerator.py Conv1dModelGenerator.py COPYONLY) configure_file(Conv2dModelGenerator.py Conv2dModelGenerator.py COPYONLY) configure_file(Conv3dModelGenerator.py Conv3dModelGenerator.py COPYONLY)