2017-08-21 125 views
3

我想通過CUDA代碼將現有項目的某些部分移植到GPU。我知道cmake有選項(find_cuda ...)來單獨處理.cu文件,但我仍在試圖弄清楚這個生態系統如何在現有項目中使用。編譯/添加cuda代碼到現有項目(CMake)

我的問題是以下。假設我有一個帶有cmake配置文件(CMakeLists)的現有C++項目。目前的做法是什麼(如果可能的話)包括CUDA內核? CMakeLists可以以某種方式構建,.cu文件僅在GPU存在時編譯?

我目前的想法是創建一個單獨的文件夾,其中只有與CUDA相關的代碼存在,然後將其編譯爲靜態庫。這是做到這一點的方式嗎?

回答

1

將CUDA文件放在單獨的文件夾中是我推薦的方法,但不是必需的。基本的原則是你將一個CMake變量中的所有.cu文件(我們稱之爲CUDA_SRC)和所有.cpp文件收集到一個不同的變量中(稱之爲SRC)。現在你編譯這兩個文件並把它們放在一起。可以使用find_package(CUDA)提供的變量CUDA_FOUND來確定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 lib

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}) 
+0

太棒了,這正是我想知道的。 –