mirror of
https://github.com/Kitware/CMake.git
synced 2026-02-24 16:49:18 -06:00
CUDA: Factor out helper for detecting native CUDA architectures
Prepare to use it for other languages.
This commit is contained in:
@@ -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;
|
||||
|
||||
29
Modules/CMakeCompilerCUDAArch.h
Normal file
29
Modules/CMakeCompilerCUDAArch.h
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
49
Modules/Internal/CMakeCUDAArchitecturesNative.cmake
Normal file
49
Modules/Internal/CMakeCUDAArchitecturesNative.cmake
Normal file
@@ -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()
|
||||
Reference in New Issue
Block a user