Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake CUDA separate compilation static lib link error on Windows but not on Ubuntu

Tags:

c++

cuda

cmake

I am using CMake to compile a CUDA project, which contains a static lib and a main file. MWE here. The directory is:

├── CMakeLists.txt ├── src ├── mylib.h ├── mylib.cu ├── test ├── CMakeLists.txt ├── main.cpp

On Ubuntu everything works fine. But on Windows I got a link error:

mylib.lib(mylib.cu.obj) : error LNK2019: unresolved external symbol __cudaRegisterLinkedBinary_40_tmpxft_00006024_00000000_7_mylib_cpp1_ii_935b38c5 referenced in function "void __cdecl __sti____cudaRegisterAll(void)" (?__sti____cudaRegisterAll@@YAXXZ)\build\test\Release\main.exe : fatal error LNK1120: 1 unresolved externals

This issue only relates to the first CMakeLists.txt:

cmake_minimum_required(VERSION 3.8)
project(MyTest LANGUAGES CXX CUDA)

# check requirements
find_package(CUDA   8.0 REQUIRED)

# set include and link directories
if (UNIX)
    set(CUDA_SAMPLE_INC ${CUDA_TOOLKIT_ROOT_DIR}/samples/common/inc)
    set(CUDA_TARGET_INC ${CUDA_TOOLKIT_ROOT_DIR}/targets/x86_64-linux/include)
    set(CUDA_SAMPLE_LKN ${CUDA_TOOLKIT_ROOT_DIR}/targets/x86_64-linux/lib)
endif (UNIX)
if (WIN32)
    set(CUDA_SAMPLE_INC C:/ProgramData/NVIDIA\ Corporation/CUDA\ Samples/v9.0/common/inc)
    set(CUDA_TARGET_INC C:/Program\ Files/NVIDIA GPU\ Computing\ Toolkit/CUDA/v9.0/include)
    set(CUDA_SAMPLE_LKN C:/Program\ Files/NVIDIA\ GPU\ Computing\ Toolkit/CUDA/v9.0/lib/x64)
endif (WIN32)
include_directories(src ${CUDA_SAMPLE_INC} ${CUDA_TARGET_INC})
link_directories(${CUDA_SAMPLE_LKN})

# define and compile our static library 
set(STATIC_MY_LIB mylib)
add_library(${STATIC_MY_LIB} STATIC src/mylib.cu)

# install
install(TARGETS ${STATIC_MY_LIB}
        ARCHIVE DESTINATION ${CMAKE_SOURCE_DIR}/lib
        LIBRARY DESTINATION ${CMAKE_SOURCE_DIR}/lib)

# comment it out to suppress the error
set_target_properties( ${STATIC_MY_LIB} PROPERTIES CUDA_SEPARABLE_COMPILATION ON)

# add our test project
add_subdirectory(test)

If I comment out set_target_properties( ${STATIC_MY_LIB} PROPERTIES CUDA_SEPARABLE_COMPILATION ON), the link error is gone.

Environments:

  • Ubuntu 16.04, gcc 5.4, Tesla Titan X, CUDA 9.1, CMake 3.10.1
  • Windows 10, VS 2015, K20c, CUDA 9.0, CMake 3.10.1

I have tried suggestions in 1, 2. But none of them works.

Why this happens? And how to overcome?

like image 710
WDC Avatar asked Apr 26 '18 01:04

WDC


1 Answers

After struggling with this issue for several days, I think I have found a solution. When creating the static library using CMake, set CUDA_RESOLVE_DEVICE_SYMBOLS, i.e. with

set_target_properties(your_project PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON)

According to this article from Nvidia, this setting forces CMake to compile and link all CUDA symbols (function calls and the like) when the library is built.

If you need separable compilation device linking to occur before consumption by a shared library or executable,you can explicitly request CMake to invoke device linking by setting the target property CUDA_RESOLVE_DEVICE_SYMBOLS

like image 165
JAustin Avatar answered Nov 10 '22 07:11

JAustin