CUDA盒过滤器索引错误

CUDA盒过滤器索引错误,cuda,filtering,Cuda,Filtering,我编写了一个简单的CUDA内核,用于图像的框过滤 texture<unsigned char,2> tex8u; #define FILTER_SIZE 7 #define FILTER_OFFSET (FILTER_SIZE/2) __global__ void box_filter_8u_c1(unsigned char* out, int width, int height, int pitch) { unsigned int x = blockIdx.x * blo

我编写了一个简单的CUDA内核,用于图像的框过滤

texture<unsigned char,2> tex8u;

#define FILTER_SIZE 7
#define FILTER_OFFSET (FILTER_SIZE/2)

__global__ void box_filter_8u_c1(unsigned char* out, int width, int height, int pitch)
{
   unsigned int x = blockIdx.x * blockDim.x + threadIdx.x;
   unsigned int y = blockIdx.y * blockDim.y + threadIdx.y;

   if(x>=width || y>=height)    return;

   float val = 0.0f;

   for(int i = -FILTER_OFFSET; i<= FILTER_OFFSET; i++)
     for(int j= -FILTER_OFFSET; j<= FILTER_OFFSET; j++)
        val += tex2D(tex8u,x + i, y + j);

   out[y * pitch + x] = static_cast<unsigned char>(val/(FILTER_SIZE  * FILTER_SIZE));   

}
纹理tex8u;
#定义过滤器大小7
#定义过滤器偏移量(过滤器大小/2)
__全局\uuuuu无效框\u过滤器\u8u\uC1(无符号字符*输出、整数宽度、整数高度、整数间距)
{
无符号整数x=blockIdx.x*blockDim.x+threadIdx.x;
无符号整数y=blockIdx.y*blockDim.y+threadIdx.y;
如果(x>=宽度| y>=高度)返回;
浮动值=0.0f;

对于(int i=-FILTER_OFFSET;i而言,其根本原因与CUDA无关,是基本的C类型转换规则导致了您看到的结果。C99标准说明了转换的执行方式:

6.3.1.8常用算术转换

  • 如果两个操作数的类型相同,则无需进一步转换
  • 否则,如果两个操作数都具有有符号整数类型或都具有无符号整数类型,则类型为较小整数的操作数 转换秩被转换为具有更大值的操作数类型 等级
  • 否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数类型的秩,则 带符号整数类型的操作数转换为 无符号整数类型的操作数
  • 否则,如果具有有符号整数类型的操作数的类型可以表示具有无符号整数类型的操作数类型的所有值 整数类型,则转换具有无符号整数类型的操作数 到带符号整数类型的操作数的类型
  • 否则,两个操作数都将转换为与有符号整数类型的操作数类型相对应的无符号整数类型
  • 第三点意味着有符号整数(在本例中是i和j)首先被转换成无符号整数,然后被添加到无符号整数(
    x
    y
    )。将负有符号整数转换为无符号整数的结果是特定于实现的,但在这里,简单的2的补码表示将把小的负整数转换为非常大的无符号整数。纹理的读取模式将此超出范围的坐标钳制到纹理中允许的最大值,并且r内核最终从纹理的错误一侧读取


    如果你使用有符号整数,就不会发生转换,整个问题就消失了。这个故事的寓意可能是“了解你的编程语言”。

    哇。回答得好。谢谢。我真的应该阅读语言标准。