如何将设备功能作为输入参数传递给主机端功能?

时间:2013-08-28 10:57:22

标签: pointers reference cuda nvidia

我只想传递设备函数作为主机函数的参数,因为主机函数可以用这个设备端函数启动一些内核。

我尝试了通常的C ++方式(通过指针/引用传递),CUDA调试器告诉我内核无法启动。

更新

我想做的是:

__host__ void hostfunction(int a, int (*DeviceFunction)(int))
{
   /...do something.../
   somekernel<<<blocks, threads>>>(int * in, DeviceFunction);
}

使用以下命令启动主机:

hostfunction(x, &SomeDeviceFunctionTemplate<int>);

2 个答案:

答案 0 :(得分:1)

如果你能发布一个你想要做的事情的例子会有所帮助,但要检查的一件事是你正在编译并运行Fermi(sm_20)或更高版本,因为旧的GPU不支持非内联函数调用。

检查设备的计算能力(需要2.0或更高版本)并检查您的nvcc命令行(需要-arch=sm_20或更高版本,或-gencode等效项。)

答案 1 :(得分:1)

这个例子可能很有用:

$ cat t237.cu
#include <stdio.h>


__device__ int f1(){ printf("dev f1\n"); return 0;}
__device__ int f2(){ printf("dev f2\n"); return 0;}
__device__ int f3(){ printf("dev f3\n"); return 0;}

__device__ int *fptrf1 = (int *)f1;
__device__ int *fptrf2 = (int *)f2;
__device__ int *fptrf3 = (int *)f3;


__global__ void mykernel(int (*fptr)()){

  fptr();
  printf("executed\n");
}

int main(){

  int *hf1, *hf2, *hf3;
  cudaMemcpyFromSymbol(&hf1, fptrf1, sizeof(int *));
  cudaMemcpyFromSymbol(&hf2, fptrf2, sizeof(int *));
  cudaMemcpyFromSymbol(&hf3, fptrf3, sizeof(int *));
  mykernel<<<1,1>>>((int (*)())hf1);
  cudaDeviceSynchronize();
  mykernel<<<1,1>>>((int (*)())hf2);
  cudaDeviceSynchronize();
  mykernel<<<1,1>>>((int (*)())hf3);
  cudaDeviceSynchronize();
  return 0;
}
$ nvcc -arch=sm_20 -O3 -o t237 t237.cu
$ ./t237
dev f1
executed
dev f2
executed
dev f3
executed
[bob@cluster1 misc]$

我认为这与Jared的建议大致相同。 正如他所提到的,这在主机代码中是不可能的:

&SomeDeviceFunctionTemplate<int>

假设SomeDeviceFunctionTemplate引用__device__函数。