将CUDA代码编译/添加到现有项目中(CMake)

5
我正在尝试通过CUDA代码将现有项目的部分移植到GPU。我了解到cmake有选项(find_cuda...)来处理.cu文件,但我仍在努力弄清楚如何在现有项目的背景下使用这个生态系统。
我的问题是:假设我有一个带有cmake配置文件(CMakeLists)的现有C++项目。目前的最佳实践是怎样优雅地(如果可能的话)包含CUDA内核?CMakeLists是否可以构建为只在GPU存在时编译.cu文件?
我的当前想法是创建一个单独的文件夹,其中只存在与CUDA相关的代码,然后将其编译为静态库。这是正确的方法吗?
1个回答

6
拥有独立文件夹的CUDA文件是我推荐的方式,但不是必须的。基本原则是将所有的.cu文件收集到一个CMake变量中(我们称之为),将所有的.cpp文件收集到另一个变量中(称之为)。现在编译这两个文件并将它们放在一起。由提供的变量可用于确定CUDA是否已安装在您的系统上。对于cuda文件使用静态库不是必需的,但我将向您展示两种方法。
在你的顶层CMake文件中,你需要像这样查找CUDA并设置一些nvcc标志:
find_package(CUDA QUIET)
if(CUDA_FOUND)
    include_directories(${CUDA_INCLUDE_DIRS})
    SET(ALL_CUDA_LIBS ${CUDA_LIBRARIES} ${CUDA_cusparse_LIBRARY} ${CUDA_cublas_LIBRARY})
    SET(LIBS ${LIBS} ${ALL_CUDA_LIBS})
    message(STATUS "CUDA_LIBRARIES: ${CUDA_INCLUDE_DIRS} ${ALL_CUDA_LIBS}")
    set(CUDA_PROPAGATE_HOST_FLAGS ON)
    set(CUDA_SEPARABLE_COMPILATION OFF)
    list( APPEND CUDA_NVCC_FLAGS -gencode=arch=compute_30,code=compute_30 )
    list( APPEND CUDA_NVCC_FLAGS -gencode=arch=compute_52,code=sm_52 )
endif()

使用静态CUDA库

if(CUDA_FOUND)
     #collect CUDA files
     FILE(GLOB_RECURSE CUDA_SRC  *.cu)
     #build static library
     CUDA_ADD_LIBRARY(my_cuda_lib ${CUDA_SRC} STATIC)
     SET(LIBS ${LIBS} ${my_cuda_lib})
endif()

#collect cpp files
FILE(GLOB_RECURSE SRC  *.cpp)

#compile .cpp files and link it to all libraries
add_executable(${PROG_NAME} ${SRC})
target_link_libraries(${PROG_NAME} ${LIBS} )

没有静态CUDA库

FILE(GLOB_RECURSE SRC  *.cpp)

if(CUDA_FOUND)
    #compile cuda files and add the compiled object files to your normal source files
    FILE(GLOB_RECURSE CUDA_SRC  *.cu)
    cuda_compile(cuda_objs ${CUDA_SRC})
    SET(SRC ${SRC} ${cuda_objs})
endif()

#compile .cpp files and link it to all libraries
add_executable(${PROG_NAME} ${SRC})
target_link_libraries(${PROG_NAME} ${LIBS} )

太棒了,这正是我想知道的。 - sdgaw erzswer
我刚看到这个问题/答案,但是这个答案对我没有用,它只是导致我遇到了这个CMake错误:(target_link_libraries): 无法为目标“/usr/local/cuda-10.2/lib64/libcudart_static.a”指定链接库,因为它不是由此项目构建的。我在这里发布了一个新问题:https://stackoverflow.com/questions/68320042/cmake-target-link-libraries-cannot-specify-link-libraries-for-target-usr-loc,关于这个问题。 - user904542

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接