[英]How to pass a function as a cuda kernel parameter?
我想创建一个通用cuda内核,该内核将可调用对象作为参数(例如lambda或function)并调用它。
我无法将设备功能作为参数传递给cuda内核。
我有计算能力3.5的cuda 9.2。 我在Debian 10上使用gcc 9.3
我试过了,用nvcc -arch=sm_35 --expt-extended-lambda main.cu -o test
:
__host__ __device__ void say_hello()
{
printf("Hello World from function!\n");
}
template<class Function>
__global__ void generic_kernel(Function f)
{
f();
}
int main()
{
// this is working
generic_kernel<<<1,1>>>([]__device__(){printf("Hello World from lambda!\n");});
cudaDeviceSynchronize();
// this is not working!
generic_kernel<<<1,1>>>(say_hello);
cudaDeviceSynchronize();
return 0;
}
我希望Hello World from function!
上看到两个Hello World from function!
和Hello World from lambda!
但我只看到来自lambda的消息。
任何版本的CUDA都不支持Debian环境。 gcc 9.3不支持CUDA 9.2
在cuda
标签上,存在很多涉及这些主题的问题。 此答案链接到其中许多。
简短的版本是根本上不可能在主机代码中捕获__device__
函数地址。 内核启动(如此处所示)是用主机代码编写的; 它是主机代码。 因此,在主机代码中使用say_hello
,它将引用__host__
函数的指针/地址。 该功能指针/地址在设备代码中没有用。 (删除__host__
装饰器将无济于事。)
有许多可能的解决方案,您已经探索了其中一种。 传递包装在某种对象中的函数,当直接使用__device__
lambda时,就适合该描述。
对于您无法使用的函数指针方法,另一种可能的解决方法是在设备代码中捕获函数指针。 然后必须将其传递到主机,然后可以在其中通过内核启动将其传递回设备代码,并在此分派。 上面的链接的答案提供了许多可以实现此目的的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.