Cuda с Boost

В настоящее время я пишу приложение 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 не включает никакого кода повышения.

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


person Dan    schedule 13.09.2011    source источник
comment
включает ли main.cu какие-либо другие файлы, которые включают код повышения?   -  person ronag    schedule 13.09.2011
comment
Да, на самом деле, если подумать, он включает wrapper.h, который включает boost\program_options.hpp. Есть ли хороший способ разделить их?   -  person Dan    schedule 13.09.2011


Ответы (4)


Дэн, я написал код 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++.

person Aurelius    schedule 23.09.2011

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

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

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

person fabrizioM    schedule 13.09.2011
comment
Собственно, это уже было сказано в моем вопросе. Решение действительно будет заключаться в том, как добиться этого или заставить nvcc справиться с этим должным образом. - person Dan; 13.09.2011
comment
Я использую VS2010 для компиляции, не знаю, может ли это вызывать проблемы? - person Dan; 16.09.2011

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

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

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

person Dan    schedule 13.09.2011

Другой вариант - обернуть код только cpp в

#ifndef __CUDACC__
person randyrand    schedule 24.02.2017