CUDA的Lambda表达式
Lambda expressions with CUDA
如果我在thrust::host
上使用thrust::transform
,则lambda使用正常
thrust::transform(thrust::host, a, a+arraySize,b,d,[](int a, int b)->int
{
return a + b;
});
但是,如果我将thrust::host
更改为thrust::device
,代码将无法通过编译器。以下是VS2013上的错误:
lambda的闭包类型("lambda [](int, int)->int")不能在
__global__
函数模板实例化的模板实参类型中使用,除非在__device__
或__global__
函数中定义了lambda
所以,问题是如何使用__device__
或__global__
连接到设备lambda。
在CUDA 7中这是不可能的。引用Mark Harris的话:
目前在CUDA中不支持,因为lambda是主机代码。将lambda从主机传递到设备是一个具有挑战性的问题,但我们将在未来的CUDA版本中对此进行研究。
你可以在CUDA 7中做的是从你的设备代码调用推力算法,在这种情况下,你可以传递lambdas给他们…
在CUDA 7中,推力算法可以从设备代码中调用(例如CUDA内核或__device__
函子)。在这些情况下,可以使用带推力的(device) lambda。这里的parallelforall博客文章给出了一个例子。
然而,CUDA 7.5引入了一个实验性设备lambda特性。此特性描述如下:
CUDA 7.5引入了一个实验性的特性:GPU lambda。GPU lambdas是匿名设备函数对象,您可以在主机代码中定义,通过使用
__device__
说明符注释它们。
为了启用此功能的编译,(目前,在CUDA 7.5中)有必要在nvcc
编译命令行中指定--expt-extended-lambda
。
使用设备lambda的简单代码在CUDA 8.0 RC下工作,尽管该版本的CUDA的设备lambda仍处于实验阶段:
#include <thrust/device_vector.h>
#include <thrust/functional.h>
#include <thrust/transform.h>
using namespace thrust::placeholders;
int main(void)
{
// --- Input data
float a = 2.0f;
float x[4] = { 1, 2, 3, 4 };
float y[4] = { 1, 1, 1, 1 };
thrust::device_vector<float> X(x, x + 4);
thrust::device_vector<float> Y(y, y + 4);
thrust::transform(X.begin(),
X.end(),
Y.begin(),
Y.begin(),
[=] __host__ __device__ (float x, float y) { return a * x + y; } // --- Lambda expression
);
for (size_t i = 0; i < 4; i++) std::cout << a << " * " << x[i] << " + " << y[i] << " = " << Y[i] << std::endl;
return 0;
}
记得用
--expt-extended-lambda
为编译。- 这 4 个 lambda 表达式之间有什么区别?
- 使用成员在类中创建 lambda 表达式
- 使用自动推导的 lambda 参数作为常量表达式
- 将 lambda 表达式传递给 std::function in C++
- 在 lambda 表达式中使用 std::atomic
- 不是 lambda 函数中的常量表达式
- &&对lambda表达式有什么好处?
- Tbb 库:错误:编写自定义类函数而不是 lambda 表达式时,对函数的调用不匹配
- 列表.erase 中的 lambda 表达式
- 使用 lambda 表达式的 Raspbian G++ 8.3.0 导致 ']' 之前的预期主表达式 - 即使标准设置为 c++14
- 仅通过引用捕获的 lambda 表达式是否保证不会抛出?
- C++: priority_queue:模板参数中的 lambda 表达式
- 容器如何处理 lambda 表达式的参数
- 在C++ Lambda 表达式中,为什么人们更喜欢按值捕获而不是作为参数传递?
- 如何在 lambda 表达式中传递变量?
- 针对 std::function 的 lambda 表达式和模板推导:为什么会这样?
- 如何修改Lambda表达式以将输出放入文本文件
- C++如何使用lambda表达式来捕获上一次迭代的值
- 为什么Qt在信号和插槽中为lambda表达式抛出错误?
- C++:从捕获函数参数的函数返回 lambda 表达式