Cuda与Boost结合使用

13
我正在编写一个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 无法处理boost代码中使用的某些结构,但NVCC应该将主机代码的编译委托给C++编译器。在我的情况下,我正在使用Visual Studio 2010,因此主机代码应该传递给cl

由于NVCC似乎变得混乱,我甚至编写了一个简单的包装器来包装boost内容,并将其放在单独的.cpp(而不是.cu)文件中,但我仍然遇到了构建错误。奇怪的是,错误是在编译我的main.cu时抛出的,而不是wrapper.cpp,但仍由boost引起,尽管main.cu不包括任何boost 代码

有人知道这个问题的解决方案或解决方法吗?


main.cu文件中是否包含其他包含boost代码的文件? - ronag
是的,实际上考虑到它包括“wrapper.h”,而“wrapper.h”又包括“boost\program_options.hpp”。有没有好的方法将它们分开? - Dan
4个回答

8
Dan,我过去使用boost::program_options编写了一个CUDA代码,并回头看看它,看看我是如何处理你的问题的。nvcc编译链中确实存在一些怪癖。如果你已经适当地分解了你的类,并意识到通常NVCC无法处理C++代码/头文件,但你的C++编译器可以很好地处理与CUDA相关的头文件,那么你通常可以处理这个问题。
我基本上有一个包含我的program_options头文件和解析指令的main.cpp文件。然后程序选项头文件包括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

您需要将代码分为两部分:

  1. 内核必须由nvcc进行编译
  2. 调用内核的程序必须由g++进行编译。

然后将两个对象链接在一起,一切都应该正常工作。 只有编译CUDA内核代码时才需要nvcc。


确实,我的问题中已经说了这么多。解决方案真正的问题是如何实现它或让nvcc正确处理它。 - Dan
我正在使用VS2010编译,不知道是否会引起问题? - Dan

0
由于@ronag的评论,我意识到我的头文件仍然(间接地)包含了boost/program_options.hpp,因为我的包装器类定义中有一些需要它的成员变量。
为了解决这个问题,我将这些变量移到了类外面,这样就可以将它们移到类定义之外并放入.cpp文件中。它们不再是成员变量,现在在内变成全局变量。
这种方法似乎可以解决问题,但很丑陋,我感觉nvcc应该优雅地处理这个问题。如果其他人有正确的解决方案,请分享 :)

0

另一个选项是将仅限于cpp的代码包装在内

#ifndef __CUDACC__

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接