Как я могу скомпилировать код CUDA, а затем связать его с проектом C++?

Я ищу помощи, чтобы начать работу с проектом, включающим CUDA. Моя цель - иметь проект, который я могу скомпилировать в родном компиляторе g++, но с использованием кода CUDA. Я понимаю, что мне нужно скомпилировать свой код CUDA в компиляторе nvcc, но, насколько я понимаю, я могу каким-то образом скомпилировать код CUDA в файл cubin или файл ptx.

Вот мои вопросы:

  1. Как использовать nvcc для компиляции в файл cubin или файл ptx? Разве мне не нужен -c или что-то в этом роде?
  2. Какой тип файла я хочу использовать?
  3. Каковы команды g++ для правильной компиляции и компоновки проекта?

Предположим следующее:

  1. У меня есть файл с именем «main.cpp», в котором есть основная функция и включает cuda.h.
  2. У меня есть еще один файл с именем «cudaFunc.cu», в котором есть код CUDA. Предположим, например, что я хочу добавить два массива целых чисел, которые существуют в main.cpp.

person Matthew    schedule 23.02.2012    source источник


Ответы (3)


Я смог решить свою проблему с помощью нескольких разных сообщений, включая эти. Не забывайте об этом, если вы используете 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 -f *.o program

Надеюсь, вы видите, что первое, что я делаю, это компилирую cudacode (который был сохранен как .cu) с помощью компилятора nvcc и опции -c (также обратите внимание, что вы можете удалить -arch=sm_20). Это создало cudacode.o. Затем я использую компилятор g++ с параметром -o и связываю библиотеку lib64 и связываю библиотеки -lcuda и -lcudart вместе с моей компиляцией main.cpp, а затем связываю cudacode.o. Надеюсь, это поможет кому-то!

person Matthew    schedule 29.02.2012
comment
Можете ли вы также предоставить минимальные файлы .cu и .cpp, которые вы тестировали? Любопытно об используемых включениях, cpp, в частности, как увидеть __global__ функции ядра из .cu. - person Ciro Santilli 新疆再教育营六四事件ۍ 09.04.2017
comment
Осторожно, ваша чистая цель удалит все файлы, оканчивающиеся на «о». Вы, вероятно, хотите clean: rm -rf *.o program - person gerowam; 21.07.2017
comment
Спасибо, Мэттью, это было очень полезно. - person SRG; 19.10.2017
comment
Я получаю искаженные имена в сгенерированных объектных файлах (для функции, которую мне нужно вызвать из моего файла, отличного от .cu). У кого-нибудь есть идея, как это исправить? - person interestedparty333; 25.02.2018

Мой ответ на этот недавний вопрос, вероятно, описывает, что вам нужно.

Пара дополнительных замечаний:

  1. Вам не нужно компилировать .cu в файл .cubin или .ptx. Вам нужно скомпилировать его в объектный файл .o, а затем связать его с объектными файлами .o из ваших файлов .cpp, скомпилированных с помощью g++.
  2. В дополнение к размещению кода ядра cuda в cudaFunc.cu вам также необходимо поместить в этот файл функцию-оболочку C или C++, которая запускает ядро ​​(если только вы не используете API-интерфейс драйвера CUDA, что маловероятно и не рекомендуется). Также добавьте файл заголовка с прототипом этой функции-оболочки, чтобы вы могли включить его в свой код C++, который должен вызывать код CUDA. Затем вы связываете файлы вместе, используя стандартную строку ссылки g++.
person harrism    schedule 24.02.2012
comment
Харрисм, спасибо за ответ. Я теперь гораздо ближе. Я могу отлично скомпилировать с помощью компилятора 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): undefined reference to cudaMalloc' - person Matthew; 24.02.2012
comment
Вам нужно связать libcudart. Сначала выясните, где находится libcudart.so — по умолчанию я думаю, что он находится в /usr/local/bin/cuda, но это зависит от установки. Как только вы найдете путь, добавьте его в строку ссылки: -L<path to CUDA libs> -lcudart. - person harrism; 25.02.2012
comment
ты мой герой! Спасибо. дополнительная проблема, с которой я столкнулся, заключалась в том, что я нахожусь на 64-битной машине, поэтому мне пришлось ссылаться на файл lib64. всего три часа назад я не знал, как использовать g++, я не знал, что такое make-файл, и я не знал, как делать ссылки. Я думаю, это то, что я получаю за то, что вырос на окнах. - person Matthew; 25.02.2012

Я обнаружил, что связывание скомпилированного кода объекта cuda с g++ может быть проблематичным. Попробуйте скомпилировать так:

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

clean: rm -rf *.o
person Jean-Luc Nacif Coelho    schedule 25.01.2013
comment
Я бы использовал rm -f, а не rm -rf, потому что файлы *.o должны быть обычными файлами, и я боюсь сделать фатальную ошибку: theregister.co.uk/2015/01/17/ - person Adam P. Goucher; 21.07.2017
comment
@Adam P. Goucher Если на Ubuntu, вы можете установить safe-rm :) - person juzzlin; 28.12.2018