繁体   English   中英

如何将函数作为cuda内核参数传递?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM