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

sdg*_*wer 4 c++ cuda cmake

我正在尝试通过 CUDA 代码将现有项目的一部分移植到 GPU。我知道 cmake 有选项(find_cuda...)来单独处理 .cu 文件,但我仍然试图弄清楚如何在现有项目的上下文中使用这个生态系统。

我的问题如下。假设我有一个带有 cmake 配置文件 (CMakeLists) 的现有 C++ 项目。优雅地(如果可能)包含 CUDA 内核的当前做法是什么?能否以某种方式构建 CMakeLists,仅当存在 GPU 时才编译 .cu 文件?

我目前的想法是创建一个单独的文件夹,其中只存在与CUDA相关的代码,然后将其编译为静态库。这是这样做的方式吗?

dar*_*ari 5

将 CUDA 文件放在单独的文件夹中是我推荐的方式,但不是必需的。基本原则是您将所有 .cu 文件收集在一个 CMake 变量中(我们称之为CUDA_SRC),并将所有 .cpp 文件收集在一个不同的变量中(称之为SRC)。现在您编译这两个文件并将它们放在一起。CUDA_FOUND提供的变量find_package(CUDA)可用于确定您的系统上是否安装了 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()
Run Code Online (Sandbox Code Playgroud)

使用静态 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} )
Run Code Online (Sandbox Code Playgroud)

没有静态 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} )
Run Code Online (Sandbox Code Playgroud)