我花了很多时间试图找出发生了什么?问题是我无法从主机代码调用这个简单的内核。我确信这个错误会立即引起一些人的注意,但我觉得我浪费了很多时间没有理由。所以我真的很感激任何帮助。
这是我的.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时识别它!请有人帮助我最终开始真正的事情!
答案 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