Подтвердить что ты не робот

Cuda с Boost

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

Проблема, с которой я столкнулась, заключается в том, что NVCC не может обрабатывать компиляцию файла boost 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 должен делегировать компиляцию хост-кода для компилятора С++. В моем случае я использую Visual Studio 2010, поэтому код хоста должен быть передан в cl.

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

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

4b9b3361

Ответ 1

Дэн, я написал код CUDA с использованием boost:: program_options в прошлом и снова посмотрел на него, чтобы посмотреть, как я справился с вашей проблемой. В цепочке компиляции nvcc есть определенные причуды. Я считаю, что вы можете вообще справиться с этим, если вы соответствующим образом разложили свои классы и понимаете, что часто NVCC не может обрабатывать код/​​заголовки С++, но ваш компилятор С++ может обрабатывать заголовки, связанные с 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 становится лучше обрабатывать больше кода на С++. Это отлично работает для меня в VC2008/2010, а linux/g++.

Ответ 2

Вам нужно разбить код на две части:

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

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

Ответ 3

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

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

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

Ответ 4

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

#ifndef __CUDACC__