在具有 GPU 加速的 arrayfun 中使用匿名函数 (Matlab)

Posted

技术标签:

【中文标题】在具有 GPU 加速的 arrayfun 中使用匿名函数 (Matlab)【英文标题】:Usage of anonymous functions in arrayfun with GPU acceleration (Matlab) 【发布时间】:2012-10-25 13:10:04 【问题描述】:

我是 Matlab R2012b 的 Parallel 工具箱的新手,想知道解决以下问题的最佳方法是什么。

我正在分析图像中每个像素的邻域。这是并行化的绝佳案例。但是,我似乎无法让它工作。

问题的主要问题是应该将一些“常量”参数传递给函数。因此,应该为每个像素调用该函数,但是,它还需要访问周围的像素。 (最好将图像作为某种常量参数和要分析的像素坐标传递)。

输出是每个像素一个值。

目前我有这个:

z2 = arrayfun(@(x) analyze(x, image, const1, ...), gpuArray(1:m*n));

其中 x 是虚拟变量,图像是包含图像亮度值的 2D 矩阵,const1(和其他)是函数常数(例如分析窗口的大小)。 m 和 n 是图像的尺寸大小。

但是,我得到了这个错误

使用 gpuArray/arrayfun 时出错 不支持使用功能性工作区。

有什么想法吗?

干杯, 鲁本

【问题讨论】:

你能把analyze的代码贴出来吗? 消息“不支持使用功能工作区”让我怀疑您无法在对 arrayfun 的调用中创建 workspace 变量。我尝试在本地对此进行测试,但可惜我的视频卡太旧且不受支持。 @slayton 感谢您的努力!我不在家 atm,analyze 函数就是一个例子,因为真正的代码非常复杂(尽管它仅存在于算术中)。但是,有效的简化是“计算每个像素及其周围像素的平均值。剩下的我可以算出来。我会尽快发布一些参考代码。 @slayton 不同的方法(例如不使用匿名函数)也非常感谢 实际上我怀疑匿名函数可能是罪魁祸首,因为它带来了您工作空间的一部分。不过我不能确定,因为我无法在我的机器上执行任何对 gpuArray 的调用。 【参考方案1】:

很遗憾,R2012b 中的 Parallel Computing Toolbox 不支持此功能。 arrayfun 的 gpuArray 版本目前不支持将常量数据绑定到匿名函数句柄。 Arrayfun 参数必须直接传递,并且必须都是标量或相同大小。

如果您可以绑定常量参数,接下来您会发现当前无法对它们进行索引(或对它们执行任何非标量操作)。

也许您可以使用支持的例程(例如 CONV2 或 FILTER2)来构建您的算法。

【讨论】:

感谢您的回答。我想你可能是对的。但是,我不会选择此作为正确答案,希望有人可以为我提供解决方法或其他东西。 恐怕您目前所能期望的最好的可能是使用 MATLAB 的 CUDAKernel 功能(除非您可以将所需的所有数据作为标量传递)。【参考方案2】:

这是一篇很老的帖子,但由于我一直在努力解决类似的问题,所以我想分享一下我对此的发现:

如果您将arrayfun 的调用放在一个函数中,您也许可以将analyze 函数实现为可以访问您的常量数组的嵌套函数。但是,这可能需要在重写代码时付出相当大的努力,因为在嵌套的 analyze 函数中,您不能将任何完整数组传递给任何其他函数,这意味着您必须以仅使用单个索引数组条目的方式重写所有内容你的常量数组,例如在数组上的 for 循环中。因此,所有像size 等函数的调用都不起作用,应该移到analyze 之外(至少我正在使用的Matlab2015b 是这种情况)。 这是如何完成的示例(不是我的):

https://devblogs.nvidia.com/high-performance-matlab-gpu-acceleration/

最好的,

汉斯-马丁

【讨论】:

以上是关于在具有 GPU 加速的 arrayfun 中使用匿名函数 (Matlab)的主要内容,如果未能解决你的问题,请参考以下文章

具有不同维度输入的函数的arrayfun

gpu、旧硬件、3d 加速和一个库

高性能几何多重网格与 GPU 加速

torch中topk()无法gpu加速

编写一次并行数组 Haskell 表达式,在 CPU 和 GPU 上运行 repa 并加速

matlab如何gpu加速