2012-02-23 25 views
36

我正在尋找有關CUDA項目的入門幫助。我的目標是建立一個可以在本地g ++編譯器中編譯的項目,但使用CUDA代碼。我知道我必須在nvcc編譯器中編譯我的CUDA代碼,但從我的理解中,我可以以某種方式將CUDA代碼編譯爲cubin文件或ptx文件。如何編譯CUDA代碼然後將其鏈接到C++項目?

這裏是我的問題:

  1. 如何使用NVCC編譯成的cubin文件或文件PTX?我不需要一個-c或什麼?
  2. 我想使用哪種文件類型?
  3. 正確編譯和鏈接項目的g ++命令是什麼?

假設如下:

  1. 我有一個名爲「main.cpp的」,在它有一個主要功能,包括cuda.h.文件
  2. 我有另一個名爲「cudaFunc.cu」的文件,其中包含CUDA代碼。比方說,我想添加兩個存在於main.cpp中的整型數組。

回答

39

我能解決我的問題,包括這些幾個不同的職位。不要忘記,如果您使用64位機器來鏈接到64位庫!它接縫很明顯,但對於像我這樣的小丑來說,那是我忘記的東西。這裏是我現在使用的make文件...如果你可以消化這個make文件,你應該可以做我想做的事情,它是獨立編譯的cuda代碼和其他G ++代碼。也請記住,你必須有gcc的,在某些版本的g ++編譯器(我用G ++ - 4.4,它是爲我工作)無論如何,這裏是make文件...

all: program 

program: cudacode.o 
    g++ -o program -L/usr/local/cuda/lib64 -lcuda -lcudart main.cpp cudacode.o 

cudacode.o: 
    nvcc -c -arch=sm_20 cudacode.cu 

clean: rm -rf *o program 

希望你可以看到,我所做的第一件事是使用nvcc編譯器和-c選項編譯cudacode(已保存爲.cu)(另請注意,您可能需要刪除-arch = sm_20)。這創建了一個cudacode.o。然後,我使用帶有-o選項的g ++編譯器並鏈接到lib64庫,並鏈接lcuda和lcudart文件以及編譯我的main.cpp,然後鏈接cudacode.o。希望這可以幫助別人!

+0

你還可以提供你測試過的最小'.cu'和'.cpp'文件嗎?對使用的包括cpp感到好奇,特別是如何從'.cu'中看到內核'__global__'函數。 – 2017-04-09 09:36:16

+1

小心點,您的乾淨目標將刪除所有以'o'結尾的文件。你可能想要'clean:rm -rf * .o程序' – gerowam 2017-07-21 12:25:47

+1

謝謝[Matthew](https://stackoverflow.com/users/1226843/matthew),這非常有幫助。 – SRG 2017-10-19 11:33:18

8

我的回答to this recent question可能會描述你需要什麼。

一對夫婦的其他注意事項:

  1. 你不需要編譯.CU到.cubin或.ptx文件。您需要將它編譯爲.o目標文件,然後將其與.gpp文件中用g ++編譯的.o目標文件相鏈接。
  2. 除了將cuda內核代碼放在cudaFunc.cu中之外,還需要在啓動內核的文件中放置一個C或C++包裝器函數(除非您使用CUDA驅動程序API,這不太可能且不推薦使用)。還要添加一個包含此包裝函數原型的頭文件,以便您可以將其包含在需要調用CUDA代碼的C++代碼中。然後,使用標準的g ++鏈接線將這些文件鏈接在一起。

我開始重複我的other answer,所以我建議您只是閱讀它。 :)

+0

Harrism,謝謝你的回答。現在我更接近了。我可以使用nvcc編譯器和.cu文件(我將其重命名爲cudacode.cu)編譯得很好,並且我有一個cudacode.o對象,但現在當我嘗試在g ++上編譯時,我得到了cudacode.o:In function 'wrapper(int *,int *,int *,int)': tmpxft_00000d3a_00000000-1_cudacode.cudafe1.cpp :(.text + 0x30):未定義引用'cudaMalloc' – Matthew 2012-02-24 14:36:44

+0

您需要鏈接libcudart。首先找出libcudart.so的位置 - 默認情況下,我認爲它進入了/ usr/local/bin/cuda,但是由於安裝而有所不同。找到路徑後,將其添加到鏈接行中:'-L -lcudart'。 – harrism 2012-02-25 00:36:05

+0

你是我的英雄!謝謝。我遇到的另一個問題是我在64位機器上,所以我不得不鏈接到lib64文件。就在三個小時前,我不知道如何使用g ++,我不知道make文件是什麼,我也不知道如何鏈接。我想這就是我在窗口上長大的原因。 – Matthew 2012-02-25 02:55:30

7

我發現將編譯後的cuda目標代碼與g ++鏈接起來可能會很麻煩。 嘗試像這樣編譯它:

all: 
nvcc cudafile.cu mainfile.cpp -o executable 

clean: rm -rf *.o 
+0

我會使用rm -f而不是rm -rf,因爲* .o文件應該是普通文件,我害怕發生致命錯誤:https://www.theregister.co.uk/2015/01/17/scary_code_of_the_week_steam_cleans_linux_pcs / – 2017-07-21 00:59:59