11

I am trying to build a cuda project using clang-3.9 based on the following documentation. But I want to use cmake to build my project. I have already set CMAKE_CC_COMPILER and CMAKE_CXX_COMPILER to clang and clang++ respectively.

But the problem is that if I use

file(GLOB_RECURSE CUDA_SOURCES "./*.cu")
CUDA_ADD_LIBRARY(Benchmarks_CUDA ${CUDA_SOURCES})

in my CMakeList.txt then cmake will be using nvcc compiler by default. But instead I want to use clang for compiling .cu files.

Instead if I use

add_library (Benchmarks_CUDA ${CUDA_SOURCES})

then I will get an error

CMake Error: Cannot determine link language for target "Benchmarks_CUDA".
CMake Error: CMake can not determine linker language for target: Benchmarks_CUDA

Can someone tell me how to use cmake to build .cu files using clang.

talonmies
  • 70,661
  • 34
  • 192
  • 269
Johns Paul
  • 633
  • 6
  • 22
  • I'll admit I had no idea that clang could be used as a CUDA compiler. Firstly, I would suggest adding all the flags that the documentation suggests. Secondly, see if setting the language using the project command helps. – Robert Prévost Sep 13 '16 at 05:46
  • @robertprevost: at least you now understand the question being asked. I'll repeat my comment, though. This is a cmake error message caused by there being no association between the .cu file extension and a C++ compile action in the default build commands. – talonmies Sep 13 '16 at 06:08
  • @RobertPrévost i think the problem is because cmake doesn't understand that clang could be used as a compiler for .cu files. That's why I don't have an error when I use CUDA_ADD_LIBRARY. Anyway I tried setting the language using the project command, but it doesn't help. Also, clang can be used for compiling CUDA programs. But their parser or optimizer is not as efficient as NVCC and hence there is atleast a 3x performance degradation for my application. – Johns Paul Sep 13 '16 at 06:17
  • 1
    Alright, the final suggestion I have is to explicitly set the linker language for the target: set_target_properties(Benchmarks_CUDA PROPERTIES LINKER_LANGUAGE CXX). – Robert Prévost Sep 13 '16 at 06:43
  • 1
    @JohnsPaul: I don't believe there is an easy way to do this. CMake doesn't support custom build rules the way that standard make does, so you are going to be left trying to craft a custom command, which isn't very straightforward. – talonmies Sep 13 '16 at 08:53
  • 1
    @JohnsPaul Although clang compiles `.cu` files, it does not support the same options that nvcc does. It will not be a drop in replacement to existing build systems. You can not rely on `CUDA_ADD_LIBRARY` to automatically work as you'd expect. You'd have to create a new function like `CLANG_CUDA_ADD_LIBRARY` that compiles `.cu` files with the appropriate `clang` options. – Pavan Yalamanchili Sep 15 '16 at 06:25

1 Answers1

1

I am afraid I don't have an answer that would have helped you four years ago. However, as is so often the case, using a new CMake version improves things dramatically. CMake 3.18 was the first to officially support using Clang to compile CUDA. I tried that version, but it didn't know how to use my clang++-12 installation. It might have been released after CMake 3.18.

No matter; on CMake 3.19+, setting CMAKE_CUDA_COMPILER "just works" with Clang 12.


First off, here's the CMakeLists.txt:

cmake_minimum_required(VERSION 3.20)
project(clang-cuda-test LANGUAGES CUDA)

add_executable(
  vectorAdd
  # Sources
  vectorAdd.cu
  # Headers
  helper_cuda.h
  helper_string.h
)
target_include_directories(vectorAdd PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")

I've copied the various source files out of the CUDA 11 samples. So I'll set Clang 12 as my compiler (though note my CUDA 11 installation is too new for it, which is why I get a warning):

alex@alex-ubuntu:~/test$ cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_CUDA_COMPILER=clang++-12
-- The CUDA compiler identification is Clang 12.0.1
-- Detecting CUDA compiler ABI info
-- Detecting CUDA compiler ABI info - done
-- Check for working CUDA compiler: /usr/bin/clang++-12 - skipped
-- Detecting CUDA compile features
-- Detecting CUDA compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
alex@alex-ubuntu:~/test$ cmake --build build/ -- -v
[1/2] /usr/bin/clang++-12   -I../ -O3 -DNDEBUG --cuda-gpu-arch=sm_52 --cuda-path=/usr/local/cuda -MD -MT CMakeFiles/vectorAdd.dir/vectorAdd.cu.o -MF CMakeFiles/vectorAdd.dir/vectorAdd.cu.o.d -x cuda -c ../vectorAdd.cu -o CMakeFiles/vectorAdd.dir/vectorAdd.cu.o
clang: warning: Unknown CUDA version. cuda.h: CUDA_VERSION=11030. Assuming the latest supported version 10.1 [-Wunknown-cuda-version]
[2/2] : && /usr/bin/clang++-12  CMakeFiles/vectorAdd.dir/vectorAdd.cu.o -o vectorAdd  -lcudadevrt  -lcudart_static  -lrt  -lpthread  -ldl -L"/usr/local/cuda/lib64" && :
alex@alex-ubuntu:~/test$ ./build/vectorAdd 
[Vector addition of 50000 elements]
Copy input data from the host memory to the CUDA device
CUDA kernel launch with 196 blocks of 256 threads
Copy output data from the CUDA device to the host memory
Test PASSED
Done
Alex Reinking
  • 16,724
  • 5
  • 52
  • 86