我可以在 Windows7x64 (MSVC) 和 Linux64 (GCC4.8.2) 的 .cu 文件 (CUDA5.5) 中使用 C++11 吗?

Posted

技术标签:

【中文标题】我可以在 Windows7x64 (MSVC) 和 Linux64 (GCC4.8.2) 的 .cu 文件 (CUDA5.5) 中使用 C++11 吗?【英文标题】:Can I use C++11 in the .cu-files (CUDA5.5) in Windows7x64 (MSVC) and Linux64 (GCC4.8.2)? 【发布时间】:2014-02-22 20:14:35 【问题描述】:

当我在 Windows7x64 (MSVS2012 + Nsight 2.0 + CUDA5.5) 中编译以下包含设计 C++11 的代码时,我没有收到错误,并且一切都编译并运行良好:

#include <thrust/device_vector.h>

int main() 
    thrust::device_vector<int> dv(10);
    auto iter = dv.begin();

    return 0;

但是当我尝试在 Linux64(Debian 7 Wheezey + Nsight Eclipse from CUDA5.5)下编译它时,我得到了错误:

../src/CudaCpp11.cu(5):错误:缺少显式类型(“int” 假设)

../src/CudaCpp11.cu(5):错误:没有合适的转换函数来自

"thrust::detail::normal_iterator>" 到 "int" 存在

在编译过程中检测到 2 个错误 “/tmp/tmpxft_00001520_00000000-6_CudaCpp11.cpp1.ii”。制作:* [src/CudaCpp11.o] 错误2

当我添加行时:-stdc++11

在属性->构建->设置->工具设置->构建阶段->预处理器选项(-Xcompiler)

我收到更多错误:

/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h(432):错误: 标识符“nullptr”未定义

/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stddef.h(432):错误: 期望一个“;”

...

/usr/include/c++/4.8/bits/cpp_type_traits.h(314):错误:命名空间 "std::__gnu_cxx" 没有成员

“__normal_iterator”

/usr/include/c++/4.8/bits/cpp_type_traits.h(314):错误:预期 ">"

nvcc 错误:“cudafe”因信号 11 而死(内存无效 参考)制作:* [src/CudaCpp11.o] 错误 11

仅当我在 Linux-GCC 中使用 thrust::device_vector&lt;int&gt;::iterator iter = dv.begin(); 时,我才不会收到错误消息。但在 Windows MSVS2012 中,所有 c++11 功能都可以正常工作!

【问题讨论】:

gcc 4.8.x 在linux下不是officially supported compiler。 @Robert Crovella GCC 4.7.2 具有相同的效果 - 无法在 nvcc+gcc 中编译 C++11。或者我该怎么做,或者我可以在 nvcc+icc(英特尔编译器)中使用 C++11 吗? 从我的脑海中浮现:最后我可以参加一个关于 GPU 编程的讲座。只需1.5小时。从那里我记得我们在幻灯片上看到的所有代码都是基于 C99 的 GPU 特殊语言。不知道是不是CUDA,我记不太清楚了。但如果是,则意味着该语言甚至不是 C 或 C++,它只是基于 C99。也许新特性会来自 C 或 C++ 的新标准,也许不会。您必须跟踪特定语言的发展。但是,如果是其他内容,请忽略此评论。稍后我将尝试找到有关此主题的更多信息。 检查我的解决方案:***.com/questions/25941117/c11-standard-with-cuda-6-0 【参考方案1】:

您可能必须像这样从 others.cu拆分 main.cpp

others.hpp:

void others();

others.cu:

#include "others.hpp"
#include <boost/typeof/std/utility.hpp>
#include <thrust/device_vector.h>

void others() 
    thrust::device_vector<int> dv(10);
    BOOST_AUTO(iter, dv.begin()); // regular C++

main.cpp:

#include "others.hpp"

int main() 
    others();

    return 0;

This particular answer 表明使用官方支持的 gcc 版本进行编译(正如 Robert Crovella 正确指出的那样)至少应该适用于 ma​​in.cpp 文件中的 c++11 代码:

g++ -std=c++0x -c main.cpp
nvcc -arch=sm_20 -c others.cu 
nvcc -lcudart -o test main.o others.o

(在 Debian 8 上使用 nvcc 5.5 和 gcc 4.7.3 测试)。

要回答您的基本问题:我不知道可以在 Linux 中使用 CUDA 5.5 在 .cu 文件中使用 C++11(而且我不知道显示的主机端 C++11 示例是否正确- 在 MSVC 下杂乱无章)。我什至为 constexpr 支持提出了功能请求,该支持仍然开放。

CUDA programming CUDA 5.5 指南指出:

对于主机代码,nvcc 支持 C++ ISO/IEC 的任何部分 主机 c++ 编译器支持的 14882:2003 规范。

对于设备代码,nvcc 支持代码中说明的特性 限制中描述的具有一些限制的示例;它不是 支持运行时类型信息 (RTTI)、异常处理和 C++ 标准库。

无论如何,可以在内核中使用 一些 C++11 功能,例如 auto,例如与升压::自动。 展望未来,threads 等其他 C++11 功能可能不太可能最终出现在 CUDA 中,我还没有听说过关于它们的官方计划(截至supercomputing 2013)。

无耻插件:如果您对这些 tweeks 中的更多内容感兴趣,请随时查看我们的库 libPMacc,它为模拟提供了多 GPU 网格和粒子抽象。我们实现了 lambda,这是一个类似于 STL 的访问概念,用于 1-3D 矩阵和其他有用的东西。

一切顺利, 阿克塞尔


更新:由于CUDA 7.0 C++11 支持内核 已正式添加。正如 BenC 正确指出的那样,此功能的部分内容已在 CUDA 6.5 中悄悄添加。

【讨论】:

【参考方案2】:

According to Jared Hoberock(Thrust 开发人员),似乎 C++11 支持已添加到 CUDA 6.5(尽管它仍处于试验阶段且未记录)。当您开始在非常大的 C++/CUDA 项目中使用 C++11 时,这可能会使事情变得更容易,因为当您使用 CMake 时,拆分所有内容对于大型项目来说可能非常麻烦。

【讨论】:

非常感谢!好消息是:“这个想法是 nvcc 将支持 主机编译器支持的任何 c++11 构造。他们将在未来某个时候发布描述警告的文档。最大的限制是 lambdas无法从主机传递到 全局 函数启动。根据我的经验,您提到的所有构造都支持使用 g++ 作为主机编译器。 " 更新:CUDA 7.0 添加in kernel c++11 支持。我更新了我的答案以反映这一点。

以上是关于我可以在 Windows7x64 (MSVC) 和 Linux64 (GCC4.8.2) 的 .cu 文件 (CUDA5.5) 中使用 C++11 吗?的主要内容,如果未能解决你的问题,请参考以下文章

std::ofstream 无法在 win7/64 和 msvc2013 上使用 std::ios::ate 打开大文件

错误未能在 Windows 7x64 上构建 json gem 本机扩展

如何使用 MSVC 2008 在 Windows 上使用 qtwebkit 构建 Qt5 - leveldb 找不到 stdint.h

memcach 安装

使用 Dependency Walker 分析 x86 可执行文件在 Windows 7 x64 上挂起

使用 Windows 7 x64 将 ASP.NET 与 Access 数据库 2010 连接