我使用CUDA来计算64x64x4数组的值,该数组已经被平放。数组包含GLubytes,然后在z列中存储任意给定像素的RGBA值。我已经创建了一个与CUDA一起使用的内核,但是我想我的块和网格的尺寸是关闭的。最终的结果不是画圆圈,而是画四分之一的圆圈。调用的内核和函数如下:
澄清:直径= 64,半径= 32。
__global__ void drawKernel(GLubyte *ball)
{
int x = (blockIdx.x * blockDim.x) + threadIdx.x;
int y = (blockIdx.y * blockDim.y) + threadIdx.y;
ball[4 * (x * DIAMETER + y)+3] = (GLubyte) 0x0;
if ((x * x) + (y * y) <= (RADIUS * RADIUS)){
ball[4 * ((x+32) * DIAMETER + (y+32))+0] = (GLubyte) 0xffffff;
ball[4 * ((x+32) * DIAMETER + (y+32))+1] = (GLubyte) 0x0;
ball[4 * ((x+32) * DIAMETER + (y+32))+2] = (GLubyte) 0x0;
ball[4 * ((x+32) * DIAMETER + (y+32))+3] = (GLubyte) 0xaaaaaa;
}
}
cudaError_t drawWithCuda()
{
size_t memorySize = DIAMETER * DIAMETER * 4 *sizeof(GLubyte);
GLubyte *dev_ball = 0; //device ball
cudaError_t cudaStatus; //CUDA error status
dim3 threadsPerBlock(8, 8);
dim3 numBlocks(DIAMETER/threadsPerBlock.x, DIAMETER/threadsPerBlock.y);
// Choose which GPU to run on, change this on a multi-GPU system.
cudaStatus = cudaSetDevice(0);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaSetDevice(0) failed! CUDA-capable GPU not on board.");
goto Error;
}
// Allocate GPU buffers for GLubyte array
cudaStatus = cudaMalloc((void**)&dev_ball, memorySize);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMalloc failed!");
goto Error;
}
//Begin CUDA-kernal call
drawKernel<<<numBlocks, threadsPerBlock>>>(dev_ball);
cudaDeviceSynchronize();
//Copy from Device
cudaStatus = cudaMemcpy(ball, dev_ball, memorySize, cudaMemcpyDeviceToHost);
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "Device to Host failed!");
goto Error;
}
Error:
cudaFree(dev_ball);
return cudaStatus;
}我的问题是:我的问题在区块和网格的维度中找到了吗?或者是别的什么东西?
输出(一旦我通过openGL运行arrray球)如下所示:

我应该补充一点,当我不使用cuda并且只计算带有正则for循环的数组值时,内核中使用的逻辑工作得非常好,并绘制圆圈。
发布于 2013-11-23 21:55:15
您将分配这么多内存(在ball中):
size_t memorySize = DIAMETER * DIAMETER * 4 *sizeof(GLubyte);即一个深为64x64x4字节的数组。
现在让我们看看内核中的数组索引计算:
ball[4 * ((x+32) * DIAMETER + (y+32))+0] = (GLubyte) 0xffffff; 您的x和y计算如下:
int x = (blockIdx.x * blockDim.x) + threadIdx.x;
int y = (blockIdx.y * blockDim.y) + threadIdx.y;给定内核启动维度,您将启动一个直径x直径的线程数组,即64x64。因此,每个x从0到63不等,每个y从0到63不等,这取决于线程。
当我们将其中一些x和y值插入内核时,索引计算就会崩溃(超过分配的内存):
ball[4 * ((63+32) * 64 + (63+32))+0] = (GLubyte) 0xffffff; 这超过了ball中的64x64x4可用区域。如果您使用cuda-memcheck运行这段代码,我很肯定您会看到超出界限的索引错误。
似乎您的数组索引应该如下所示:
ball[4 * ((x) * DIAMETER + (y))+0] = (GLubyte) 0xffffff; https://stackoverflow.com/questions/20166520
复制相似问题