Cuda 如何将指向设备函数的指针作为参数传递给内核函数?

Cuda 如何将指向设备函数的指针作为参数传递给内核函数?,cuda,Cuda,这个问题是关于CUDA C/C++编程的。我试着寻找了很多,但没有找到合适的问题,所以也没有找到答案。 我有1个设备函数、1个内核函数和主函数: typedef float (*pfunc)(float arg); __device__ float dev_func(float arg) { return arg * arg; } __global__ void ker_func(pfunc fnc) { printf("%f\n", fnc(2)); } int main

这个问题是关于CUDA C/C++编程的。我试着寻找了很多,但没有找到合适的问题,所以也没有找到答案。 我有1个设备函数、1个内核函数和主函数:

typedef float (*pfunc)(float arg);

__device__ float dev_func(float arg) {
    return arg * arg;
}

__global__ void ker_func(pfunc fnc) {
    printf("%f\n", fnc(2));
}

int main(void) {
    pfunc fnc = dev_func;
    //now how do I copy this pointer to device memory?
    ker_func<<<1,1>>>(...);
    return 0;
}
从:

主机代码中的_全局_函数地址不能用于设备代码,例如启动内核。类似地,在设备代码中使用的_全局__)函数的地址不能在主机代码中使用

不允许在主机代码中获取_设备_函数的地址

所以你有两个选择:

全局定义_设备_函数指针,并在内核中调用它

typedef float (*pfunc)(float arg);

__device__ float dev_func(float arg) {
    return arg * arg;
}

// create device function pointer here
__device__ pfunc dev_func_ptr = dev_func;

__global__ void ker_func() {
    // call function through device function pointer
    printf("%f\n", dev_func_ptr(2));
}
如果要将函数指针作为参数传递给内核,则:

#define gpuErrchk(val) \
    cudaErrorCheck(val, __FILE__, __LINE__, true)
void cudaErrorCheck(cudaError_t err, char* file, int line, bool abort)
{
    if(err != cudaSuccess)
    {
        printf("%s %s %d\n", cudaGetErrorString(err), file, line);
        if(abort) exit(-1);
    }
}

typedef float (*pfunc)(float arg);

__device__ float dev_func(float arg) {
    return arg * arg;
}

// create device function pointer here
__device__ pfunc dev_func_ptr = dev_func;

__global__ void ker_func(pfunc fnc) {
    // call function through device function pointer
    printf("%f\n", fnc(2));
}


int main(int argc, char** argv)
{
    // create a host function pointer
    pfunc host_function_ptr;
    // copy function pointer value from device to host
    gpuErrchk(cudaMemcpyFromSymbol(&host_function_ptr, dev_func_ptr, sizeof(pfunc)));
    // pass the copied function pointer in kernel
    ker_func<<<1,1>>>(host_function_ptr);

    gpuErrchk(cudaPeekAtLastError());
    gpuErrchk(cudaDeviceSynchronize());

    return 0;
}