2012-02-23 44 views
36

Tôi đang tìm kiếm trợ giúp để bắt đầu với một dự án liên quan đến CUDA. Mục tiêu của tôi là có một dự án mà tôi có thể biên dịch trong trình biên dịch g ++ bản địa nhưng sử dụng mã CUDA. Tôi hiểu rằng tôi có để biên dịch mã CUDA của tôi trong trình biên dịch nvcc, nhưng từ sự hiểu biết của tôi bằng cách nào đó tôi có thể biên dịch mã CUDA thành một tập tin cubin hoặc một tập tin ptx.Làm thế nào tôi có thể biên dịch mã CUDA sau đó liên kết nó với một dự án C++?

Dưới đây là những câu hỏi của tôi:

  1. Làm thế nào để sử dụng nvcc để biên dịch thành một file cubin hoặc một tập tin PTX? Tôi không cần một cái gì đó?
  2. Tôi muốn sử dụng loại tệp nào?
  3. Các lệnh g ++ để biên dịch chính xác và liên kết dự án với nhau là gì?

Giả như sau:

  1. Tôi có một tập tin gọi là "main.cpp" mà có một chức năng chính trong đó và bao gồm cuda.h.
  2. Tôi có một tệp khác có tên "cudaFunc.cu" có mã CUDA trong đó. Ví dụ, giả sử rằng tôi muốn thêm hai mảng số nguyên tồn tại trong main.cpp.

Trả lời

39

Tôi đã có thể giải quyết vấn đề của mình bằng một vài bài đăng khác nhau bao gồm cả những bài đăng này. Đừng quên rằng nếu bạn đang sử dụng một máy 64 bit để liên kết đến thư viện 64 bit! Nó seams loại rõ ràng, nhưng đối với chú hề như tôi, đó là một cái gì đó tôi quên. Đây là tập tin mà bây giờ tôi đang sử dụng ... nếu bạn có thể tiêu hóa tập tin này, bạn sẽ có thể làm những gì tôi đang cố gắng làm là biên dịch riêng biệt mã cuda và mã G ++ khác. Cũng nên nhớ rằng bạn phải có gcc, g ++ biên dịch tại một số phiên bản (Tôi đang sử dụng g ++ - 4.4 và nó đang làm việc cho tôi) Dù sao, đây là làm cho tập tin ...

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 

Hy vọng rằng bạn có thể thấy rằng điều đầu tiên tôi làm là biên dịch cudacode (đã được lưu dưới dạng .cu) bằng cách sử dụng trình biên dịch nvcc và tùy chọn -c (cũng lưu ý rằng bạn có thể muốn xóa bỏ -arch = sm_20). Điều này tạo ra một cudacode.o. Sau đó tôi sử dụng trình biên dịch g ++ với tùy chọn -o và liên kết đến thư viện lib64 và liên kết các tệp lcuda và lcudart cùng với biên dịch main.cpp của tôi và sau đó liên kết cudacode.o. Hy vọng điều này sẽ giúp một ai đó!

+0

Bạn cũng có thể cung cấp tệp '.cu' và' .cpp' tối thiểu mà bạn đã thử nghiệm không? Tò mò về việc sử dụng, cpp, đặc biệt là làm thế nào để xem các hàm '__global__' của nhân từ' .cu'. –

+1

Cẩn thận ở đó, mục tiêu sạch sẽ của bạn sẽ xóa tất cả các tệp kết thúc bằng 'o'. Bạn có thể muốn 'clean: rm -rf * .o program' – gerowam

+1

Cảm ơn bạn [Matthew] (https://stackoverflow.com/users/1226843/matthew), điều này rất hữu ích. – SRG

8

Câu trả lời của tôi to this recent question có thể mô tả những gì bạn cần.

Một vài ghi chú thêm:

  1. Bạn không cần phải biên dịch .cu của bạn đến một .cubin hoặc tập tin .ptx. Bạn cần biên dịch nó thành một tệp đối tượng .o và sau đó liên kết nó với các tệp đối tượng .o từ tệp .cpp của bạn được biên dịch với giht g ++.
  2. Ngoài việc đặt mã hạt nhân cuda vào cudaFunc.cu, bạn cũng cần phải đặt hàm bao bọc C hoặc C++ trong tệp đó khởi chạy hạt nhân (trừ khi bạn đang sử dụng API trình điều khiển CUDA, điều này khó xảy ra và không được khuyến nghị). Ngoài ra, hãy thêm một tệp tiêu đề với nguyên mẫu của hàm bao bọc này để bạn có thể bao gồm nó trong mã C++ của bạn cần gọi mã CUDA. Sau đó, bạn liên kết các tệp với nhau bằng cách sử dụng dòng liên kết tiêu chuẩn g ++ của bạn.

Tôi bắt đầu lặp lại số other answer của mình, vì vậy, tôi khuyên bạn chỉ nên đọc nó. :)

+0

Harrism, Cảm ơn câu trả lời của bạn. Giờ tôi đã gần hơn rồi. Tôi có thể biên dịch tốt bằng cách sử dụng trình biên dịch nvcc và tệp .cu (mà tôi đổi tên thành cudacode.cu) và tôi có một đối tượng cudacode.o, nhưng bây giờ khi tôi cố gắng biên dịch trên g ++ tôi nhận cudacode.o: Trong hàm 'wrapper (int *, int *, int *, int) ': tmpxft_00000d3a_00000000-1_cudacode.cudafe1.cpp :(. text + 0x30): tham chiếu không xác định đến' cudaMalloc' – Matthew

+0

Bạn cần liên kết libcudart. Đầu tiên tìm ra nơi libcudart.so là - theo mặc định tôi nghĩ rằng nó đi vào/usr/local/bin/cuda, nhưng điều đó thay đổi theo cài đặt. Khi bạn tìm thấy đường dẫn, hãy thêm đường dẫn này vào dòng liên kết của bạn: '-L -lcudart'. – harrism

+0

bạn là anh hùng của tôi! cảm ơn bạn. một vấn đề khác mà tôi gặp phải là tôi đang sử dụng máy 64 bit, vì vậy tôi phải liên kết đến tệp lib64. chỉ ba giờ trước, tôi không biết làm thế nào để sử dụng g + +, tôi không biết những gì một tập tin được, và tôi didnt biết làm thế nào để liên kết. tôi đoán đó là những gì tôi nhận được để lớn lên trên cửa sổ. – Matthew

7

Tôi thấy rằng việc liên kết mã đối tượng cuda đã biên dịch với g + + có thể gây rắc rối. Hãy thử biên dịch nó như sau:

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

clean: rm -rf *.o 
+0

Tôi muốn sử dụng rm -f thay vì rm -rf, vì tệp * .o phải là tệp thông thường và tôi sợ gây ra lỗi nghiêm trọng: https://www.theregister.co.uk/2015/01/17/scary_code_of_the_week_steam_cleans_linux_pcs / –

Các vấn đề liên quan