Image processing CUDA:无法计算网格大小
我正在写一个程序将rgba图像转换成灰度。我在这方面做了很多工作,并且正确地实现了内核。然而,网格大小可能是错误的,即使按照我的逻辑它是正确的 内核: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
__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,对不起。