CUDA:将设备函数作为参数传递给全局函数

CUDA:将设备函数作为参数传递给全局函数,cuda,Cuda,如何让这样的东西工作 #定义Eval(x,y,func){y=func(x);} __全局无效求值(双*xs,双*ys,int N,双f(双)) { int tid=threadIdx.x; 如果(tid

如何让这样的东西工作

#定义Eval(x,y,func){y=func(x);}
__全局无效求值(双*xs,双*ys,int N,双f(双))
{
int tid=threadIdx.x;
如果(tid
然后在我的主函数里面

double*xs_d,*ys_d;
双*xs_h,*ys_h;
xs_h=(双*)malloc(sizeof(双)*256);
ys_h=(双*)malloc(双*256);
cudaMalloc((无效**)和xs_d,sizeof(双)*256);
cudaMalloc((无效**)和ys_d,sizeof(双)*256;
对于(int i=0;i<256;i++)
{
xs_h[i]=(双)i;
}
HANDLE_ERROR(cudaMemcpy(xs_d,xs_h,256*sizeof(double),cudaMemcpyHostToDevice));
评估(xs_d,ys_d,256,Sin);
cudaDeviceSynchronize();
句柄错误(cudaMemcpy(ys_h,ys_d,256*sizeof(双精度),cudaMemcpyDeviceToHost));
它在最后一行失败了。到目前为止,我已经看到了类似的解决方案,但它们使用了
\uuuu device\uuuu
函数,主机(例如
main
函数)无法更改或访问这些函数。例如,我不能将
\uuuu设备\uuuu int*fptrf1=(int*)f1(取自示例)位于main内部。是否有可能以某种方式拥有这种灵活性

例如,我不能将
\uuuu设备\uuuu int*fptrf1=(int*)f1(取自示例)位于
main
内部。是否有可能以某种方式拥有这种灵活性

一种可能的方法是使用:

$cat t151.cu
#定义Eval(x,y,func){y=func(x);}
模板
__全局无效求值(双*xs,双*ys,int N,F)
{
int tid=threadIdx.x;
如果(tid
(CUDA 11.3)


对于指针使用的各种设备函数,本文将链接到许多示例。

谢谢。我有几个后续问题。
\uuuuu主机\uuuuuu设备\uuuuuu
是什么意思?
[]]
[]\uuuuuuuu主机\uuuuuuuu设备\uuuuuuuuuuu
中是什么意思?这是指向函数的指针吗?我可以硬编码类型而不是使用模板吗?那么该类型是什么?
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu设备
用于向CUDA编译器。在本例中,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu主机部分是不必要的,您可以删除该部分,其工作方式与此相同<代码> []/COD>语法是C++ lambda语法的一部分。我无法在这些评论的空间中给你一个关于C++ lambda函数的教程。
$ cat t151.cu
#define Eval(x, y, func) {y = func(x);}
template <typename F>
__global__ void Evaluate(double *xs, double *ys, int N, F f)
{
    int tid = threadIdx.x;
    if (tid < N)
        Eval(xs[tid], ys[tid], f);


}

int main(){
    double *xs_d, *ys_d;
    double *xs_h, *ys_h;
    xs_h = (double *) malloc(sizeof(double) * 256);
    ys_h = (double *) malloc(sizeof(double) * 256);
    cudaMalloc((void **)&xs_d, sizeof(double) * 256);
    cudaMalloc((void **)&ys_d, sizeof(double) * 256);
    for (int i = 0; i < 256; i++)
    {
        xs_h[i] = (double)i;
    }

    cudaMemcpy(xs_d, xs_h, 256*sizeof(double), cudaMemcpyHostToDevice);
    auto Sinlambda = [] __host__ __device__ (double v) {return sin(v);};
    Evaluate<<<1,256>>>(xs_d, ys_d, 256, Sinlambda);
    cudaDeviceSynchronize();
    cudaMemcpy(ys_h, ys_d, 256*sizeof(double), cudaMemcpyDeviceToHost);
}
$ nvcc -o t151 t151.cu -std=c++11 --extended-lambda
$ cuda-memcheck ./t151
========= CUDA-MEMCHECK
========= ERROR SUMMARY: 0 errors
$