2011-05-01 67 views
1

我花了很多時間試圖找出發生了什麼?問題是我無法從我的主機代碼調用這個簡單的內核。我敢肯定,這個錯誤會立即對某些人顯着,但我覺得我很可能沒有理由浪費了很多時間。所以我非常感謝任何幫助。簡單程序中的CUDA問題

這是我的.cpp代碼

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <time.h> 
#include <windows.h> 
#include <shrUtils.h> 
#include <cutil_inline.h> 
#include <cutil_gl_inline.h> 
#include <cuda.h> 


CUfunction reduce0; //i've used many ways to declare my kernel function,but..... 


int main(int argc , char *argv[]){ 

    int i,N,sum; 
    int *data; 
    int *Md; 
    srand (time(NULL)); 
    N=(int)pow((float)2,(float)atoi(argv[1])); 
    data=(int *)malloc(N * sizeof(int)); 

    for (i=0;i<N;i++){ 
     data[i]=rand() % 10 + 1;  
    } 
    cudaMalloc((void**) &Md, N); 

    clock_t start = clock(); 

    dim3 dimBlock(512,0); 
    dim3 dimGrid(1,1); 

    reduce0<<< dimGrid,dimBlock >>>(Md,Md);  



    sum=0; 
    for(i=0;i<N;i++){ 
     sum=sum+data[i]; 
    } 

    printf("Sum of the %d-array is %d \n", N , sum); 
    printf("Time elapsed: %f\n", ((double)clock() - start)/CLOCKS_PER_SEC); 

return 0; 

} 

這裏是我的代碼.CU

__global__ void reduce0(int*g_idata, int*g_odata){ 

extern __shared__ int sdata[]; 

// each thread loadsone element from global to shared mem 

unsigned int tid = threadIdx.x; 
unsigned int i= blockIdx.x*blockDim.x+ threadIdx.x; 
sdata[tid] = g_idata[i]; 

__syncthreads(); 

// do reduction in shared mem 

for(unsigned int s=1; s < blockDim.x; s *= 2) { 
if(tid % (2*s) == 0){ 
sdata[tid] += sdata[tid + s]; 
} 

__syncthreads(); 
} 

// write result for this block to global mem 
if(tid == 0) g_odata[blockIdx.x] = sdata[0]; 
} 

那麼請問我應該怎麼做才能調用內核?在編譯時,它不識別這個符號「< < <」,並且就reduce0()而言,只有在.cpp聲明時才能識別它!請有人幫助我終於開始真正的cuda事情!

+0

你是如何調用編譯器? – 2011-05-01 15:16:02

回答

1

CUfunction是一個驅動程序API抽象 - 如果您要使用語言集成功能來啓用內核調用的語法,則不需要。

如果您不需要使用驅動程序API(大多數人不需要),只需將您的C++代碼移動到.cu文件中,然後像現在這樣調用內核。

cudaMalloc()調用分配CPU無法讀取或寫入的設備內存。您必須使用cudaMemcpy(...,cudaMemcpyHostToDevice);將縮減輸入複製到設備內存中,然後在完成處理後,將輸出複製到主機內存使用cudaMemcpy(..., cudaMemcpyDeviceToHost);

ps該減少內核非常慢。我建議你打開Reduce SDK並從那裏使用其中一個內核。

或者,使用將包含在CUDA 4.0中的Thrust庫。推力支持非常快速和靈活的減少。

+0

感謝您的回覆。 如果我把我的cpp文件移動到cu文件,它將如何清楚哪個是主機代碼,哪個是設備代碼?我的意思是,據我所知cpp =主機代碼和cu =設備代碼。 此外,你可以給我一個教程(一個教程的鏈接或類似的東西)如何可以由主機代碼調用內核? – Marios 2011-05-01 16:13:36

+0

ps我知道這個算法有7個改進的步驟。我現在正在做的是我論文的一部分 – Marios 2011-05-01 16:21:36

+0

另一件事是,我不想使用cufunction.It是我試圖讓這件事情工作的最後一件事!所以我只是忘了清除它;) – Marios 2011-05-01 16:23:13

0

調用內核的代碼必須由NVCC編譯器處理。 (< < <無效C++)通常意味着把它放在.cu文件中。你不想把所有的cpp代碼轉移到cu中(就像你在註釋中提到的那樣),只是調用內核的代碼。

變化

CUfunction reduce0; 

void reduce_kernel(int*g_idata, int*g_odata); 

並更換這些線路:

dim3 dimBlock(512,0); 
dim3 dimGrid(1,1); 

reduce0<<< dimGrid,dimBlock >>>(Md,Md); 

有:

reduce_kernel(Md, Md); 

並添加到您的.CU文件:

void reduce_kernel(int*g_idata, int*g_odata) 
{ 
    dim3 dimBlock(512,0); 
    dim3 dimGrid(1,1); 

    reduce0<<< dimGrid,dimBlock >>>(g_idata, g_odata); 
} 

這把我的頭頂部,所以可能會稍微偏離,但你可以得到的想法。

0

調用內核的代碼必須由NVCC編譯器處理。(< < <無效C++)通常意味着把它放在.cu文件中。你不想把所有的cpp代碼轉移到cu中(就像你在註釋中提到的那樣),只是調用內核的代碼。

0

除了上面的內容,我想我在你的cudaMalloc調用中發現了一個錯誤。即使這不是一個實際的錯誤,我認爲這是更好的可移植性編程實踐。它應該改爲:

cudaMalloc((void**) &Md, sizeof(int)*N);