CUDA问题在一个简单的程序中

时间:2011-05-01 15:11:40

标签: c 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];
}

所以我问我应该怎么做才能调用内核?在编译时,它无法识别此符号“&lt;&lt;&lt;”至于reduce0()它只在我声明.cpp时识别它!请有人帮助我最终开始真正的事情!

5 个答案:

答案 0 :(得分:1)

CUfunction是一个驱动程序API抽象 - 如果您打算使用支持&lt;&lt;&lt;&gt;&gt;&gt;的语言集成功能,则不需要它。内核调用的语法。

如果您不必使用驱动程序API(大多数人不需要),只需将您的C ++代码移动到.cu文件中,并像现在一样调用内核。

cudaMalloc()调用分配CPU无法读取或写入的设备内存。您必须使用cudaMemcpy(...,cudaMemcpyHostToDevice);将缩减输入复制到设备内存中,然后在完成处理后,使用cudaMemcpy(..., cudaMemcpyDeviceToHost);将输出复制到主机内存

ps减少内核非常慢。我建议你打开还原SDK并使用其中一个内核。

或者,使用将包含在CUDA 4.0中的Thrust库。 Thrust支持非常快速和灵活的减少。

答案 1 :(得分:0)

调用内核的代码必须由NVCC编译器处理。 (&lt;&lt;&lt;&lt;&lt;&#;无效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);  
}

这是我的头顶,所以可能稍微偏离,但你可以得到这个想法。

答案 2 :(得分:0)

调用内核的代码必须由NVCC编译器处理。 (&lt;&lt;&lt;&lt;&lt;&#;无效C ++)通常意味着将它放在.cu文件中。您不希望将所有cpp代码移动到cu(正如您在注释中所要求的那样),只是调用内核的代码。

答案 3 :(得分:0)

除了上述内容,我想我在你的cudaMalloc调用中发现了一个错误。即使这不是一个实际的错误,我认为这是更好的可移植性编程实践。它应该是:

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

答案 4 :(得分:0)

如果您使用的是Windows计算机,请查看有关为CUDA 3.2设置Visual Studio 2010的文章: http://www.codeproject.com/Tips/186655/CUDA-3-2-on-VS2010-in-9-steps.aspx