瀏覽代碼

CUDA: Error on empty/invalid CMAKE_CUDA_ARCHITECTURES set by user

If empty we otherwise treat it the same as unset in most places, but still end
up failing eventually with a confusing "Failed to find a working CUDA
architecture".

This also detects some other basic invalid ones (e.g. "al").
Raul Tambre 3 年之前
父節點
當前提交
7a0d098352

+ 5 - 0
Help/release/dev/cuda-invalid-architectures.rst

@@ -0,0 +1,5 @@
+cuda-invalid-architectures
+--------------------------
+
+* CUDA compiler detection now tries to detect invalid architectures and issue
+  an error.

+ 8 - 1
Modules/CMakeDetermineCUDACompiler.cmake

@@ -257,7 +257,7 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN)
   endif()
 
   # Append user-specified architectures.
-  if(CMAKE_CUDA_ARCHITECTURES)
+  if(DEFINED CMAKE_CUDA_ARCHITECTURES)
     if("x${CMAKE_CUDA_ARCHITECTURES}" STREQUAL "xall")
       string(APPEND nvcc_test_flags " -arch=all")
       set(architectures_mode all)
@@ -279,6 +279,13 @@ if(NOT CMAKE_CUDA_COMPILER_ID_RUN)
     set(CMAKE_CUDA_COMPILER_ID_REQUIRE_SUCCESS ON)
   endif()
 
+  # Rest of the code treats an empty value as equivalent to "use the defaults".
+  # Error out early to prevent confusing errors as a result of this.
+  # Note that this also catches invalid non-numerical values such as "a".
+  if(architectures_mode STREQUAL "explicit" AND "${tested_architectures}" STREQUAL "")
+    message(FATAL_ERROR "CMAKE_CUDA_ARCHITECTURES must be valid if set.")
+  endif()
+
   if(CMAKE_CUDA_COMPILER_ID STREQUAL "Clang")
     if(NOT CMAKE_CUDA_ARCHITECTURES)
       # Clang doesn't automatically select an architecture supported by the SDK.

+ 4 - 0
Tests/RunCMake/CMakeLists.txt

@@ -534,6 +534,10 @@ add_RunCMake_test(no_install_prefix)
 add_RunCMake_test(configure_file)
 add_RunCMake_test(CTestTimeout -DTIMEOUT=${CTestTestTimeout_TIME})
 add_RunCMake_test(CTestTimeoutAfterMatch)
+if(CMake_TEST_CUDA)
+  add_RunCMake_test(CUDA_architectures)
+  set_property(TEST RunCMake.CUDA_architectures APPEND PROPERTY LABELS "CUDA")
+endif()
 add_RunCMake_test(DependencyGraph -DCMAKE_Fortran_COMPILER=${CMAKE_Fortran_COMPILER})
 
 # ctresalloc links against CMakeLib and CTestLib, which means it can't be built

+ 3 - 0
Tests/RunCMake/CUDA_architectures/CMakeLists.txt

@@ -0,0 +1,3 @@
+cmake_minimum_required(VERSION 3.22)
+project(${RunCMake_TEST} NONE)
+include(${RunCMake_TEST}.cmake)

+ 4 - 0
Tests/RunCMake/CUDA_architectures/RunCMakeTest.cmake

@@ -0,0 +1,4 @@
+include(RunCMake)
+
+run_cmake(architectures-empty)
+run_cmake(architectures-invalid)

+ 1 - 0
Tests/RunCMake/CUDA_architectures/architectures-empty-result.txt

@@ -0,0 +1 @@
+1

+ 5 - 0
Tests/RunCMake/CUDA_architectures/architectures-empty-stderr.txt

@@ -0,0 +1,5 @@
+^CMake Error at .*/Modules/CMakeDetermineCUDACompiler\.cmake:[0-9]+ \(message\):
+  CMAKE_CUDA_ARCHITECTURES must be valid if set\.
+Call Stack \(most recent call first\):
+  architectures-empty\.cmake:2 \(enable_language\)
+  CMakeLists\.txt:3 \(include\)

+ 2 - 0
Tests/RunCMake/CUDA_architectures/architectures-empty.cmake

@@ -0,0 +1,2 @@
+set(CMAKE_CUDA_ARCHITECTURES "")
+enable_language(CUDA)

+ 1 - 0
Tests/RunCMake/CUDA_architectures/architectures-invalid-result.txt

@@ -0,0 +1 @@
+1

+ 5 - 0
Tests/RunCMake/CUDA_architectures/architectures-invalid-stderr.txt

@@ -0,0 +1,5 @@
+^CMake Error at .*/Modules/CMakeDetermineCUDACompiler\.cmake:[0-9]+ \(message\):
+  CMAKE_CUDA_ARCHITECTURES must be valid if set\.
+Call Stack \(most recent call first\):
+  architectures-invalid\.cmake:2 \(enable_language\)
+  CMakeLists\.txt:3 \(include\)$

+ 2 - 0
Tests/RunCMake/CUDA_architectures/architectures-invalid.cmake

@@ -0,0 +1,2 @@
+set(CMAKE_CUDA_ARCHITECTURES "invalid")
+enable_language(CUDA)