Создание программы GPL C с модулем CUDA

Я пытаюсь изменить программу GPL, написанную на C. Моя цель — заменить один метод реализацией CUDA, что означает, что мне нужно компилировать с помощью nvcc вместо gcc. Мне нужна помощь в создании проекта, а не в его реализации (я не думаю, что вам нужно что-то знать о CUDA C, чтобы помочь).

Я впервые пытаюсь изменить проект C средней сложности, который включает в себя .configure и Makefile. Честно говоря, я впервые за долгое время делаю что-либо на C, включая все, что связано с gcc или g++, так что я немного растерялся.

Я не очень заинтересован в изучении configure и Makefiles - это скорее эксперимент. Прежде чем тратить время на создание надлежащего сценария сборки, я хотел бы убедиться, что реализация проекта идет хорошо. (Не отказываясь учиться по мере необходимости, просто пытаясь дать представление о масштабах).

С учетом сказанного, каковы мои варианты создания этого проекта? У меня куча вопросов...

  • Я попытался добавить «CC=nvcc» в файл configure.in после AC_PROG_CC. Это, похоже, сработало - выходные данные при запуске configure и make показали nvcc в качестве компилятора. Однако make не смог скомпилировать исходный файл с ядром CUDA, не распознав синтаксис, специфичный для CUDA. Не знаю почему, надеялся, что это сработает.

  • Можно ли скомпилировать исходный файл с помощью nvcc, а затем включить его на этапе компоновки в процессе создания основной программы? Если да, то как? (Этот вопрос может не иметь смысла - я действительно ржавый в этом)

  • Как правильно это сделать?

  • Есть ли быстрый и грязный способ, который я мог бы использовать для целей тестирования?

  • Есть ли какой-то секретный инструмент, который все используют для настройки и понимания этих файлов конфигурации и Makefile? Это даже хуже, чем скрипты Apache Ant, к которым я привык (да, я не в своей тарелке)


person emulcahy    schedule 20.02.2012    source источник
comment
Возможно, вы пропустили расширения файлов. nvcc использует расширения файлов для определения того, что содержит код устройства, а что нет — любой код устройства, содержащий файлы, должен иметь расширение .cu для правильной компиляции.   -  person talonmies    schedule 20.02.2012
comment
Просто любопытно, что вы делаете в функции CUDA?   -  person arrayfire    schedule 20.02.2012
comment
Хорошая мысль о файлах .cu. Я попробую переименовать некоторые исходные файлы.   -  person emulcahy    schedule 21.02.2012
comment
Я пытаюсь адаптировать fcrackzip для выполнения в ядре CUDA. Это для школьного проекта по моему выбору, надеюсь, это все еще в рамках, так как это не совсем домашняя работа.   -  person emulcahy    schedule 21.02.2012


Ответы (1)


Вам не нужно компилировать все с помощью nvcc. Ваше предположение, что вы можете просто скомпилировать код CUDA с помощью NVCC и оставить все остальное (кроме компоновки), верно. Вот подход, который я бы использовал для начала.

  1. Добавьте 1 новый заголовок (например, myCudaImplementation.h) и 1 новый исходный файл (с расширением .cu, например, myCudaImplementation.cu). Исходный файл содержит реализацию вашего ядра, а также функцию-оболочку C (хост), которая вызывает ядро ​​с соответствующей конфигурацией выполнения (она же <<<>>>) и аргументами. Заголовочный файл содержит прототип функции-оболочки C. Назовем эту функцию-оболочку runCudaImplementation()

  2. Я бы также предоставил еще одну функцию хоста C в исходном файле (с прототипом в заголовке), которая запрашивает и настраивает присутствующие устройства GPU и возвращает true, если это успешно, и false, если нет. Назовем эту функцию configureCudaDevice().

  3. Теперь в вашем исходном коде C, где вы обычно вызываете реализацию вашего процессора, вы можете сделать это.

    // must include your new header
    #include "myCudaImplementation.h"
    
    // at app initialization
    // store this variable somewhere you can access it later
    bool deviceConfigured = configureCudaDevice;          
    ...                             
    // then later, at run time
    if (deviceConfigured) 
        runCudaImplementation();
    else
        runCpuImplementation(); // run the original code
    
  4. Теперь, поскольку вы поместили весь свой код CUDA в новый файл .cu, вам нужно только скомпилировать этот файл с помощью nvcc. Все остальное остается прежним, за исключением того, что вы должны связать объектный файл, который выводит nvcc. например

    nvcc -c -o myCudaImplementation.o myCudaImplementation.cu <other necessary arguments>
    

Затем добавьте myCudaImplementation.o в строку ссылки (что-то вроде :) g++ -o myApp myCudaImplementation.o

Теперь, если у вас есть сложное приложение для работы, которое использует configure и уже имеет сложный make-файл, это может быть более сложным, чем описанное выше, но это общий подход. Суть в том, что вы не хотите компилировать все свои исходные файлы с помощью nvcc, только файлы .cu. Используйте свой хост-компилятор для всего остального.

Я не эксперт в настройке, поэтому не могу помочь. Вы можете запустить configure для создания make-файла, а затем отредактировать этот make-файл — это не будет общим решением, но поможет вам начать работу.

Обратите внимание, что в некоторых случаях вам также может понадобиться отделить компиляцию ваших файлов .cu от их связывания. В этом случае вам необходимо использовать отдельные функции компиляции и компоновки NVCC, для которых эта запись в блоге может оказаться полезной.

person harrism    schedule 20.02.2012
comment
Отлично, спасибо, что нашли время, чтобы объяснить это. Я могу справиться с таким подходом. - person emulcahy; 21.02.2012
comment
Получил это работает. Еще один дополнительный шаг, который может потребоваться сделать другим, — это добавить extern C { } вокруг метода-оболочки. Это, вероятно, очевидно для связывания ветеранов. - person emulcahy; 25.02.2012
comment
Вам не нужно использовать extern C, если у вас нет только связи с C (например, вызов его из файла .c). - person harrism; 25.02.2012
comment
@harrism Правильно ли говорить, что исходный код, скомпилированный с помощью g++, может иметь API среды выполнения cuda, такой как cudaMalloc (& p) и cudaMemcpy (p), но не может запускать ядро, такое как foo‹‹‹›››(p)? - person user1823664; 23.04.2017
comment
Для cuda 5.0 и более поздних версий: devblogs.nvidia.com/parallelforall / - person user1823664; 23.04.2017
comment
@ user1823664 да, правильно сказано. Однако существует API cudaLaunch() для запуска без <<<>>>. - person harrism; 01.05.2017