Issue
Newer versions of CMake (3.18 and later), are "aware" of the choice of CUDA architectures which compilation of CUDA code targets. Targets have a href="https://cmake.org/cmake/help/latest/prop_tgt/CUDA_ARCHITECTURES.html#prop_tgt:CUDA_ARCHITECTURES" rel="nofollow noreferrer">CUDA_ARCHITECTURES
property, which, when set, generates the appropriate -gencode arch=whatever,code=whatever
compilation options for you. You will even get a warning if you don't set this value:
CMake Error in CMakeLists.txt:
CUDA_ARCHITECTURES is empty for target "my_cuda_app".
by default, this target property is initialized to CMAKE_CUDA_ARCHITECTURES
. But CMAKE_CUDA_ARCHITECTURES
itself is not initialized to anything (!)
How can we have CMake auto-detect an appropriate value for CUDA_ARCHITECTURES
or the global CMAKD_CUDA_ARCHITECTURES
? That is, use the architectures of GPUs installed on the system?
Solution
CMake actually offers such autodetection capability, but:
- It's undocumented (and will probably be refactored at some point in the future).
- It's part of the deprecated FindCUDA mechanism, and is geared towards direct manipulation of
CUDA_CMAKE_FLAGS
(which isnt what we want). - It doesn't "play nice", and hides its useful-form internal variables from us.
Still, with a little elbow grease, we can make it work.
First, its location: It's in a module, FindCUDA/select_compute_arch
(which, on a Linux system, will be located in /path/to/cmake/root/share/cmake-X.YY/Modules/FindCUDA/select_compute_arch.cmake
).
Now here's how you use it:
include(FindCUDA/select_compute_arch)
CUDA_DETECT_INSTALLED_GPUS(INSTALLED_GPU_CCS_1)
string(STRIP "${INSTALLED_GPU_CCS_1}" INSTALLED_GPU_CCS_2)
string(REPLACE " " ";" INSTALLED_GPU_CCS_3 "${INSTALLED_GPU_CCS_2}")
string(REPLACE "." "" CUDA_ARCH_LIST "${INSTALLED_GPU_CCS_3}")
SET(CMAKE_CUDA_ARCHITECTURES ${CUDA_ARCH_LIST})
If you only want this for a single target, you would replace the last line with:
set_property(TARGET my_target PROPERTY "${CUDA_ARCH_LIST}")
Notes:
When there are no GPUs on your system you may get a result such as:
3.5;5.0;5.3;6.0;6.1;7.0;7.5;7.5+PTX
.This is an issue with CMake which will not be resolved, since the submodule we're using here is not officially supported. So, if you need to compile on systems with no GPUs, either avoid this call or parse your results for the "+PTX" entry.
The
select_compute_arch
submodule has existed for much longer, but in the past you would use it differently, and would include it throughinclude(FindCUDA)
.I wonder if
LIST(APPEND CMAKE_CUDA_ARCHITECTURES
might not be more appropriate thanSET(CMAKE_CUDA_ARCHITECTURES
.See CMake issues 22375 and 19199 for where CMake might go with this in the future. Caveat: I filed those bugs...
Answered By - einpoklum Answer Checked By - Robin (WPSolving Admin)