Cuda с повышением - PullRequest
       28

Cuda с повышением

12 голосов
/ 13 сентября 2011

В настоящее время я пишу приложение CUDA и хочу использовать библиотеку boost :: program_options для получения необходимых параметров и ввода данных пользователем.

Проблема, с которой я столкнулся, заключается в том, что NVCC не может справиться с компиляцией файла наддува any.hpp, выдавая такие ошибки, как

1>C:\boost_1_47_0\boost/any.hpp(68): error C3857: 'boost::any': multiple template parameter lists are not allowed

Я искал в Интернете и обнаружил, что это связано с тем, что NVCC не может обрабатывать определенные конструкции, используемые в буст-коде , но NVCC должен делегировать компиляцию кода хоста компилятору C ++. В моем случае я использую Visual Studio 2010, поэтому код хоста должен быть передан cl.

Так как NVCC, похоже, запутался, я даже написал простую оболочку для надстройки и вставил ее в отдельный файл .cpp (вместо .cu), но я все еще получаю ошибки сборки. Странно, но при компиляции моего main.cu вместо wrapper.cpp возникает ошибка, но она все равно вызвана бустом, даже если main.cu не включает буст код .

Кто-нибудь знает решение или даже обходной путь для этой проблемы?

Ответы [ 4 ]

8 голосов
/ 23 сентября 2011

Дэн, я написал код CUDA с использованием boost :: program_options в прошлом и оглянулся на него, чтобы увидеть, как я справился с вашей проблемой. Конечно, в цепочке компиляции nvcc есть некоторые причуды. Я полагаю, что вы, как правило, можете справиться с этим, если правильно разложите свои классы и поймете, что часто NVCC не может обрабатывать код / ​​заголовки C ++, но ваш компилятор C ++ может нормально обрабатывать заголовки, связанные с CUDA.

По сути, у меня есть main.cpp, который включает в себя мой заголовок program_options и материал для разбора, определяющий, что делать с опциями. Заголовок program_options затем включает в себя связанные с CUDA прототипы заголовков / классов. Важной частью (как я думаю, вы видели) является отсутствие кода CUDA, а сопровождающие заголовки включают этот заголовок параметров. Передайте ваши объекты в функцию параметров и заполните ее соответствующей информацией. Что-то вроде уродливой версии паттерна стратегии. Сцепленных:

main.cpp:
#include "myprogramoptionsparser.hpp"
(...)
CudaObject* MyCudaObj = new CudaObject;
GetCommandLineOptions(argc,argv,MyCudaObj);

myprogramoptionsparser.hpp:
#include <boost/program_options.hpp>
#include "CudaObject.hpp"

void GetCommandLineOptions(int argc,char **argv,CudaObject* obj){
(do stuff to cuda object) }

CudaObject.hpp:
(do not include myprogramoptionsparser.hpp)

CudaObject.cu:
#include "CudaObject.hpp"

Это может быть немного раздражающим, но компилятор nvcc, кажется, становится лучше в обработке большего количества кода C ++. Это отлично сработало для меня в VC2008 / 2010 и linux / g ++.

5 голосов
/ 13 сентября 2011

Вы должны разделить код на две части:

  1. ядро ​​должно быть скомпилировано nvcc
  2. программа, которая вызывает ядро, должна быть скомпилирована g ++.

Затем свяжите два объекта вместе, и все должно работать. nvcc требуется только для компиляции кода ядра CUDA.

0 голосов
/ 24 февраля 2017

Другой вариант заключается в переносе только кода cpp в

#ifndef __CUDACC__
0 голосов
/ 13 сентября 2011

Благодаря комментарию @ ronag я понял, что я все еще (косвенно) включаю boost/program_options.hpp косвенно в мой заголовок, так как у меня были некоторые переменные-члены в моем определении класса-оболочки, которые нуждались в этом.

Чтобы обойти это, япереместили эти переменные за пределы класса и, таким образом, могли переместить их за пределы определения класса в файл .cpp.Они больше не являются переменными-членами и теперь глобальны внутри wrapper.cpp

Кажется, это работает, но это ужасно, и я чувствую, что nvcc должен справиться с этим изящно;если у кого-то еще есть правильное решение, пожалуйста, оставьте его:)

...