混合編譯.c/.cpp與.cu文件

混合編譯.c/.cpp與.cu文件

項目中用到cuda編程,寫了kernel函數,須要nvcc編譯器來編譯。.c/.cpp的文件,假定用gcc編譯。ios

如何混合編譯它們,總體思路是:.cu文件編譯出的東西,做爲最終編譯出的可執行程序的連接依賴。編程

具體提及來又能夠有這幾種狀況:bash

  • 分別編譯各個文件,最後連接
  • 將CUDA程序編譯爲靜態庫
  • 將CUDA程序弄成動態庫

其中後兩種方式更工程化,基於makefile或CMake會更加方便。app

假設手頭上的文件爲:函數

test1.cu
test2.c

則具體編譯指令、編譯腳本以下:優化

方法1:分別編譯各個文件

nvcc -c test1.cu
gcc -c test2.c
gcc -o testc test1.o test2.o -lcudart -L/usr/local/cuda/lib64

方法2: 將cuda程序編譯爲靜態庫

nvcc -lib test1.cu -o libtestcu.a
gcc test2.c -ltestcu -L. -lcudart -L/usr/local/cuda/lib64

方法3:將CUDA程序弄成動態庫

以makefile爲例spa

all: c

c: libtestcu.so
    gcc test2.c -ltestcu -L. -lcudart -L/usr/local/cuda/lib64 -o testc

libtestcu.so: test.cu
    nvcc -o libtestcu.so -shared -Xcompiler -fPIC test1.cu

方法4:基於CMake的一個例子

foo.cuh寫kernel函數聲明 foo.cu 實現kernel函數 foo.cuhfoo.cu一塊兒,編譯成一個庫.net

main.c調用kernel函數debug

foo.cuhcode

參見https://blog.csdn.net/fb_help/article/details/79330815

須要注意的是,VS在debug模式下,應該把nvcc的flags中優化選項關閉掉。

技巧: 能夠把kernel函數作一層封裝,這樣一來在其餘.c/.cpp文件中,調用這個wrapper函數便可

e.g.

#include <stdio.h>
#include <iostream>

#include "foo.cuh" //注意包含頭文件

int main()
{
    std::cout<<"Hello C++"<<std::endl;
    useCUDA(); // 這個函數是kernel函數的wrapper函數
    return 0;
}
相關文章
相關標籤/搜索