【问题标题】:Getting the imageDenoising CUDA example to work using a MATLAB CUDAKernel使用 MATLAB CUDAKernel 让 imageDenoising CUDA 示例工作
【发布时间】:2015-03-16 23:37:43
【问题描述】:

TL;DR

我正在寻找一种方法来提取现有 CUDA 工具包示例的一部分并将其转换为 MATLAB 中的 CUDAKernel 可执行文件。

故事

为了获得非局部均值 (NLM) 2D 过滤器的短运行时实现,我偶然发现了 imageDenoising example provided with the CUDA Toolkit,它实现了该过滤器的两个变体,称为 NLM 和 NLM2(或“快速 NLM” )。

之前没有 CUDA 编码经验,我最初尝试关注 MATLAB's documentation on the subject,结果导致了几个奇怪的错误,包括:ptx compilationmultiple entry pointswrong number of inputs in the C prototype。在这一点上,我意识到这不会是一个“正常工作”的案例,需要进行一些修补。

所以我决定通过简单地删除imageDenoising.cu文件的一部分并将相关的.cuh..._nlm_kernel.cuh..._nlm2_kernel.cuh)合并到.cu中来消除多入口点问题,以便获得单个在任何给定时间的入口点。 令我惊讶的是,这实际上成功地编译了,我终于能够创建一个CUDAKernel而没有错误(使用命令k = parallel.gpu.CUDAKernel('imageDenoising.ptx', 'uint8_T *, int, int, float, float');)。

但这还不够,因为我错误地认为第一个参数是 RGB 矩阵形式的未处理图像(即 X*Y*3 uint8),所以我得到的结果正是输入,但在第 4 个元素中有 0

在进行了更多搜索后,我意识到在这样的转换过程中还有一些我完全不知道的其他关键方面(例如 the need to initialize __device__ variables),在这个阶段我决定寻求帮助。

问题

我目前想知道如何有效地从这里继续。虽然我很想知道这种方法是否通常能取得成果(以及这个过程的完整示例是否在某处可用),但我应该注意哪些其他陷阱,以及我可以采取哪些替代行动方案(考虑我在 CUDA 方面的知识非常有限,而且我不会雇用其他人为我做这件事),我记住这是如此,所以我必须有一个 特定的编程问题,所以这里是:

如何修改imageDenoising.cu 以使从中构造的MATLAB CUDAKernel 也接受未处理的图像作为输入?

注意:在我的应用程序中,输入矩阵是一个二维、灰度、double 矩阵。

相关: How CudaMalloc work?

附言

一段工作代码显然会受到欢迎,但我真的更愿意“学会钓鱼”。

【问题讨论】:

    标签: matlab image-processing cuda filtering gpgpu


    【解决方案1】:

    我最终采用了另一种 CUDAKernel 方法,使用 .MEX,通过执行以下操作:

    1. 设置外部库 OpenCV v2.4.10不是 v3!)和 mexopencv
    2. 使用guidelines of mexopencv for unimplemented functionsOpenCV's fastNlMeansDenoising 编写一个小型包装函数,如下所示(不包括文档):

    #include "mexopencv.hpp"
    using namespace cv;
    
    void mexFunction(int nlhs, mxArray *plhs[],
                     int nrhs, const mxArray *prhs[])
    {
        // Check arguments
        if (nlhs != 1 || nrhs<1 || ((nrhs % 2) != 1) )
            mexErrMsgIdAndTxt("fastNLM:invalidArgs", "Wrong number of arguments");
    
        // Argument vector  
        vector<MxArray> rhs(prhs, prhs + nrhs);
    
        // Option processing
          // Defaults:
        double h = 3;
        int templateWindowSize = 7;
        int searchWindowSize = 21;
          // Parsing input name-value pairs:
        for (int i = 1; i<nrhs; i += 2) {
            string key = rhs[i].toString();
            if (key == "h")
                h = rhs[i + 1].toDouble();
            else if (key == "templateWindowSize")
                templateWindowSize = rhs[i + 1].toInt();
            else if (key == "searchWindowSize")
                searchWindowSize = rhs[i + 1].toInt();
            else
                mexErrMsgIdAndTxt("mexopencv:error", "Unrecognized option");
        }
    
        // Process
        Mat src(rhs[0].toMat()), dst;
        fastNlMeansDenoising(src, dst, h, templateWindowSize, searchWindowSize);
    
        // Convert cv::Mat back to mxArray*
        plhs[0] = MxArray(dst);
    }
    
    1. 正在编译它.....和 ​​viola - 一个有效的 CUDA 加速 NLM 过滤器。

    通过比较opencv\sources\modules\photo\src\cuda\nlm.cu(这是opencv2 路径)与imageDenoising_nlm2_kernel.cuh,可以找到我的问题本身的答案。

    这个解决方案对我来说效果很好,因为让 NLM 过滤器运行对我来说比使用 CUDAKernel 更重要。

    我从中学到的主要教训(我想传授给其他人)是:

    在 MATLAB 中运行 CUDA 代码也可以通过 CUDAKernel 以外的方式完成,例如使用 .mex 包装器,如上所示。

    【讨论】:

      猜你喜欢
      • 2013-10-21
      • 1970-01-01
      • 2018-05-22
      • 2020-12-10
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 2011-06-08
      • 2023-04-11
      相关资源
      最近更新 更多