From 492980ebec1c3226de90410ac33339ae9a058b72 Mon Sep 17 00:00:00 2001 From: Allen Xu Date: Thu, 27 Aug 2026 16:29:51 +0800 Subject: [PATCH 1/2] Fix LTO architecture selection with older CMake Signed-off-by: Allen Xu --- cpp/CMakeLists.txt | 16 ++----- cpp/cmake/Modules/SelectLtoArchitecture.cmake | 48 +++++++++++++++++++ cpp/cmake/tests/CMakeLists.txt | 6 +++ cpp/cmake/tests/select_lto_architecture.cmake | 38 +++++++++++++++ 4 files changed, 95 insertions(+), 13 deletions(-) create mode 100644 cpp/cmake/Modules/SelectLtoArchitecture.cmake create mode 100644 cpp/cmake/tests/select_lto_architecture.cmake diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 8e237b08b128..0a01b9c91579 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -186,21 +186,11 @@ set(CUDF_CUDA_DEFINITIONS "") # override must therefore not exceed the architecture of any target GPU on which it will be linked. set(CUDF_LTO_ARCHITECTURE "" - CACHE STRING "LTO fragment architecture; empty selects the minimum supported by the toolkit" + CACHE STRING "LTO fragment architecture; empty selects the minimum configured architecture" ) -if(CUDF_LTO_ARCHITECTURE STREQUAL "") - foreach(architecture IN LISTS CMAKE_CUDA_ARCHITECTURES_ALL) - string(REGEX MATCH "^[0-9]+" architecture "${architecture}") - if(architecture AND (NOT CUDF_LTO_ARCHITECTURE OR architecture LESS CUDF_LTO_ARCHITECTURE)) - set(CUDF_LTO_ARCHITECTURE "${architecture}") - endif() - endforeach() -endif() - -if(NOT CUDF_LTO_ARCHITECTURE MATCHES "^[0-9]+$") - message(FATAL_ERROR "CUDF_LTO_ARCHITECTURE must be a numeric architecture") -endif() +include(cmake/Modules/SelectLtoArchitecture.cmake) +cudf_select_lto_architecture(CUDF_LTO_ARCHITECTURE) message(VERBOSE "CUDF: Using ${CUDF_LTO_ARCHITECTURE} as the common LTO architecture") # For now, disable CMake's automatic module scanning for C++ files. There is an sccache bug in the diff --git a/cpp/cmake/Modules/SelectLtoArchitecture.cmake b/cpp/cmake/Modules/SelectLtoArchitecture.cmake new file mode 100644 index 000000000000..4d72ea1b599d --- /dev/null +++ b/cpp/cmake/Modules/SelectLtoArchitecture.cmake @@ -0,0 +1,48 @@ +# ============================================================================= +# cmake-format: off +# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# cmake-format: on +# ============================================================================= + +include_guard(GLOBAL) + +# Select the common LTO base architecture and return it through output_variable. +function(cudf_select_lto_architecture output_variable) + set(selected_architecture "${CUDF_LTO_ARCHITECTURE}") + + if(selected_architecture STREQUAL "") + # CMAKE_CUDA_ARCHITECTURES is resolved against the active compiler by rapids-cmake. Prefer it + # over CMAKE_CUDA_ARCHITECTURES_ALL, whose value depends on the CMake version and can therefore + # contain architectures that the active compiler no longer supports. + foreach(architecture IN LISTS CMAKE_CUDA_ARCHITECTURES) + string(REGEX MATCH "^[0-9]+" numeric_architecture "${architecture}") + if(numeric_architecture AND (NOT selected_architecture OR numeric_architecture LESS + selected_architecture) + ) + set(selected_architecture "${numeric_architecture}") + endif() + endforeach() + endif() + + if(selected_architecture STREQUAL "") + # Preserve support for symbolic CMake values such as `all` and `all-major`. + foreach(architecture IN LISTS CMAKE_CUDA_ARCHITECTURES_ALL) + string(REGEX MATCH "^[0-9]+" numeric_architecture "${architecture}") + if(numeric_architecture AND (NOT selected_architecture OR numeric_architecture LESS + selected_architecture) + ) + set(selected_architecture "${numeric_architecture}") + endif() + endforeach() + endif() + + if(NOT selected_architecture MATCHES "^[0-9]+$") + message(FATAL_ERROR "CUDF_LTO_ARCHITECTURE must be a numeric architecture") + endif() + + set(${output_variable} + "${selected_architecture}" + PARENT_SCOPE + ) +endfunction() diff --git a/cpp/cmake/tests/CMakeLists.txt b/cpp/cmake/tests/CMakeLists.txt index d9dcabffb800..dec2425e1d90 100644 --- a/cpp/cmake/tests/CMakeLists.txt +++ b/cpp/cmake/tests/CMakeLists.txt @@ -34,3 +34,9 @@ add_test(NAME cudf_export_consumer COMMAND ${CMAKE_COMMAND} --build set_tests_properties(cudf_export_consumer_configure PROPERTIES FIXTURES_SETUP cudf_export_consumer) set_tests_properties(cudf_export_consumer PROPERTIES FIXTURES_REQUIRED cudf_export_consumer) + +add_test( + NAME cudf_lto_architecture_selection + COMMAND ${CMAKE_COMMAND} "-DCUDF_REPOSITORY_DIR=${CUDF_REPOSITORY_DIR}" -P + "${CMAKE_CURRENT_LIST_DIR}/select_lto_architecture.cmake" +) diff --git a/cpp/cmake/tests/select_lto_architecture.cmake b/cpp/cmake/tests/select_lto_architecture.cmake new file mode 100644 index 000000000000..345c2717c75a --- /dev/null +++ b/cpp/cmake/tests/select_lto_architecture.cmake @@ -0,0 +1,38 @@ +# ============================================================================= +# cmake-format: off +# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +# cmake-format: on +# ============================================================================= + +include("${CUDF_REPOSITORY_DIR}/cpp/cmake/Modules/SelectLtoArchitecture.cmake") + +# Verify that the selected LTO architecture matches the expected value. +function(assert_lto_architecture expected configured_architectures all_architectures override) + set(CMAKE_CUDA_ARCHITECTURES "${configured_architectures}") + set(CMAKE_CUDA_ARCHITECTURES_ALL "${all_architectures}") + set(CUDF_LTO_ARCHITECTURE "${override}") + + cudf_select_lto_architecture(actual) + + if(NOT actual STREQUAL expected) + message(FATAL_ERROR "Expected LTO architecture ${expected}, got ${actual}") + endif() +endfunction() + +# CMake 4.0's static list still contains SM50 when paired with CUDA 13, while rapids-cmake's +# compiler-aware configured list correctly begins at SM75. +assert_lto_architecture( + 75 "75-real;80-real;86-real;90a-real;100f-real;120a-real;120" "50;52;60;61;70;75;80;86;90" "" +) + +# CUDA 12 continues to use SM70 as its common LTO base. +assert_lto_architecture( + 70 "70-real;75-real;80-real;86-real;90a-real;90-virtual" "50;52;60;61;70;75;80;86;90" "" +) + +# An explicit user override remains authoritative. +assert_lto_architecture(80 "75-real;80-real" "50;52;60;61;70;75;80" 80) + +# Preserve the existing fallback for symbolic CMake architecture values. +assert_lto_architecture(70 all "70;75;80;86;90" "") From 9938b8216e5c5bf31eba114a5531a2220e14dac9 Mon Sep 17 00:00:00 2001 From: Allen Xu Date: Fri, 28 Aug 2026 11:07:48 +0800 Subject: [PATCH 2/2] Simplify LTO architecture selection Signed-off-by: Allen Xu --- cpp/CMakeLists.txt | 15 ++++-- cpp/cmake/Modules/AddFragment.cmake | 2 +- cpp/cmake/Modules/SelectLtoArchitecture.cmake | 48 ------------------- cpp/cmake/tests/CMakeLists.txt | 6 --- cpp/cmake/tests/select_lto_architecture.cmake | 38 --------------- 5 files changed, 12 insertions(+), 97 deletions(-) delete mode 100644 cpp/cmake/Modules/SelectLtoArchitecture.cmake delete mode 100644 cpp/cmake/tests/select_lto_architecture.cmake diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index 0a01b9c91579..53e1cef85071 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -182,15 +182,22 @@ set(CUDF_CUDA_FLAGS "") set(CUDF_CXX_DEFINITIONS "") set(CUDF_CUDA_DEFINITIONS "") +if(CMAKE_CUDA_COMPILER_VERSION VERSION_GREATER_EQUAL 13.0.0) + set(DEFAULT_CUDF_LTO_ARCHITECTURE 75) +else() + set(DEFAULT_CUDF_LTO_ARCHITECTURE 70) +endif() + # LTO IR can only be linked for targets greater than or equal to its architecture. An explicit # override must therefore not exceed the architecture of any target GPU on which it will be linked. set(CUDF_LTO_ARCHITECTURE - "" - CACHE STRING "LTO fragment architecture; empty selects the minimum configured architecture" + "${DEFAULT_CUDF_LTO_ARCHITECTURE}" + CACHE STRING "LTO fragment architecture" ) -include(cmake/Modules/SelectLtoArchitecture.cmake) -cudf_select_lto_architecture(CUDF_LTO_ARCHITECTURE) +if(NOT CUDF_LTO_ARCHITECTURE MATCHES "^[0-9]+$") + message(FATAL_ERROR "CUDF_LTO_ARCHITECTURE must be a numeric architecture") +endif() message(VERBOSE "CUDF: Using ${CUDF_LTO_ARCHITECTURE} as the common LTO architecture") # For now, disable CMake's automatic module scanning for C++ files. There is an sccache bug in the diff --git a/cpp/cmake/Modules/AddFragment.cmake b/cpp/cmake/Modules/AddFragment.cmake index 55c31ad6496a..a68b52830819 100644 --- a/cpp/cmake/Modules/AddFragment.cmake +++ b/cpp/cmake/Modules/AddFragment.cmake @@ -67,7 +67,7 @@ macro(add_fragment) CUDA_STANDARD 20 CUDA_STANDARD_REQUIRED ON CUDA_VISIBILITY_PRESET hidden - CUDA_ARCHITECTURES ${CUDF_LTO_ARCHITECTURE} + CUDA_ARCHITECTURES ${CUDF_LTO_ARCHITECTURE}-real ) target_link_libraries( ${OBJECT_ID} diff --git a/cpp/cmake/Modules/SelectLtoArchitecture.cmake b/cpp/cmake/Modules/SelectLtoArchitecture.cmake deleted file mode 100644 index 4d72ea1b599d..000000000000 --- a/cpp/cmake/Modules/SelectLtoArchitecture.cmake +++ /dev/null @@ -1,48 +0,0 @@ -# ============================================================================= -# cmake-format: off -# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# cmake-format: on -# ============================================================================= - -include_guard(GLOBAL) - -# Select the common LTO base architecture and return it through output_variable. -function(cudf_select_lto_architecture output_variable) - set(selected_architecture "${CUDF_LTO_ARCHITECTURE}") - - if(selected_architecture STREQUAL "") - # CMAKE_CUDA_ARCHITECTURES is resolved against the active compiler by rapids-cmake. Prefer it - # over CMAKE_CUDA_ARCHITECTURES_ALL, whose value depends on the CMake version and can therefore - # contain architectures that the active compiler no longer supports. - foreach(architecture IN LISTS CMAKE_CUDA_ARCHITECTURES) - string(REGEX MATCH "^[0-9]+" numeric_architecture "${architecture}") - if(numeric_architecture AND (NOT selected_architecture OR numeric_architecture LESS - selected_architecture) - ) - set(selected_architecture "${numeric_architecture}") - endif() - endforeach() - endif() - - if(selected_architecture STREQUAL "") - # Preserve support for symbolic CMake values such as `all` and `all-major`. - foreach(architecture IN LISTS CMAKE_CUDA_ARCHITECTURES_ALL) - string(REGEX MATCH "^[0-9]+" numeric_architecture "${architecture}") - if(numeric_architecture AND (NOT selected_architecture OR numeric_architecture LESS - selected_architecture) - ) - set(selected_architecture "${numeric_architecture}") - endif() - endforeach() - endif() - - if(NOT selected_architecture MATCHES "^[0-9]+$") - message(FATAL_ERROR "CUDF_LTO_ARCHITECTURE must be a numeric architecture") - endif() - - set(${output_variable} - "${selected_architecture}" - PARENT_SCOPE - ) -endfunction() diff --git a/cpp/cmake/tests/CMakeLists.txt b/cpp/cmake/tests/CMakeLists.txt index dec2425e1d90..d9dcabffb800 100644 --- a/cpp/cmake/tests/CMakeLists.txt +++ b/cpp/cmake/tests/CMakeLists.txt @@ -34,9 +34,3 @@ add_test(NAME cudf_export_consumer COMMAND ${CMAKE_COMMAND} --build set_tests_properties(cudf_export_consumer_configure PROPERTIES FIXTURES_SETUP cudf_export_consumer) set_tests_properties(cudf_export_consumer PROPERTIES FIXTURES_REQUIRED cudf_export_consumer) - -add_test( - NAME cudf_lto_architecture_selection - COMMAND ${CMAKE_COMMAND} "-DCUDF_REPOSITORY_DIR=${CUDF_REPOSITORY_DIR}" -P - "${CMAKE_CURRENT_LIST_DIR}/select_lto_architecture.cmake" -) diff --git a/cpp/cmake/tests/select_lto_architecture.cmake b/cpp/cmake/tests/select_lto_architecture.cmake deleted file mode 100644 index 345c2717c75a..000000000000 --- a/cpp/cmake/tests/select_lto_architecture.cmake +++ /dev/null @@ -1,38 +0,0 @@ -# ============================================================================= -# cmake-format: off -# SPDX-FileCopyrightText: Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. -# SPDX-License-Identifier: Apache-2.0 -# cmake-format: on -# ============================================================================= - -include("${CUDF_REPOSITORY_DIR}/cpp/cmake/Modules/SelectLtoArchitecture.cmake") - -# Verify that the selected LTO architecture matches the expected value. -function(assert_lto_architecture expected configured_architectures all_architectures override) - set(CMAKE_CUDA_ARCHITECTURES "${configured_architectures}") - set(CMAKE_CUDA_ARCHITECTURES_ALL "${all_architectures}") - set(CUDF_LTO_ARCHITECTURE "${override}") - - cudf_select_lto_architecture(actual) - - if(NOT actual STREQUAL expected) - message(FATAL_ERROR "Expected LTO architecture ${expected}, got ${actual}") - endif() -endfunction() - -# CMake 4.0's static list still contains SM50 when paired with CUDA 13, while rapids-cmake's -# compiler-aware configured list correctly begins at SM75. -assert_lto_architecture( - 75 "75-real;80-real;86-real;90a-real;100f-real;120a-real;120" "50;52;60;61;70;75;80;86;90" "" -) - -# CUDA 12 continues to use SM70 as its common LTO base. -assert_lto_architecture( - 70 "70-real;75-real;80-real;86-real;90a-real;90-virtual" "50;52;60;61;70;75;80;86;90" "" -) - -# An explicit user override remains authoritative. -assert_lto_architecture(80 "75-real;80-real" "50;52;60;61;70;75;80" 80) - -# Preserve the existing fallback for symbolic CMake architecture values. -assert_lto_architecture(70 all "70;75;80;86;90" "")