piwis
piwis

Reputation: 23

How to prevent cmake from linking to libcudart.so?

I have a CUDA program (cuda_test.cc) that I would like to run even on a machine that has no CUDA device (in which case it will execute an algorithm on the cpu instead of on the gpu). From the command line it is rather straightforward:

machine-with-cuda$ nvcc -ccbin g++ -o cuda_test cuda_test.cc
machine-without-cuda$ ./cuda_test 
You don't have a CUDA device

However, I need to use cmake because my program will be included in an existing library that uses cmake. Cmake always calls c++ with the -rdynamic /usr/local/cuda/lib64/libcudart.so, so I end up with an executable linked to libcudart.so, whic

machine-with-cuda$ cat CMakeLists.txt 
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
FIND_PACKAGE(CUDA)
SET(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -ccbin g++")
CUDA_ADD_EXECUTABLE(cuda_test cuda_test.cc)

machine-with-cuda$ make
...
/usr/bin/c++       CMakeFiles/cuda_test.dir/cuda_test.cc.o  -o cuda_test -rdynamic /usr/local/cuda/lib64/libcudart.so -Wl,-rpath,/usr/local/cuda/lib64 
...

machine-without-cuda$ ./cuda_test
error while loading shared libraries: libcudart.so.6.5: cannot open shared object file: No such file or directory

(Note that even in compiling a .cu file instead of a .cc, I still end up with an executable linked to libcudart.so).

How can I prevent cmake from linking to libcudart.so? Or is there another way to make sure that my program will be able to run even if cuda is not installed?

Thank you very much

Upvotes: 2

Views: 1678

Answers (1)

Robert Crovella
Robert Crovella

Reputation: 152143

The recommended approach to creating a CUDA program that will run correctly even if on a machine without a GPU (and therefore without CUDA) is to include the cuda runtime provided by libcudart.

There are two possible methods for this:

  1. If you intend to have your application dynamically linked against the CUDA runtime library (i.e. against libcudart.so on linux, or cudart.lib/cudart.dll on windows), then you should bundle and redistribute the appropriate library with your application. (Yes, you are permitted to redistribute these libraries.)

  2. Alternatively, you can statically link against libcudart, and there is no separate bundling or redistribution needed.

Using either of the above methods, your application would then query the CUDA runtime library (e.g. using cudaGetDeviceProperties, or cudaGetDeviceCount). If the first query to the library throws an error, then the usual response at this point is that "there is no proper CUDA installation", and so your code would take the non-CUDA codepath.

Upvotes: 4

Related Questions