CUDA as language: cross-compilation compile ABI detect fails for toolchain without cudadevrt library
Hello,
DriveWorks SDK for cuda-safe variant aarch64-qnx-safe
does not provide cudadevrt
library.
If project uses CUDA as a language, initial ABI check fails first due to hardcoded name in Modules/Compiler/NVIDIA.cmake
set(CMAKE_${lang}_RUNTIME_LIBRARY_LINK_OPTIONS_STATIC "cudadevrt;cudart_static")
set(CMAKE_${lang}_RUNTIME_LIBRARY_LINK_OPTIONS_SHARED "cudadevrt;cudart")
Options are most likely added by #17988 (closed) with assumption it does not hurt.
These variables can't be overridden with custom toolchain file.
Configure fails with following message from try_compile
step:
cannot find -lcudadevrt: No such file or directory
If removed, test itself uses device specific API that is not part of safe implementation:
[ 50%] Building CUDA object CMakeFiles/cuda_test.dir/usr/share/cmake/Modules/CMakeCUDACompilerABI.cu.o
/usr/share/cmake/Modules/CMakeCompilerCUDAArch.h(16): error: identifier "cudaDeviceProp" is undefined
/usr/share/cmake/Modules/CMakeCompilerCUDAArch.h(17): error: identifier "cudaGetDeviceProperties" is undefined
Looks like cudaDeviceGetAttribute
is present on both API variants.
As FindCUDA is deprecated (and many open projects just have their own copy/variant of FindCUDA), it would be nice to have flexibility to configure default check options using nvcc itself or via toolchain variables and have ABI check sample common for CUDA API variants.
nvcc
needs to be invoked with option --cudadevrt=none
and couple of QNX specific parameters: --qpp-config
, --target-dir
Passing these options to nvcc invoked by try_compile
is not clean, the only way I figured out to pass them via CMAKE_CUDA_FLAGS_INIT
.
To reproduce issue on Linux PC it is enough to remove /usr/local/cuda/targets/x86_64-linux/lib/libcudadevrt.a
and configure any project that has enabled CUDA language:
cmake_minimum_required (VERSION 3.25)
project(cuda_test
VERSION "0.1.0"
LANGUAGES CXX CUDA)
add_executable(${PROJECT_NAME} /usr/share/cmake/Modules/CMakeCUDACompilerABI.cu main.cpp)
target_include_directories(${PROJECT_NAME}
PUBLIC
${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}
)
cmake --debug-trycompile -B host -DCMAKE_CUDA_COMPILER="/usr/local/cuda/bin/nvcc" -DCMAKE_CUDA_FLAGS_INIT="--cudadevrt=none" -DCMAKE_CUDA_ARCHITECTURES=50
Note also that project needs explicit CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES
to find CUDA includes for main.cpp:
#include <cuda_runtime_api.h>
int main()
{
return 0;
}
If not, compilation fails with message:
fatal error: cuda_runtime_api.h: No such file or directory
May be it is worth to add CUDA toolkit includes to system lookup paths, if language enabled and configured.
See also: