【发布时间】:2018-08-02 17:19:55
【问题描述】:
我是 CUDA C 的新手。我正在编写一个简单的数组 Add 和 Reduce,当它运行从设备复制回主机的错误检查时,我得到一个“未知错误”。我不确定错误检查器是否有问题并且没有返回正确的 cudaError 但我无法找出问题所在......
using namespace std;
#include <iostream>
void CudaAddReduce(int *input, int *output, size_t size);
__global__ void Fill(int *fillItem);
__global__ void Add(int *input1, int *result);
__global__ void Reduce(int *intputArray, int *outputArray);
main(int argc, char *argv[])
{
const int N = 100;
int inp[N];
int outp[N];
size_t size = (N * sizeof(int));
CudaAddReduce(inp,outp,size);
cout << outp[N] << endl;
}
void CudaAddReduce(int *input, int *output, size_t size)
{
// allocate buffers to device
//input
int *d_input;
if (cudaMalloc(&d_input,size) != cudaSuccess){
cerr << cudaGetErrorString(cudaGetLastError()) << endl;
cout << "Input allocation to device" << endl;
exit(1);
}
////////////////////////////
//output
int *d_output;
if (cudaMalloc(&d_output,size) != cudaSuccess){
cerr << cudaGetErrorString(cudaGetLastError()) <<endl;
cout << "output allocation to device" << endl;
exit(1);
}
//////////////////////////////////
//copy buffers to device from host
//////////////////////////////////
//input
if (cudaMemcpy(d_input, input, size, cudaMemcpyHostToDevice) != cudaSuccess){
cerr << cudaGetErrorString(cudaGetLastError()) << endl;
cout << "Input Copy from host to device" << endl;
exit(1);
}
/////////////////////////////////
//execute device kernals
/////////////////////////////////
int numThreads = 256;
int numBlocks = 1;
//Fill Kernal
Fill<<<numBlocks,numThreads>>>(d_input);
// Add Kernal
Add<<<numBlocks,numThreads>>>(d_input,d_output);
//execute Reduce Kernal
Reduce<<<numBlocks,numThreads>>>(d_output,d_input);
cudaThreadSynchronize();
/////////////////////////////////
//copy result from device to host
/////////////////////////////////
//output
if (cudaMemcpy(output,d_output,size,cudaMemcpyDeviceToHost)!= cudaSuccess){
cerr << cudaGetErrorString(cudaGetLastError()) << endl;
cout << "Output Copy from device to host" << endl;
exit(1);
}
//clear device buffers
cudaFree(d_input);
cudaFree(d_output);
}
__global__ void Fill(int *fillItem)
{
int id = blockIdx.x * blockDim.x + threadIdx.x;
fillItem[id] = 1;
}
__global__ void Add (int *input1, int* result)
{
int id = blockIdx.x * blockDim.x + threadIdx.x;
result[id] = input1[id] + input1[id];
}
__global__ void Reduce(int *inputArray, int *outputArray)
{
extern __shared__ int sdata[];
// each thread loads one element from global to shared mem
unsigned int tid = threadIdx.x;
unsigned int i = blockIdx.x * blockDim.x + threadIdx.x;
sdata[tid] = inputArray[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) outputArray[blockIdx.x] = sdata[0];
}
谢谢
【问题讨论】:
-
从哪里开始... 每个内核都包含越界内存操作,reduce 内核缺少共享内存大小内核参数,并且您的
main中的cout包含越界内存访问. -
我不认为一个问题应该因为提问者写了错误的代码而被否决。这个问题是合法的(它甚至吸引了一个合法的答案。它可能不值得任何赞成票,但不要反对它。
-
我同意哈里斯主义。虽然错误 bing 重命名为 YouveDoneSomethingStupidWithMemoryError 可能会让生活变得更轻松,因为这是我唯一一次看到它!
-
我确实对它投了反对票,原因如下:这不是因为代码不好,而是因为(如最初写的那样)问题表明几乎没有在调试它时做出任何努力。有内存分配、三个单独的内核启动和主机设备内存传输。像注释掉代码部分并运行它这样简单的事情将有助于隔离代码中第一个问题发生的位置。即使提问者不明白为什么会这样,它也会大大改进问题并简化发布到问题的代码
-
见What Stack Overflow is not...。正如所写的那样,这个问题不太可能对其他人有帮助。曾经。但如果问题类似于“在什么情况下运行时 API 会返回‘未知错误’?这是一个小重现案例.....有人可以解释为什么这段代码失败以及错误消息的含义这种情况?”。这对其他人来说是一个有用的问题和答案。
标签: c++ visual-studio-2008 cuda