VexCL、Thrust 和 Boost.Compute 的区别

Posted

技术标签:

【中文标题】VexCL、Thrust 和 Boost.Compute 的区别【英文标题】:Differences between VexCL, Thrust, and Boost.Compute 【发布时间】:2013-12-07 21:12:01 【问题描述】:

只要粗略了解这些库,它们看起来就非常相似。我知道 VexCL 和 Boost.Compute 使用 OpenCl 作为后端(尽管 V1.0 版本的 VexCL 也支持 CUDA 作为后端),而 Thrust 使用 CUDA。除了不同的后端,它们之间有什么区别。

具体来说,他们解决了哪些问题空间以及我为什么要使用一个而不是另一个。

此外,在推力常见问题解答中指出

支持 OpenCL 的主要障碍是缺乏支持 C++ 模板的 OpenCL 编译器和运行时

如果是这样,VexCL和Boost.Compute怎么可能存在。

【问题讨论】:

别忘了 C++ AMP! :) 【参考方案1】:

我是VexCL 的开发人员,但我真的很喜欢Kyle Lutz,Boost.Compute 的作者,在Boost mailing list 上就同一主题所说的话。简而言之,从用户的角度来看,Thrust、Boost.Compute、AMD 的Bolt 可能还有微软的C++ AMP 都实现了类似STL 的API,而VexCL 是一个基于表达式模板的库,本质上更接近Eigen .我相信类 STL 库之间的主要区别在于它们的可移植性:

    Thrust 仅支持 NVIDIA GPU,但也可以通过其 OpenMP 和 TBB 后端在 CPU 上工作。 Bolt 使用 AMD 对 OpenCL 的扩展,这些扩展仅在 AMD GPU 上可用。它还提供 Microsoft C++ AMP 和 Intel TBB 后端。 唯一支持 Microsoft C++ AMP 的编译器是 Microsoft Visual C++(虽然 Bringing C++AMP Beyond Windows 的工作正在进行中)。 Boost.Compute 似乎是其中最便携的解决方案,因为它基于标准 OpenCL。

同样,所有这些库都在尝试实现类似 STL 的接口,因此它们具有非常广泛的适用性。 VexCL 的开发考虑了科学计算。如果 Boost.Compute 开发得早一点,我可能会在它之上建立 VexCL :)。另一个值得关注的科学计算库是ViennaCL,这是一个免费的开源线性代数库,用于在多核架构(GPU、MIC)和多核 CPU 上进行计算。查看 [1] 以比较该领域的 VexCL、ViennaCL、CMTL4 和 Thrust。

关于引用的 Thrust 开发人员无法添加 OpenCL 后端:Thrust、VexCL 和 Boost.Compute(我不熟悉其他库的内部结构)都使用元编程技术来完成他们所做的事情。但是由于 CUDA 支持 C++ 模板,因此 Thrust 开发人员的工作可能更容易一些:他们必须编写元程序,在 C++ 编译器的帮助下生成 CUDA 程序。 VexCL 和 Boost.Compute 作者编写的元程序可以生成生成 OpenCL 源代码的程序。看看slides 我试图解释 VexCL 是如何实现的。所以我同意当前 Thrust 的设计禁止他们添加 OpenCL 后端。

[1] Denis Demidov、Karsten Ahnert、Karl Rupp、Peter Gottschling、Programming CUDA and OpenCL: A Case Study Using Modern C++ Libraries、SIAM J. Sci。计算机,35(5),C453–C472。 (arXiv version 也可用)。

更新:@gnzlbg 评论说在基于 OpenCL 的库中不支持 C++ 函子和 lambda。事实上,OpenCL 基于 C99 并在运行时从存储在字符串中的源代码编译,因此没有简单的方法与 C++ 类进行完全交互。但公平地说,基于 OpenCL 的库确实在一定程度上支持基于用户的函数甚至 lambda。

Boost.Compute 提供自己的implementation of simple lambdas(基于Boost.Proto),并允许通过BOOST_COMPUTE_ADAPT_STRUCT 和BOOST_COMPUTE_CLOSURE 宏与用户定义的结构进行交互。 VexCL 为 OpenCL 函数提供类似线性代数的 DSL(也基于 Boost.Proto)和supports conversion of generic C++ algorithms and functors(甚至是 Boost.Phoenix lambdas)。 我相信 AMD 的 Bolt 确实通过其 C++ for OpenCL 扩展魔术支持用户定义的函子。

话虽如此,基于 CUDA 的库(可能是 C++ AMP)在实际编译时编译器方面具有明显优势(您能这么说吗?),因此与用户代码的集成可以更加紧密。

【讨论】:

您可能想补充一点,虽然基于 OpenCL 的库不支持作为内核的函数对象(和 lambda),但那些不基于 OpenCL 的库通常支持。 对这些库中用于模拟函数对象支持的功能进行了非常好的总结!干得好!你提到的关于 AMD 的 Bolt 的 OpenCL 扩展魔法的 C++ 就是 C++AMP。 他们确实支持C++ code in OpenCL sources。 这似乎只是一个模板函数,但a bit below 他们在 OpenCL 字符串中使用模板。那个标准的 OpenCL 或 AMD 是特定的吗?我不知道你能做到这一点! 是的,我可能错过了一点。这是扩展名specification。这是announcement。

以上是关于VexCL、Thrust 和 Boost.Compute 的区别的主要内容,如果未能解决你的问题,请参考以下文章

在thrust::device_vector (CUDA Thrust) 上的thrust::min_element 崩溃

CUDA Thrust 大幅减少

我可以使用thrust::host_vector 还是必须使用cudaHostAlloc 进行Thrust 的零拷贝?

在 MATLAB MEX 文件中使用 Thrust 的运行时链接器错误

如何将 std::vector<thrust::device_vector<int>> 转换为 int**?

Thrust::sort 使无效参数崩溃