日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux下c和cuda混合编译,并生成动态链接库.so和使用

發布時間:2025/3/15 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux下c和cuda混合编译,并生成动态链接库.so和使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Linux下c和cuda混合編譯,并生成動態鏈接庫.so和使用

98人閱讀 評論(0) 收藏 舉報 分類: Linux

目錄(?)[+]

梗概

如果要生成動態鏈接庫,就需要把源碼,無論是.c .cpp .cu還是其他的語言寫的程序,都通過編譯器變成.o文件,之后把相應的.o文件進行鏈接成為.so動態鏈接庫。這樣就可以直接調用其中的函數了。
形成過程: .c .cpp .cu -> .o -> .so
使用 : test.c + .so - > test
./test
但是其中還是有許多的小細節需要注意的。


現在就舉個栗子:

把yolo算法,編譯成動態鏈接庫,其中需要用到opencv、cuda、cudnn。之后講介紹怎么把這些庫一起與源碼進行編譯,生成可以用的.so。
源碼文件分為三類:.c文件 .h頭文件和 .cu的cuda文件
【分析編譯.c文件】

<code class="hljs lasso has-numbering">gcc <span class="hljs-attribute">-fPIC</span> <span class="hljs-attribute">-DOPENCV</span> <span class="hljs-string">`pkg-config --cflags opencv`</span> <span class="hljs-attribute">-DGPU</span> <span class="hljs-attribute">-I</span>/usr/<span class="hljs-built_in">local</span>/cuda/include<span class="hljs-subst">/</span> <span class="hljs-attribute">-DCUDNN</span> <span class="hljs-attribute">-Wall</span> <span class="hljs-attribute">-Wfatal</span><span class="hljs-attribute">-errors</span> <span class="hljs-attribute">-Ofast</span> <span class="hljs-attribute">-DOPENCV</span> <span class="hljs-attribute">-DGPU</span> <span class="hljs-attribute">-DCUDNN</span> <span class="hljs-attribute">-c</span> <span class="hljs-built_in">.</span>/src/image<span class="hljs-built_in">.</span>c <span class="hljs-attribute">-o</span> obj/image<span class="hljs-built_in">.</span>o</code><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul>

gcc : 編譯器
-fPIC: 使用 -fPIC 選項,會生成 PIC 代碼。告訴編譯器產生與位置無關代碼(Position-Independent Code), .so 要求為 PIC,以達到動態鏈接的目的,否則,無法實現動態鏈接。
`pkg-config –cflags opencv`: 根據pkg-config信息來找到opencv的include,因為源文件中包含使用了一些opencv的函數,所以需要引入include文件。對應的“ 兩個反引號不要少。
-I/usr/local/cuda/include/ : 首先-I表示根據需要在/usr/local/cuda/include/目錄下找到對應的文件。并包含進去一起編譯。
-Wall: 表示把所有警告都展示出來。
-Wfatal-errors: 表示當發生第一個錯誤的時候停止編譯,這樣的好處就是可以找到錯誤的地方,防止許多無用的信息掩蓋了錯誤信息。
-Ofast:編譯所采用的優化手段。
-c: 進行源文件的編譯成.o文件
-o: 輸出到哪里,并且文件名是什么,只有緊跟其后的一項是輸出
-DOPENCV,-DGPU,-DCUDNN:這些選項就是控制代碼中的宏定義,如果帶有這些選項進行編譯,證明宏定義是選定的。即#ifdef OPENCV 是定義了的,否則沒有定義。這也相當與vs中的預處理選項。通過這項可以根據修改Makefile文件來確定某個庫是否使用,在源碼中再通過宏定義來實現,非常方便。

【分析.cu文件編譯】

<code class="hljs lasso has-numbering">nvcc <span class="hljs-subst">--</span>gpu<span class="hljs-attribute">-architecture</span><span class="hljs-subst">=</span>compute_52 <span class="hljs-subst">--</span>gpu<span class="hljs-attribute">-code</span><span class="hljs-subst">=</span>compute_52 <span class="hljs-attribute">-DOPENCV</span> <span class="hljs-string">`pkg-config --cflags opencv2`</span> <span class="hljs-attribute">-DGPU</span> <span class="hljs-attribute">-I</span>/usr/<span class="hljs-built_in">local</span>/cuda/include<span class="hljs-subst">/</span> <span class="hljs-attribute">-DCUDNN</span> <span class="hljs-subst">--</span>compiler<span class="hljs-attribute">-options</span> <span class="hljs-string">"-Wall -Wfatal-errors -Ofast -DOPENCV -DGPU -DCUDNN -fPIC"</span> <span class="hljs-attribute">-c</span> <span class="hljs-built_in">.</span>/src/convolutional_kernels<span class="hljs-built_in">.</span>cu <span class="hljs-attribute">-o</span> obj/convolutional_kernels<span class="hljs-built_in">.</span>o</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul>

很多與c的編譯差不多。
nvcc : cuda的編譯器
–gpu-architecture=compute_52 –gpu-code=compute_52 : 這個是根據顯卡計算能力來確定的,來表示gpu的架構是說明,我的顯卡是GT960,所以是compute_52
–compiler-options : 在雙引號中填寫一些編譯選項。 尤其是-fPIC選項,因為在外面寫是編譯不通過的,只能在雙引號里面寫。

把所有的.c文件和.cu文件都編譯成.o文件,當然都是-fPIC編譯的,即是位置無關的。
現在就開始通過這些目標文件來進行.so的生成。

<code class="hljs avrasm has-numbering">gcc -shared -o libtest<span class="hljs-preprocessor">.so</span> *<span class="hljs-preprocessor">.o</span></code><ul style="" class="pre-numbering"><li>1</li></ul>

-shared : 因為要做成動態鏈接庫,所以需要把該庫做成可以共享的。
*.o : 即剛才生成的所有.o文件,依次添加進去。
但是只把這些.o文件進行鏈接,鏈接到libtest.so文件中,雖然也可以生成.so文件,但是在使用時會出現一些錯誤,如:undefined reference to `cudnnGetConvolutionBackwardDataWorkspaceSize’ 等關于cudnn的錯誤。 所以需要在鏈接的時候把cudnn的相關鏈接也鏈接進去。

<code class="hljs lasso has-numbering">gcc <span class="hljs-attribute">-shared</span> <span class="hljs-attribute">-o</span> libtest<span class="hljs-built_in">.</span>so <span class="hljs-subst">*</span><span class="hljs-built_in">.</span>o <span class="hljs-attribute">-L</span>/usr/<span class="hljs-built_in">local</span>/cuda/lib64 <span class="hljs-attribute">-lcuda</span> <span class="hljs-attribute">-lcudart</span> <span class="hljs-attribute">-lcublas</span> <span class="hljs-attribute">-lcurand</span> <span class="hljs-attribute">-lcudnn</span></code><ul style="" class="pre-numbering"><li>1</li></ul>

-L/usr/local/cuda/lib64 : 確定lib的路徑,-L后面跟的就是lib所在的路徑,如果要引入其中的.so文件,只需要-l開頭即可,后面跟文件名去掉lib的名字即可。
這樣就生成了.so文件。

使用.so文件:

Step 1:

<code class="hljs brainfuck has-numbering"><span class="hljs-comment">gcc</span> <span class="hljs-literal">-</span><span class="hljs-comment">c</span> <span class="hljs-comment">test</span><span class="hljs-string">.</span><span class="hljs-comment">c</span> <span class="hljs-comment">$(pkg</span><span class="hljs-literal">-</span><span class="hljs-comment">config</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">cflags</span> <span class="hljs-literal">-</span><span class="hljs-literal">-</span><span class="hljs-comment">libs</span> <span class="hljs-comment">opencv)</span></code><ul style="" class="pre-numbering"><li>1</li></ul>

因為test.c中有opencv的函數,所以編譯的時候需要引入opencv,生成test.o文件
Step 2:

<code class="hljs lasso has-numbering">gcc <span class="hljs-attribute">-o</span> test test<span class="hljs-built_in">.</span>o libtest<span class="hljs-built_in">.</span>so <span class="hljs-attribute">-L</span>/usr/<span class="hljs-built_in">local</span>/cuda/lib64 <span class="hljs-attribute">-lcuda</span> <span class="hljs-attribute">-lcudart</span> <span class="hljs-attribute">-lcublas</span> <span class="hljs-attribute">-lcurand</span> <span class="hljs-attribute">-lcudnn</span></code><ul style="" class="pre-numbering"><li>1</li></ul>

把程序與cuda的庫進行動態鏈接,生成可執行文件test。


總結

以上是生活随笔為你收集整理的Linux下c和cuda混合编译,并生成动态链接库.so和使用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。