【发布时间】:2012-01-08 16:53:44
【问题描述】:
我正在使用 CUDA 对图像进行线性过滤。我使用 2D 线程块和 2D 网格来使问题自然。以下是我的索引方式:(height 和 width 是图像尺寸)
dim3 BlockDim(16,16);
dim3 GridDim;
GridDim.x = (width + 15) / 16;
GridDim.y = (height + 15) / 16;
在内核中,我访问的位置如下:
unsigned int xIndex = blockIdx.x*16+ threadIdx.x;
unsigned int yIndex = blockIdx.y*16+ threadIdx.y;
unsigned int tid = yIndex * width + xIndex;
我想返回四个边界(稍后我会满足它们)。我这样做是:
if(yIndex>=height-N || xIndex>=width-N || yIndex<N || xIndex<N)
return;
其中 N 是我不想计算的每个边界处的像素数。
问题:
代码在所有标准图像尺寸上都能正常运行。但是对于某些随机图像尺寸,它会显示对角线。例如,在我的情况下,500x333 图像(即使没有维度是 16 的倍数)显示正确的输出,而 450x365 显示输出中的对角线。即使我只返回网格的额外线程而没有其他类似的东西,问题仍然存在:
if(yIndex>=height || xIndex>=width)
return;
代码保持不变,一些输入运行良好,而另一些则不然。任何人都可以发现错误吗?我已在此处附上输入和输出示例:IMAGES 谢谢!
更新:
内核代码(简化为返回输入图像,但同样的问题)
__global__ void filter_8u_c1_kernel(unsigned char* in, unsigned char* out, int width, int height, float* filter, int fSize)
{
unsigned int xIndex = blockIdx.x*BLOCK_SIZE + threadIdx.x;
unsigned int yIndex = blockIdx.y*BLOCK_SIZE + threadIdx.y;
unsigned int tid = yIndex * width + xIndex;
unsigned int N = filterSize/2;
if(yIndex>=height-N || xIndex>=width-N || yIndex<N || xIndex<N)
return;
/*Filter code removed, still gives the same problem*/
out[tid] = in[tid];
}
更新 2:
我还通过反转 if 条件删除了 return 语句。但问题依然存在。
if(yIndex<=height-N && xIndex<=width-N && yIndex>N && xIndex>N){
/*Kernel Code*/
}
【问题讨论】:
-
如果没有看到代码,将很难回答,但我会非常怀疑ever 在内核中使用 return 语句。如果代码中存在内存或指令同步障碍,那么很可能是返回语句本身导致了问题。
-
我已经在更新中添加了代码。和我之前说的差不多。
-
您能否将您正在使用的内核参数和启动参数添加到失败的案例中?
filterSize目前也未定义,应该是fSize? -
我已经在问题中提到了启动参数。 filterSize 可以是任何值,例如 3,5,7,9 .. 它有助于计算 N,它设置边界处的偏移像素。实际上,如果我将 N 硬编码为任何值,它没有任何区别。在这种配置下,我只复制输入图像以输出所有标准尺寸的作品,还有一些其他的,但图像尺寸很少,例如 450x364,它会给出错误的输出。请看附件。
标签: cuda