Search code examples
cudacmakethrustnvcc

Undefined Symbol Error when using thrust::max_element


I am working on a CUDA C++ project that uses separable compilation, and I am having some trouble getting a thrust function to compile.

The project builds with no problem until the following function call is added.

thrust::device_ptr<float> max_int = thrust::max_element(
    thrust::device_ptr<float>(dev_temp_intensity_buffer),
    thrust::device_ptr<float>(dev_temp_intensity_buffer + INT_BUF_SIZE);

As said, I get the build error:

Severity    Code    Description Project File    Line    Suppression State
Error   LNK2019 unresolved external symbol __fatbinwrap_66_tmpxft_00006db0_00000000_18_cuda_device_runtime_compute_61_cpp1_ii_8b1a5d37 referenced in function __cudaRegisterLinkedBinary_66_tmpxft_00006db0_00000000_18_cuda_device_runtime_compute_61_cpp1_ii_8b1a5d37 visualize   C:\Users\13\Google Drive\WireMeshOT Rafael\CUDA\simulator\build\src\visualize_intermediate_link.obj 1   

The funny thing is that this other thrust function call compiles just fine:

thrust::exclusive_scan(thrust::device_ptr<unsigned int>(dev_ray_alive),
    thrust::device_ptr<unsigned int>(dev_ray_alive + NRAYS),
    thrust::device_ptr<unsigned int>(dev_scanned_alive_rays));

Obs1: dev_temp_intensity_buffer is a float device pointer, and I am including thrust/extrema.h and thrust/device_ptr.h.

Obs2: I am using CMake to configure the build. The relevant CMake code excerpts are shown below.

SET(CUDA_SEPARABLE_COMPILATION ON)

set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -rdc=true -D_FORCE_INLINES) 
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -arch=compute_52  -code=sm_52 -lcudart -lcudadevrt -lcuda)
set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS} -Xptxas -v)

cuda_add_executable(
 project 
 file1.cu
  ...)

target_link_libraries (project glut glew)

Solution

  • I finally figured it out!

    The linking problem was due to the fact that cudadevrt library was missing. The catch is that only adding -lcudadevrt to the CUDA_NVCC_FLAGS was not enough!

    The problem goes away when linking the CUDA runtime device library to the CMake target as shown below:

    target_link_libraries(project glut glew ${CUDA_cudadevrt_LIBRARY})

    Obs1: the CUDA_cudadevrt_LIBRARY variable is only made available on CMake versions above 3.7.2. Adding the line cmake_minimum_required(VERSION 3.7.2) is a good idea.

    Obs2: linking only to CUDA_LIBRARIES as below does solve the issue only if you are using a CMake version above 3.7.2. On lower versions this variable exist but does not contain cudadevrt library.

    target_link_libraries(project glut glew ${CUDA_LIBRARIES})