Skip to content

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 to ENV{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}

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
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information