c++cmakecuda

How to find and link CUDA libraries using CMake 3.15 and later?


I'm using CMake 3.15-rc3 on my Unix-like system.

I need to link a program I'm building with several of the CUDA libraries, including cublas, cufft, cusolver, curand, nppicc, nppial, nppist, nppidei, nppig, nppitc, npps.

Based on what I found online, I need to do something like this:

add_executable(test benchmark.cpp)
find_package(CUDALibs)
target_link_libraries(test CUDA::cudart CUDA::cublas CUDA::cufft CUDA::cusolver CUDA::curand CUDA::nppicc CUDA::nppial CUDA::nppist CUDA::nppidei CUDA::nppig CUDA::nppitc CUDA::npps)

When I run make I get the following error:

CMake Warning at CMakeLists.txt:27 (find_package):
  By not providing "FindCUDALibs.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "CUDALibs",
  but CMake did not find one.

  Could not find a package configuration file provided by "CUDALibs" with any
  of the following names:

    CUDALibsConfig.cmake
    cudalibs-config.cmake

  Add the installation prefix of "CUDALibs" to CMAKE_PREFIX_PATH or set
  "CUDALibs_DIR" to a directory containing one of the above files.  If
  "CUDALibs" provides a separate development package or SDK, be sure it has
  been installed.


So looks like I need a CUDALibsConfig.cmake file. Where do I get this file and how to I tell cmake to use it?

If I use the following it works:

find_package(CUDA REQUIRED)
target_link_libraries(run_benchmarks tf libmxnet.so ${CUDA_LIBRARIES} ${CUDA_cusparse_LIBRARY} ${CUDA_cublas_LIBRARY} ${CUDA_npp_LIBRARY})

But according to this find_package(cuda) is deprecated, so I want to learn the proper usage.

Edit I tried what was suggested in one of the responses. I added CUDA to the project LANGUAGES:

project(
        test_project
        DESCRIPTION "Test project"
        LANGUAGES CXX CUDA
        )

And then I used find_package( FindCUDAToolkit REQUIRED)

However, when I run cmake I get the following errors:

 nchafni   dev  …  sample_code  benchmarks  build  1  cmake ..
-- The CXX compiler identification is GNU 7.5.0
-- The CUDA compiler identification is NVIDIA 10.1.243
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Check for working CUDA compiler: /usr/local/cuda-10.1/bin/nvcc
-- Check for working CUDA compiler: /usr/local/cuda-10.1/bin/nvcc -- works
-- Detecting CUDA compiler ABI info
-- Detecting CUDA compiler ABI info - done
CMake Error at CMakeLists.txt:17 (find_package):
  By not providing "FindFindCUDAToolkit.cmake" in CMAKE_MODULE_PATH this
  project has asked CMake to find a package configuration file provided by
  "FindCUDAToolkit", but CMake did not find one.

  Could not find a package configuration file provided by "FindCUDAToolkit"
  with any of the following names:

    FindCUDAToolkitConfig.cmake
    findcudatoolkit-config.cmake

  Add the installation prefix of "FindCUDAToolkit" to CMAKE_PREFIX_PATH or
  set "FindCUDAToolkit_DIR" to a directory containing one of the above files.
  If "FindCUDAToolkit" provides a separate development package or SDK, be
  sure it has been installed.


-- Configuring incomplete, errors occurred!

What am I missing?


Solution

  • Using find_package(CUDA) is deprecated for the case of programs written in CUDA / compiled with a CUDA compiler (e.g. NVCC). The documentation page says (emphasis mine):

    It is no longer necessary to use this module or call find_package(CUDA) for compiling CUDA code. Instead, list CUDA among the languages named in the top-level call to the project() command, or call the enable_language() command with CUDA. Then one can add CUDA (.cu) sources to programs directly in calls to add_library() and add_executable().

    But find_package(CUDA) was not really deprecated - as of CMake version 3.15 - for C++ code which simply uses CUDA-enabled/CUDA-bundled/CUDA-utilizing libraries; that would have to wait for two more minor versions.

    In CMake 3.17, a find module was introduced: FindCUDAToolkit() - and thus, find_package(CUDAToolkit). You can't use that with your version of CMake (3.15), and find_package(CUDA) will work - but it's clunky and outdated, and will not find various CUDA novelties.

    That is not what I recommend, however. You see, it is actually very easy to upgrade to a newer CMake version: KitWare offer binary releases which have very little dependencies. On a Linux system they would be:

        linux-vdso.so.1
        libdl.so.2
        librt.so.1
        libpthread.so.0
        libm.so.6
        libc.so.6
        /lib64/ld-linux-x86-64.so.2
    

    ... and you would be hard-pressed to find a system without these. Also, even when installed under an arbitrary path, CMake will be able to differentiate between its version of shared files and whatever the system version of CMake uses. So - no reason to stick with the old version.