summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2023-09-15 15:47:28 (GMT)
committerBrad King <brad.king@kitware.com>2023-09-21 19:34:28 (GMT)
commit8617c28221cac2bd89402178b25dcd47445a9349 (patch)
tree4570dd05f43aedb4d2f14c13a9c1d5e188654ad9
parent0db0fe7958346ace0f5f01496e071c365faf3eb9 (diff)
downloadCMake-8617c28221cac2bd89402178b25dcd47445a9349.zip
CMake-8617c28221cac2bd89402178b25dcd47445a9349.tar.gz
CMake-8617c28221cac2bd89402178b25dcd47445a9349.tar.bz2
CUDA: Factor out helper for detecting native CUDA architectures
Prepare to use it for other languages.
-rw-r--r--Modules/CMakeCUDACompilerABI.cu25
-rw-r--r--Modules/CMakeCompilerCUDAArch.h29
-rw-r--r--Modules/CMakeTestCUDACompiler.cmake49
-rw-r--r--Modules/Internal/CMakeCUDAArchitecturesNative.cmake49
4 files changed, 84 insertions, 68 deletions
diff --git a/Modules/CMakeCUDACompilerABI.cu b/Modules/CMakeCUDACompilerABI.cu
index 8463e86..b04d0ec 100644
--- a/Modules/CMakeCUDACompilerABI.cu
+++ b/Modules/CMakeCUDACompilerABI.cu
@@ -2,11 +2,8 @@
# error "A C or C++ compiler has been selected for CUDA"
#endif
-#include <cstdio>
-
-#include <cuda_runtime.h>
-
#include "CMakeCompilerABI.h"
+#include "CMakeCompilerCUDAArch.h"
int main(int argc, char* argv[])
{
@@ -19,25 +16,7 @@ int main(int argc, char* argv[])
#endif
static_cast<void>(argv);
- int count = 0;
- if (cudaGetDeviceCount(&count) != cudaSuccess || count == 0) {
- std::fprintf(stderr, "No CUDA devices found.\n");
- return -1;
- }
-
- int found = 0;
- const char* sep = "";
- for (int device = 0; device < count; ++device) {
- cudaDeviceProp prop;
- if (cudaGetDeviceProperties(&prop, device) == cudaSuccess) {
- std::printf("%s%d%d", sep, prop.major, prop.minor);
- sep = ";";
- found = 1;
- }
- }
-
- if (!found) {
- std::fprintf(stderr, "No CUDA architecture detected from any devices.\n");
+ if (!cmakeCompilerCUDAArch()) {
// Convince the compiler that the non-zero return value depends
// on the info strings so they are not optimized out.
return require ? -1 : 1;
diff --git a/Modules/CMakeCompilerCUDAArch.h b/Modules/CMakeCompilerCUDAArch.h
new file mode 100644
index 0000000..dcb030f
--- /dev/null
+++ b/Modules/CMakeCompilerCUDAArch.h
@@ -0,0 +1,29 @@
+#include <cstdio>
+
+#include <cuda_runtime.h>
+
+static bool cmakeCompilerCUDAArch()
+{
+ int count = 0;
+ if (cudaGetDeviceCount(&count) != cudaSuccess || count == 0) {
+ std::fprintf(stderr, "No CUDA devices found.\n");
+ return -1;
+ }
+
+ bool found = false;
+ const char* sep = "";
+ for (int device = 0; device < count; ++device) {
+ cudaDeviceProp prop;
+ if (cudaGetDeviceProperties(&prop, device) == cudaSuccess) {
+ std::printf("%s%d%d", sep, prop.major, prop.minor);
+ sep = ";";
+ found = true;
+ }
+ }
+
+ if (!found) {
+ std::fprintf(stderr, "No CUDA architecture detected from any devices.\n");
+ }
+
+ return found;
+}
diff --git a/Modules/CMakeTestCUDACompiler.cmake b/Modules/CMakeTestCUDACompiler.cmake
index 79ee20f..3057fe9 100644
--- a/Modules/CMakeTestCUDACompiler.cmake
+++ b/Modules/CMakeTestCUDACompiler.cmake
@@ -22,51 +22,10 @@ if(CMAKE_CUDA_ABI_COMPILED)
set(CMAKE_CUDA_COMPILER_WORKS TRUE)
message(STATUS "Check for working CUDA compiler: ${CMAKE_CUDA_COMPILER} - skipped")
- # Run the test binary to detect the native architectures.
- execute_process(COMMAND "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_CUDA.bin"
- RESULT_VARIABLE _CUDA_ARCHS_RESULT
- OUTPUT_VARIABLE _CUDA_ARCHS_OUTPUT
- ERROR_VARIABLE _CUDA_ARCHS_OUTPUT
- OUTPUT_STRIP_TRAILING_WHITESPACE
- )
- if(_CUDA_ARCHS_RESULT EQUAL 0)
- if("$ENV{CMAKE_CUDA_ARCHITECTURES_NATIVE_CLAMP}")
- # Undocumented hook used by CMake's CI.
- # Clamp native architecture to version range supported by this CUDA.
- list(GET CMAKE_CUDA_ARCHITECTURES_ALL 0 _CUDA_ARCH_MIN)
- list(GET CMAKE_CUDA_ARCHITECTURES_ALL -1 _CUDA_ARCH_MAX)
- set(CMAKE_CUDA_ARCHITECTURES_NATIVE "")
- foreach(_CUDA_ARCH IN LISTS _CUDA_ARCHS_OUTPUT)
- if(_CUDA_ARCH LESS _CUDA_ARCH_MIN)
- set(_CUDA_ARCH "${_CUDA_ARCH_MIN}")
- endif()
- if(_CUDA_ARCH GREATER _CUDA_ARCH_MAX)
- set(_CUDA_ARCH "${_CUDA_ARCH_MAX}")
- endif()
- list(APPEND CMAKE_CUDA_ARCHITECTURES_NATIVE ${_CUDA_ARCH})
- endforeach()
- unset(_CUDA_ARCH)
- unset(_CUDA_ARCH_MIN)
- unset(_CUDA_ARCH_MAX)
- else()
- set(CMAKE_CUDA_ARCHITECTURES_NATIVE "${_CUDA_ARCHS_OUTPUT}")
- endif()
- list(REMOVE_DUPLICATES CMAKE_CUDA_ARCHITECTURES_NATIVE)
- list(TRANSFORM CMAKE_CUDA_ARCHITECTURES_NATIVE APPEND "-real")
- else()
- if(NOT _CUDA_ARCHS_RESULT MATCHES "[0-9]+")
- set(_CUDA_ARCHS_STATUS " (${_CUDA_ARCHS_RESULT})")
- else()
- set(_CUDA_ARCHS_STATUS "")
- endif()
- string(REPLACE "\n" "\n " _CUDA_ARCHS_OUTPUT " ${_CUDA_ARCHS_OUTPUT}")
- message(CONFIGURE_LOG
- "Detecting the CUDA native architecture(s) failed with "
- "the following output:\n${_CUDA_ARCHS_OUTPUT}\n\n")
- endif()
- unset(_CUDA_ARCHS_EXE)
- unset(_CUDA_ARCHS_RESULT)
- unset(_CUDA_ARCHS_OUTPUT)
+ include(Internal/CMakeCUDAArchitecturesNative)
+ # Run the test binary to get:
+ # - CMAKE_CUDA_ARCHITECTURES_NATIVE
+ cmake_cuda_architectures_native(CUDA)
endif()
# This file is used by EnableLanguage in cmGlobalGenerator to
diff --git a/Modules/Internal/CMakeCUDAArchitecturesNative.cmake b/Modules/Internal/CMakeCUDAArchitecturesNative.cmake
new file mode 100644
index 0000000..4185eda
--- /dev/null
+++ b/Modules/Internal/CMakeCUDAArchitecturesNative.cmake
@@ -0,0 +1,49 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+function(cmake_cuda_architectures_native lang)
+ # Run the test binary to detect the native architectures.
+ execute_process(COMMAND "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_${lang}.bin"
+ RESULT_VARIABLE archs_result
+ OUTPUT_VARIABLE archs_output
+ ERROR_VARIABLE archs_output
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ if(archs_result EQUAL 0)
+ if("$ENV{CMAKE_CUDA_ARCHITECTURES_NATIVE_CLAMP}")
+ # Undocumented hook used by CMake's CI.
+ # Clamp native architecture to version range supported by this CUDA.
+ list(GET CMAKE_${lang}_ARCHITECTURES_ALL 0 arch_min)
+ list(GET CMAKE_${lang}_ARCHITECTURES_ALL -1 arch_max)
+ set(CMAKE_CUDA_ARCHITECTURES_NATIVE "")
+ foreach(arch IN LISTS archs_output)
+ if(arch LESS arch_min)
+ set(arch "${arch_min}")
+ endif()
+ if(arch GREATER arch_max)
+ set(arch "${arch_max}")
+ endif()
+ list(APPEND CMAKE_CUDA_ARCHITECTURES_NATIVE ${arch})
+ endforeach()
+ unset(arch)
+ unset(arch_min)
+ unset(arch_max)
+ else()
+ set(CMAKE_CUDA_ARCHITECTURES_NATIVE "${archs_output}")
+ endif()
+ list(REMOVE_DUPLICATES CMAKE_CUDA_ARCHITECTURES_NATIVE)
+ list(TRANSFORM CMAKE_CUDA_ARCHITECTURES_NATIVE APPEND "-real")
+ else()
+ if(NOT archs_result MATCHES "[0-9]+")
+ set(archs_status " (${archs_result})")
+ else()
+ set(archs_status "")
+ endif()
+ string(REPLACE "\n" "\n " archs_output " ${archs_output}")
+ message(CONFIGURE_LOG
+ "Detecting the CUDA native architecture(s) failed with "
+ "the following output${archs_status}:\n${archs_output}\n\n")
+ endif()
+
+ set(CMAKE_${lang}_ARCHITECTURES_NATIVE "${CMAKE_CUDA_ARCHITECTURES_NATIVE}" PARENT_SCOPE)
+endfunction()