2013-07-19 29 views
0

我正在编写一个程序将rgba图像转换为灰度。我在这方面做了很多工作,并正确地实现了内核。然而,网格大小可能是错误的,即使它的逻​​辑是正确的。CUDA:无法计算网格大小

内核:

__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); 

我创建多个线程则需要数,然后应用在内核绑定检查。

+2

这是一个广泛使用的逻辑,用于创建更多数量的线程并在内核中执行绑定检查。这是计算网格大小的通用公式。 'gridSizeX =(numCols + blockSize.x - 1)/blockSize.x;' – sgarizvi

+0

[this]的可能重复(http://stackoverflow.com/questions/14711668/colored-image-to-greyscale-image-using- cuda并行处理)。我认为它的标准问题来自udacity当然.. –

+0

@SagarMasuti;我也读过这篇文章,但是我无法弄清楚我的代码中出现了什么问题。如果您可以将错误指向我的(逻辑上正确的)代码,这将会很有帮助。 –

回答

4

您正在访问您的图片使用x+y。但想想这个,你能以这种方式获得的最大图像尺寸是numRows+numCols。你不能只添加这两个坐标,因为那意味着例如(1,2)(3,0)是一样的图像元素,它是普通的垃圾。相反,对于每个y坐标,您必须跳过整行图像,因此它应该是rgbaImage[x+y*numCols](当然,greyImage也是如此)。但请注意,根据图像数据的布局,它可能也是其他方式(x*numRows+y),但我在此假设通常的图像布局(并且在您的内核中它无所谓,因为所有像素都是平等对待)。

+0

谢谢你。也许我被存储在一维数组中的图像弄糊涂了。它就像计算二维数组中单元的内存地址一样。我确定调试器和本地CUDA环境的可用性可能有所帮助。顺便说一句,你知道Windows中的CUDA emalation环境,或者可以指向gpuocelot for Windows的一些文档吗? –

+0

@HarshilSharma不,对不起。 –