如何为GpuMat编写内核?

时间:2017-04-27 16:57:00

标签: c++ opencv cuda

我正在尝试使用以下代码迭代cv :: cuda :: GpuMat:

__global__ void kernel(uchar* src, int rows, int cols, size_t step)
{
    int rowInd = blockIdx.y * blockDim.y + threadIdx.y;
    int colInd = blockIdx.x * blockDim.x + threadIdx.x;

    if ((rowInd < rows) && (colInd < cols))
    {
        uchar * rowptr = src + (rowInd * step);
        rowptr[colInd] = 255;
    }

}

void invoke_kernel(cv::cuda::GpuMat _img)
{
    dim3 tpb(50, 50);
    dim3 bpg(((_img.cols + 49) / 50), ((_img.rows + 49)/ 50));
    kernel<<<bpg, tpb>>> (_img.data, _img.rows, _img.cols, _img.step);

}

int main()
{


    cv::cuda::GpuMat mat;
    mat.create(cv::Size(500, 500), CV_8UC1);
    std::cout << mat.rows << " " << mat.cols << std::endl;
    invoke_kernel(mat);

    cv::Mat img;
    mat.download(img);

    cv::namedWindow("test");
    cv::imshow("test", img);
    cv::waitKey(0);

    return 0;
}

正如您所看到的,它只是应该将内核中的整个(原始黑色)图像设置为白色。

除了第一列之外,图像保持黑色,即白色。感觉就像我在某处做了一些非常愚蠢的事情,但我无法弄清楚:/

我检查了内核是否运行了正确的dimnensions(10x10块,每块50x50个线程)。当我尝试使用NVIDIA调试器时,会出现另一个问题。经过一些谷歌搜索后,我发现NVCC编译器似乎在优化过程中删除了我的rowInd和colInd变量,因此调试器不会显示它们的值。

感谢您的时间。

1 个答案:

答案 0 :(得分:1)

嗯,事实证明,问题是块大小50x50 = 2500有点太多了。有一些限制,我还没想到,但是,正如CUDA文档中所述,16x16很好。

所以,只是为了澄清:

dim3 tpb(16, 16);
dim3 bpg(((_img.cols + 15) / 16), ((_img.rows + 15)/ 16));
invoke_kernel中的

完成了这项工作。

始终阅读文档,孩子们。