在Matlab中使用匿名函数的arrayfun与GPU加速的用法

3
我是Matlab R2012b中Parallel toolbox的新手,想知道克服以下问题的最佳方法。
我正在分析图像中每个像素的邻域。这是极好的并行化案例。但是,我似乎无法使其工作。
问题的主要难点在于某些“常量”参数应传递给函数。因此,应为每个像素调用该函数,但它还需要访问周围的像素(最好通过将图像作为某种常量参数和要分析的像素的坐标来实现)。
输出是每个像素的一个值。
目前我有这个:
z2 = arrayfun(@(x) analyze(x, image, const1, ...), gpuArray(1:m*n));

其中x是dummy-var,image是包含图像亮度值的2D矩阵,const1(和其他常量)是函数常量(例如分析窗口的大小)。m和n是图像维度的大小。

然而,我遇到了这个错误

Error using gpuArray/arrayfun Use of functional workspace is not supported.

有任何想法吗?

谢谢, Ruben


你能发布“analyze”的代码吗? - slayton
@slayton 谢谢你的努力!我现在不在家,分析函数只是一个例子,因为真正的代码非常复杂(尽管它仅由算术运算组成)。然而,一个有效的简化方法是“计算每个像素及其周围像素的平均值”。我可以想出其余部分。我会尽快发布一些参考代码。 - RVH
@slayton 非常欢迎采用不同的方法(例如不使用匿名函数)。 - RVH
实际上,我怀疑匿名函数可能是罪魁祸首,因为它带来了你工作区的一部分。不过我不能确定,因为我无法在我的机器上执行任何对 gpuArray 的调用。 - slayton
@RobertCrovella 使用的函数包括exp()、mod()、ceil()、.*和inv()以及标准算术运算符。为什么使用这些函数呢? - RVH
显示剩余3条评论
2个回答

2
很遗憾,Parallel Computing Toolbox在R2012b版本中不支持此功能。arrayfun的gpuArray版本目前不支持将常量数据绑定到匿名函数句柄中。必须直接传递arrayfun参数,并且所有参数都必须是标量或相同大小。
如果您可以绑定常量参数,那么您可能会发现您目前无法对它们进行索引(或执行任何非标量操作)。
也许您可以使用支持的例程(如CONV2或FILTER2)构建您的算法。

谢谢你的回答。我认为你可能是对的。然而,我还不会选择这个作为正确答案,希望有人能提供给我一个解决方法或其他东西。 - RVH
很抱歉,目前您最好的选择可能是使用MATLAB的CUDAKernel功能(除非您可以将所有所需的数据作为标量传递)。 - Edric

0

这是一个非常古老的帖子,但由于我也遇到了类似的问题,我想分享一下我对此的发现:

如果你将arrayfun的调用放在一个函数内部,你可能可以将analyze函数实现为一个嵌套函数,该函数可以访问你的常量数组。然而,这可能需要相当大的努力来重写你的代码,因为在嵌套的analyze函数中,你不能将任何完整的数组传递给其他函数,这意味着你必须以一种方式重写所有内容,以便你只使用常量数组的单个索引数组条目,例如在数组的for循环中。因此,所有像size等函数的调用都将无法工作,并且应该移动到analyze之外(至少对于我使用的Matlab2015b而言)。

以下是一个示例,展示了如何实现(不是我的):

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

最好的祝福,

Hans-Martin


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接