2011-05-01 49 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);