Image processing CUDA:无法计算网格大小

Image processing CUDA:无法计算网格大小,image-processing,cuda,gpu,Image Processing,Cuda,Gpu,我正在写一个程序将rgba图像转换成灰度。我在这方面做了很多工作,并且正确地实现了内核。然而,网格大小可能是错误的,即使按照我的逻辑它是正确的 内核: __global__ void rgba_to_greyscale(const uchar4* const rgbaImage, unsigned char* const greyImage, int numRows, int numCols) { int

我正在写一个程序将rgba图像转换成灰度。我在这方面做了很多工作,并且正确地实现了内核。然而,网格大小可能是错误的,即使按照我的逻辑它是正确的

内核:

__global__
void rgba_to_greyscale(const uchar4* const rgbaImage,
                   unsigned char* const greyImage,
                   int numRows, int numCols)
{   
    int x = (blockIdx.x * blockDim.x) + threadIdx.x;
    int y = (blockIdx.y * blockDim.y) + threadIdx.y;

    if(x >= numCols || y >= numRows)
        return;

    uchar4 rgba = rgbaImage[x+y];
    float channelSum = 0.299f*rgba.x + 0.587f*rgba.y + 0.114f*rgba.z;

    greyImage[x+y] = channelSum;
}
内核发布:

const dim3 blockSize(10, 10, 1);  //TODO
  size_t gridSizeX, gridSizeY;
  gridSizeX = numCols + (10 - (numCols % 10) );  //adding some number to make it multiple of 10
  gridSizeY = numRows + (10 - (numRows % 10) );  //adding some number to make it multiple of 10

  const dim3 gridSize( gridSizeX, gridSizeY, 1);  //TODO
  rgba_to_greyscale<<<gridSize, blockSize>>>(d_rgbaImage, d_greyImage, numRows, numCols);
constdim3块大小(10,10,1)//待办事项
大小\u t gridSizeX,gridSizeY;
gridSizeX=numCols+(10-(numCols%10))//添加一些数字使其成为10的倍数
gridSizeY=numRows+(10-(numRows%10))//添加一些数字使其成为10的倍数
常量dim3 gridSize(gridSizeX,gridSizeY,1)//待办事项
rgba_至_灰度(d_rgbaImage、d_greyImage、numRows、numCols);

我正在创建更多的线程,然后在内核中应用绑定检查。

您正在使用
x+y
访问映像。但是想想看,这种方法可以得到的最大图像大小是
numRows+numCols
。您不能只添加这两个坐标,因为这意味着例如
(1,2)
是与
(3,0)
相同的图像元素,这是纯粹的垃圾。相反,对于每个y坐标,您必须跳过图像的整行,因此它应该是
rgbaImage[x+y*numCols]
(当然,对于
greyImage
,也是如此)。但是请注意,取决于图像数据的布局,它也可能是另一种方式(
x*numRows+y
),但我在这里假设通常的图像布局(在内核中,这并不重要,因为所有像素都被同等对待)。

您使用
x+y
访问图像。但是想想看,这种方法可以得到的最大图像大小是
numRows+numCols
。您不能只添加这两个坐标,因为这意味着例如
(1,2)
是与
(3,0)
相同的图像元素,这是纯粹的垃圾。相反,对于每个y坐标,您必须跳过图像的整行,因此它应该是
rgbaImage[x+y*numCols]
(当然,对于
greyImage
,也是如此)。但是请注意,根据图像数据的布局,也可能是另一种方式(
x*numRows+y
),但我在这里假设的是通常的图像布局(在内核中,这并不重要,因为所有像素都被同等对待).

这是一种广泛使用的逻辑,用于在内核中创建更多的线程并执行绑定检查。下面是计算网格大小的通用公式<代码>网格大小=(numCols+blockSize.x-1)/blockSize.x的可能重复项。我认为这是udacity课程的标准问题。@SagarMasuti;我也读过那篇文章,但我不知道我的代码有什么问题。如果您能在我的(逻辑正确的)代码中指出错误,这将非常有帮助;gridSizeY=(numRows+blockSize.y-1)/blockSize.y;常量dim3 gridSize(gridSizeX,gridSizeY,1);它只是从顶部转换一条非常细的像素带。有人能验证内核本身是否正确吗?这是一种广泛使用的逻辑,用于在内核内创建更多的线程并执行绑定检查。下面是计算网格大小的通用公式<代码>网格大小=(numCols+blockSize.x-1)/blockSize.x的可能重复项。我认为这是udacity课程的标准问题。@SagarMasuti;我也读过那篇文章,但我不知道我的代码有什么问题。如果您能在我的(逻辑正确的)代码中指出错误,这将非常有帮助;gridSizeY=(numRows+blockSize.y-1)/blockSize.y;常量dim3 gridSize(gridSizeX,gridSizeY,1);它只是从顶部转换一条非常细的像素带。有人能验证内核本身是否正确吗?谢谢。也许我被存储在一维数组中的图像弄糊涂了。它就像在2D数组中计算单元的内存地址一样。我相信调试器和本机CUDA环境的可用性会有所帮助。顺便说一句,你知道Windows中的CUDA emalation环境吗?或者可以指向一些gpuocelot for Windows的文档?@HarshilSharma不,对不起。谢谢。也许我被存储在一维数组中的图像弄糊涂了。它就像在2D数组中计算单元的内存地址一样。我相信调试器和本机CUDA环境的可用性会有所帮助。顺便问一下,您是否了解Windows中的CUDA emalation环境,或者可以指向一些gpuocelot for Windows的文档?@HarshilSharma No,对不起。