FindCUDA: Improve detection of CUDA
Currently it is nearly always necessary to set the CUDA compiler manually when you install the Ubuntu package nvidia-cuda-toolkit:
- 18.04:
- nvidia-cuda-toolkit: CUDA 9.1
- default GCC: 7.4
- Required adjustment: Set CUDA_HOST_COMPILER (CMake 3.10 don't use
CUDAHOSTCXX
) to GCC 6
- 20.04:
- nvidia-cuda-toolkit: CUDA 10.1
- default GCC: 9.3
- Required adjustment: Set CUDA_HOST_COMPILER/CUDAHOSTCXX to GCC 8
- 20.10:
- nvidia-cuda-toolkit: CUDA 11.0.3
- default GCC: 10.2
- Required adjustment: Set CUDA_HOST_COMPILER/CUDAHOSTCXX to GCC 9
- 21.04:
- nvidia-cuda-toolkit: CUDA 11.2.2
- default GCC: 10.3
- Required adjustment: works already
Required adjustments examples:
CUDA_HOST_COMPILER=/usr/lib/nvidia-cuda-toolkit/bin/gcc
- Environment variable
CUDAHOSTCXX
with/usr/lib/nvidia-cuda-toolkit/bin/gcc
The package nvidia-cuda-toolkit
already provides a script to solve this issue (/usr/lib/nvidia-cuda-toolkit/bin/gcc
)
#!/bin/sh
# Check for g++ to avoid using different versions of gcc and g++ on systems
# with both g++-4.X and gcc-4.Y but not g++-4.Y installed.
prog=false
if g++-8 --version >/dev/null 2>&1; then
prog=g++-8
elif g++-7 --version >/dev/null 2>&1; then
prog=g++-7
elif g++-6 --version >/dev/null 2>&1; then
prog=g++-6
elif g++-5 --version >/dev/null 2>&1; then
prog=g++-5
...
else
echo "ERROR: No supported gcc/g++ host compiler found." >&2
echo " Use 'nvcc -ccbin <compiler>' to specify a host compiler." >&2
exit 1
fi
exec $prog "$@"
But this script is never used due to the code of FindCUDA:
if(DEFINED ENV{CUDAHOSTCXX})
set(CUDA_HOST_COMPILER "$ENV{CUDAHOSTCXX}" CACHE FILEPATH "Host side compiler used by NVCC")
elseif(CMAKE_GENERATOR MATCHES "Visual Studio")
...
else()
if(APPLE
AND "${CMAKE_C_COMPILER_ID}" MATCHES "Clang"
AND "${CMAKE_C_COMPILER}" MATCHES "/cc$")
...
elseif(MSVC AND "${CMAKE_C_COMPILER}" MATCHES "clcache|sccache")
# NVCC does not think it will work if it is passed clcache.exe or sccache.exe
# as the host compiler, which means that builds with CC=cl.exe won't work.
# Best to just feed it whatever the actual cl.exe is as the host compiler.
set(CUDA_HOST_COMPILER "cl.exe" CACHE FILEPATH "Host side compiler used by NVCC")
else()
set(CUDA_HOST_COMPILER "${CMAKE_C_COMPILER}"
CACHE FILEPATH "Host side compiler used by NVCC")
endif()
endif()
So in case ENV{CUDAHOSTCXX}
is not set, the CUDA_HOST_COMPILER
is always set to ${CMAKE_C_COMPILER}
.
Better would be:
- Set
CUDA_HOST_COMPILER
toENV{CUDAHOSTCXX}
, if present - if
ENV{CUDAHOSTCXX}
is not present call/usr/lib/nvidia-cuda-toolkit/bin/gcc -dumpfullversion
:- If the returned version is below the version provided by
${CMAKE_C_COMPILER} -dumpfullversion
use this - Otherwise use
${CMAKE_C_COMPILER}
- If the returned version is below the version provided by
Further adjustments:
- Change message to contain the compiler (e.g.
Found CUDA Toolkit v10.1
=>Found CUDA Toolkit v10.1 (using GCC 7.3.0)
) - Use
try_compile
to check if the compiler is compatible to CUDA. Otherwise abort so you don't need to spend time on a build which fails later.
Edited by Brad King