如果你正在寻找更高维度的容器以及在内核代码中传递和操作这些容器的能力,我花了几年的时间来开发 ecuda API协助我自己的科研项目(所以它已经完成了步伐)。希望它可以填补所需的利基。它是如何使用的简短示例(此处使用了C ++ 11特性,但ecuda可以与前C ++ 11编译器一起使用):
#include <cstdlib> #include <iomanip> #include <iostream> #include <vector> #include <ecuda/ecuda.hpp> // kernel function __global__ void calcColumnSums( typename ecuda::matrix<double>::const_kernel_argument mat, typename ecuda::vector<double>::kernel_argument vec ) { const std::size_t t = threadIdx.x; auto col = mat.get_column(t); vec[t] = ecuda::accumulate( col.begin(), col.end(), static_cast<double>(0) ); } int main( int argc, char* argv[] ) { // allocate 1000x1000 hardware-aligned device memory matrix ecuda::matrix<double> deviceMatrix( 1000, 1000 ); // generate random values row-by-row and copy to matrix std::vector<double> hostRow( 1000 ); for( std::size_t i = 0; i < 1000; ++i ) { for( double& x : hostRow ) x = static_cast<double>(rand())/static_cast<double>(RAND_MAX); ecuda::copy( hostRow.begin(), hostRow.end(), deviceMatrix[i].begin() ); } // allocate device memory for column sums ecuda::vector<double> deviceSums( 1000 ); CUDA_CALL_KERNEL_AND_WAIT( calcColumnSums<<<1,1000>>>( deviceMatrix, deviceSums ) ); // copy columns sums to host and print std::vector<double> hostSums( 1000 ); ecuda::copy( deviceSums.begin(), deviceSums.end(), hostSums.begin() ); std::cout << "SUMS ="; for( const double& x : hostSums ) std::cout << " " << std::fixed << x; std::cout << std::endl; return 0; }
我把它写成尽可能直观(通常像用ecuda::)替换std ::一样简单。如果你知道STL,那么ecuda应该做你在逻辑上期望基于CUDA的C ++扩展所做的事情。
看一眼 Boost.Compute 。它提供了一个类似STL的高级接口,包括容器等 vector<T> 和算法 transform() 和 sort() 。
vector<T>
transform()
sort()
它建立在 OpenCL的 允许它在大多数现代GPU和CPU上运行,包括NVIDIA,AMD和Intel的GPU。
另一个高级库是 VexCL - OpenCL的矢量表达模板库。它为矢量操作提供了直观的表示法,可在MIT许可下使用。
有许多专门用于GPGPU编程的高级库。由于它们依赖于CUDA和/或OpenCL,因此必须明智地选择它们(基于CUDA的程序不会在AMD的GPU上运行,除非它经历了诸如以下项目的预处理步骤 的 gpuocelot 强> )。
您可以在NVIDIA上找到一些CUDA库的示例 网站 。
Thrust是一个类似于C ++标准的并行算法库 模板库(STL)。 Thrust的高级界面大大增强 程序员的工作效率,同时实现性能可移植性 GPU和多核CPU。与已建立的互操作性 技术(如CUDA,TBB和OpenMP)有助于集成 使用现有软件。
如 @Ashwin 指出,Thrust的类似STL语法使其成为开发CUDA程序时广泛选择的库。快速查看这些示例,可以看出如果您决定使用此库,您将编写的代码类型。 NVIDIA的网站提供了 主要特点 这个图书馆。一个 视频演示 (来自GTC 2012)也可提供。
CUB为CUDA编程模式的每一层提供最先进的可重用软件组件。它是一个灵活的协作线程块原语库和CUDA内核编程的其他实用程序。
它提供设备范围,块宽和整个经线的并行原语,如并行排序,前缀扫描,缩减,直方图等。
它是开源的,可用 GitHub上 。从实现的角度来看,它不是高级的(您在CUDA内核中开发),但提供了高级算法和例程。
该库主要用于机器学习,并且依赖于 表达模板 。
从Eigen 3.3开始,现在可以在CUDA内核中使用Eigen的对象和算法。但是,仅支持一部分功能,以确保在CUDA内核中不会触发动态分配。
注意 OpenCL的 不仅仅是GPGPU计算,因为它支持异构平台(多核CPU,GPU等)。
OpenACC应用程序接口描述了一个集合 编译器指令,用于指定标准中的循环和代码区域 C,C ++和Fortran从主机CPU卸载到附加 加速器,提供跨操作系统,主机CPU的可移植性 和加速器。
Bolt是一个针对异构计算而优化的C ++模板库。 Bolt旨在提供高性能库实现 用于常见算法,例如扫描,缩小,转换和排序。该 Bolt接口在C ++标准模板库(STL)上建模。 熟悉STL的开发人员将认识到许多Bolt API 和定制技术。
的 Boost.Compute 强> :as @Kyle Lutz 说,Boost.Compute为OpenCL提供类似STL的接口。请注意,这不是官方的Boost库(尚未)。
的 SkelCL 强> “是一个提供高级抽象的库,用于缓解现代并行异构系统的编程”。这个库依赖于 骨架编程 ,你可以在他们的网站上找到更多信息 调查报告 。
虽然这不是这个问题的范围,但对其他编程语言也有同样的支持:
如果您需要进行线性代数(例如)或其他特定操作,专用数学库也可用于CUDA和OpenCL(例如 的 ViennaCL 强> , 的 CUBLAS 强> , 的 岩浆 强> 等等。)。
另请注意,如果需要执行一些非常具体的计算,使用这些库不会阻止您执行某些低级操作。
最后,我们可以提到C ++标准库的未来。已经进行了大量工作来增加并行性支持。这是 仍然是技术规范 并没有明确提到GPU(AFAIK)(虽然NVIDIA的Thrust开发商Jared Hoberock直接参与其中),但是实现这一目标的意愿绝对存在。
该 的 推力 强> library提供容器,并行原语和算法。所有这些功能都很好地包含在类似STL的语法中。因此,如果您熟悉STL,您实际上可以使用Thrust编写整个CUDA程序,而无需编写单个CUDA内核。看看中的简单例子 的 快速入门指南 强> 看看你可以使用Thrust编写的那种高级程序。
cpp-opencl项目提供了一种使开发人员可以轻松编程GPU的方法。它允许您直接在C ++中实现GPU上的数据并行性,而不是使用OpenCL。
请参阅 http://dimitri-christodoulou.blogspot.com/2014/02/implement-data-parallelism-on-gpu.html
和源代码: https://github.com/dimitrs/cpp-opencl
请参阅下面的示例。 parallel_for_each lambda函数中的代码在GPU上执行,其余所有代码都在CPU上执行。更具体地说,在CPU(通过调用std :: transform)和GPU(通过调用compute :: parallel_for_each)上执行功能。
#include <vector> #include <stdio.h> #include "ParallelForEach.h" template<class T> T square(T x) { return x * x; } void func() { std::vector<int> In {1,2,3,4,5,6}; std::vector<int> OutGpu(6); std::vector<int> OutCpu(6); compute::parallel_for_each(In.begin(), In.end(), OutGpu.begin(), [](int x){ return square(x); }); std::transform(In.begin(), In.end(), OutCpu.begin(), [](int x) { return square(x); }); // // Do something with OutCpu and OutGpu 锟斤拷.......... // } int main() { func(); return 0; }
新的 OpenMP的 版本4现在包括加速器卸载支持。
AFAIK GPU被视为加速器。
C ++ AMP是您正在寻找的答案。