2013-08-28 18 views
0

我只想通過設備函數作爲主函數的參數,因此,主函數然後可以用這個設備端函數啓動一些內核。如何將設備函數作爲輸入參數傳遞給主機端函數?

我嘗試了通常的C++方法(通過指針/引用傳遞),CUDA調試器告訴我內核無法啓動。

更新:

我想要做的是:

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

而且隨着啓動主機:

hostfunction(x, &SomeDeviceFunctionTemplate<int>); 
+1

你的問題並不完全清楚,至少對我而言。如果你可以發佈一個你嘗試過的例子,內核沒有啓動,那可能會有幫助。 –

+1

由於'__host__'函數不能獲取'__device__'函數的地址,所以您基本上需要編寫一個簡短的'__global__'函數來獲取感興趣的'__device__'函數的地址,然後將其存儲到內存中。你的'__host__'函數然後可以從內存中讀取該函數指針,然後將它傳遞給'somekernel'。 –

回答

1

這將會是有益的,如果你可以發佈一個例子你要做的事情,但有一點要檢查的是你正在編譯和運行在費米(sm_20)或更高版本,因爲舊的GPU不支持非內聯函數c承滴盤。

檢查設備的計算能力(需要2.0或更高版本)並檢查您的nvcc命令行(需要-arch=sm_20或更高版本,或-gencode等效項)。

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 
[[email protected] misc]$ 

我想,這大概是什麼一起被賈裏德暗示的線路。 正如他所說,這不會在主機代碼是可行的:

&SomeDeviceFunctionTemplate<int> 

假設SomeDeviceFunctionTemplate__device__功能。

相關問題