…Обыденный при-дедлайновый раш. Лица с ярко выраженными следами напряженных раздумий. Все вокруг словно наэлектрилизовано, но при этом чувствуется легкий привкус надежды на светлое будущее. Тем более вроде бы удалось распараллелить алгоритм на CUDA, осталось все это собрать да слинковать…
Итак, вводные: некоторый модуль надо быстро-быстро собрать на студии (Visual Studio 10 Prof если быть точным). Этот модуль страстно хочет вызвать CUDA ядро. NVidea в тот момент, как раз приходила в себя, опосля пропажи паролей из developer’s zone. По этому поводу, на всякий случай, все ссылки на загрузки вели на страничку, живоописующую меры, принятые корпорацией в ответ на произвол хакеров. В связи с чем доставить на студию готовую примочку для компиляции *.cu файлов – NVidea Nsight было невозможно.
Что-ж, переходим к плану Бе – краткая памятка как компилировать CUDA ядро (*.cu) на Visual Studio:
- добавляем *.cu файл к проекту (Add->Add Existing Item) и выбираем наш файл My_Cuda_Kernel.cu
- щелкаем его правой кнопкой мыша и выбираем Свойства (Properties)
- находим пункт Item Type и вместо (Does not participate in build) Не учавствует в сборке выбираем – Custom Build Tool, ака ща я все сам соберу
- жмем Apply
- в свойствах появляется новый элемент – Custom Build Tool – в данном разделе нас интересуют Outputs and Command Line
- в вывод (Outputs) заносим что-нибудь вроде $(Platform)/$(Configuration)/My_Cuda_Kernel.cu.obj
- а в командную строку – непосредственно вызов компилятора:
cd c:\My_Project_Dir\src\cuda nvcc -c -D__CUDACC__ My_Cuda_Kernel.cu -o ../../$(Platform)/$(Configuration)/My_Cuda_Kernel.cu.obj -gencode arch=compute_30,code=sm_30 -gencode arch=compute_30,code=compute_30 --ftz=true --prec-div=false --prec-sqrt=false -DNVCC --include-path .,..,d:\Additional_Include_Dirs\include
При этом:
путь к nvcc(.exe) – должен быть в переменной системного окружения PATH
предполагается что объектники для *.cu и *.cpp файлов валятся в c:\My_Cuda_Project_Dir\$(Platform)\$(Configuration), а сами исходники лежат соответственно в c:\My_Cuda_Project_Dir\src и c:\My_Cuda_Project_Dir\src\cuda.
флаг -c – подсказывает компилятору что мы желаем видеть в результате сборки объектный файл
флаг -o – подсказывает как его назвать и куда положить
__CUDACC__,NVCC – данные флаги показывает что компиляция производится с помощью nvcс – и могут быть использованы в самом коде для разделения исходного кода на то, что должно компиляться хост компилятором, а что с помощью nvcc.
–ftz=true –prec-div=false –prec-sqrt=false – влияют на точность вычислений – чем меньше точность – тем быстрее, чтобы использовать упрощенные вычисления надо указать флаг –use_fast_math.
-gencode arch=compute_30,code=sm_30 – используя такой флаг мы указываем, под какие архитектуры мы будем собирать (их можно указывать несколько) наш модуль.
compute_30 – compute_* – мы указываем виртуальную архитектуру – это некоторый обобщенный набор методов которые будут поддерживаться
sm_30 – sm_* – указание конкретного устройства, набор инструкций которого мы хотим использовать и на котором предполагается наш код запускать. Кроме этого, мы указываем что мы хотим сгенерировать код для Just In Time Compilation – т.е. в нашем модуле будут не только конкретные инструкции для той или иной архитектуры, но и их промежуточное представление – PTX – оно может быть использовано драйвером видео-карты для компиляции наиболее оптимального набора инструкций, в случае если мы будем запускать наш код на более новых архитектурах.
Указанный отдельно, флаг arch – указывает, возможности какой архитектуры будут использоваться (при этом обратной совместимости нет и если вы собрали что-то под sm_30 – никто не гарантирует что это будет работоспособно на sm_20). Также надо принимать во внимание различие между минорными версиями архитектур одного поколения – код использующий возможности sm_13 (в которой была добавлена поддержка операций двойной точности) не будет работать на sm_12 (хотя возможно эмуляция данной функциональности).
Указанный отдельно флаг code – показывает под какую конкретную архитектуру видеокарты мы хотим собрать наш модуль
Литература по теме:
The CUDA Compiler Driver NVCC из NVidea SDK – подробная и актуальная информация по флагам компиляции nvcc и разъяснение основных этапов компиляции, а также как происходит вызов CUDA кода из обычных приложений
http://stackoverflow.com/questions/9363827/building-gpl-c-program-with-cuda-module – пример компиляции и линковки CUDA кода к c++ коду
http://llpanorama.wordpress.com/2008/05/21/my-first-cuda-program/ – простой и подробный пример для CUDA hello word