使用nvcc (CUDA)编译Eigen库

5

我尝试使用nvcc(CUDA 5.0 RC)编译以下程序(main.cu):

#include <Eigen/Core>
#include <iostream>

int main( int argc, char** argv )
{
    std::cout << "Pure CUDA" << std::endl;
}

很不幸,我得到了一堆警告和错误,只能用nvcc而不是Microsoft编译器来解释。

这个假设对吗?是否有办法使用nvcc编译Eigen?(我实际上不想将Eigen矩阵传输到GPU,只是访问它们的成员)

如果不能使用nvcc编译Eigen,是否有一个关于巧妙分离主机和设备代码的不错指南/教程?

我正在使用CUDA 5.0 RC、Visual Studio 2008、Eigen 3.0.5。为了编译.cu文件,我既使用了CUDA中包含的规则文件,也使用了由CMake生成的自定义构建步骤。使用CUDA规则文件时,我将构建目标定向到计算能力3.0。

感谢您的建议。

附注:如果我使用主机编译器编译相同的代码,它可以完美地工作。


2
nvcc并不是一个完整的C++编译器,所以如果它无法编译Eigen,我不会感到惊讶。如果您只在CPU上以正常方式使用Eigen数据类型,则可以使用nvcc将使用CUDA的所有内容单独编译,然后将其链接到实际程序中,该程序是使用您选择的C++编译器编译的。至少在GCC中可以工作,我不知道Visual Studio,但不知道为什么它不应该工作(除了它是微软...)。 - leftaroundabout
2
我想将代码中要移植到CUDA的部分使用Eigen。虽然不是很多,但我希望有一个好的解决方案...特别是我想隐藏浮点指针的复制和相关操作。 - GeorgT
1
如果你想隐藏那种东西,你必须自己包装句柄。我真的看不出你在代码的哪个部分需要Eigen的哪些部分;我会让它变得非常简单,只处理CUDA和适当的CPU C++之间提供接口,然后在安全的高级C++中编写所有有趣的东西。(这在我的这个项目中效果非常好,虽然规模比较小,但可能与你想要的非常相似。) - leftaroundabout
1
ArrayFire是一个相当接近Eigen的实现。在这里可以看到ArrayFire与Eigen的基准测试结果:http://www.accelereyes.com/products/benchmarks_arrayfire(我知道这一点,因为我曾在Eigen和ArrayFire上工作过)。 - arrayfire
1
你能提供一些你看到的错误吗?如果Eigen使用C++11,那么nvcc可能不支持。然而,对于任何不太前沿的C++,nvcc应该可以处理得很好——它会将C++主机代码传递给主机编译器。 - harrism
显示剩余2条评论
3个回答

3
NVCC调用普通主机编译器之前会进行一些预处理,因此很可能NVCC无法正确解析Eigen代码(特别是如果它使用C++11功能,但你说VS2008可以工作,这不太可能)。
我通常建议将设备代码和包装器分离到.cu文件中,并将应用程序的其余部分保留在正常的.c/.cpp文件中,由主机编译器直接处理。请参见this answer以获取有关在VS2008中设置此项的一些提示。

2

从Eigen 3.3版本开始,nvcc(7.5)可以成功地将Eigen代码传递给cl(MSVC 2013)(几乎?)正确。例如,以下代码仅产生11个警告:

#include <Eigen/Core>
#include <iostream>

int main()
{
    std::cout << "Hello Eigen\t";
    std::cout << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION << "\n";
    std::cout << "Hello nvcc\t";
    std::cout << __CUDACC_VER_MAJOR__ << "." << __CUDACC_VER_MINOR__ << "." << __CUDACC_VER_BUILD__ << "\n";
    return 0;
}

按预期输出(Eigen 3.3rc1):

Hello Eigen 3.2.94
Hello nvcc 7.5.17

但是有一长串警告(如果您真的想看,请参见历史记录)。

更新:

不幸的是,使用CUDA 8.0&VS2015(同时使用Eigen 3.2.9和Eigen 3.3rc1)再次导致编译错误:

"operator=" has already been declared in the current scope eigen\src\Core\Block.h 111
"operator=" has already been declared in the current scope eigen\src\Core\Ref.h 89

就差一步了...

更新2:

这已在提交中得到修复 59db051 并可通过使用开发分支或等待v3.3(或3.3rc2)来获得。


你是否已经成功运行了使用Eigen:: Vector3d等的内核?我还没在任何地方找到过,也未能实现可行的最小工作示例。 - GPMueller
@GMueller,我个人没有尝试过,但我也没有必要。我的问题更像是OP的问题。发表一下你尝试过的内容,我相信会有人能够帮助你解决问题。 - Avi Ginsburg

2

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