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


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

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

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

具體說起來又可以有這幾種情況:

  • 分別編譯各個文件,最后鏈接
  • 將CUDA程序編譯為靜態庫
  • 將CUDA程序弄成動態庫

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

假設手頭上的文件為:

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為例

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一起,編譯成一個庫

main.c調用kernel函數

foo.cuh

參見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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM