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)文件中,但我仍然遇到构建错误。奇怪的是,错误是在编译 mymain.cu而不是时引发的,wrapper.cpp但仍然是由 boost 引起的,即使main.cu不包含任何 boost code

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

4

4 回答 4

8

丹,我过去使用 boost::program_options 编写了一个 CUDA 代码,然后回头看看我是如何处理你的问题的。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++ 中对我来说效果很好。

于 2011-09-23T14:53:07.477 回答
5

您必须将代码分成两部分:

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

然后将两个对象链接在一起,一切都应该正常工作。nvcc 仅用于编译 CUDA 内核代码。

于 2011-09-13T17:40:13.763 回答
0

感谢@ronag 的评论,我意识到我仍然(间接地)boost/program_options.hpp在我的标题中间接包含,因为我的包装类定义中有一些需要它的成员变量。

为了解决这个问题,我将这些变量移到了类之外,因此可以将它们移到类定义之外并进入 .cpp 文件。它们不再是成员变量,现在是全局变量wrapper.cpp

这似乎可行,但很难看,我觉得 nvcc 应该优雅地处理它;如果其他人有适当的解决方案,请仍然发布:)

于 2011-09-13T10:00:44.423 回答
0

另一种选择是将仅 cpp 代码包装在

#ifndef __CUDACC__
于 2017-02-24T01:36:38.440 回答