微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Octave 并行包:用户定义的函数调用问题

如何解决Octave 并行包:用户定义的函数调用问题

我在使用 pararrayfun 调用用户定义的函数时遇到了麻烦(pararrayfun 也是如此)。当我执行以下代码时:

pkg load parallel

function retval = mul(x,y)
  retval = x*y;
endfunction

vector_x = 1:2^3;
vector_y = 1:2^3;

vector_z = pararrayfun(nproc,@(x,y) mul(x,y),vector_x,vector_y)
vector_z = pararrayfun(nproc,y) x*y,vector_y)

我得到以下输出

vector_z =

  -1  -1  -1  -1  -1  -1  -1  -1

vector_z =

    1    4    9   16   25   36   49   64

也就是说,调用用户自定义函数似乎不起作用,而与匿名函数一样起作用。

机器是 x86_64,带有 Debian bullseye 和 5.10.0-1-amd64 内核。 Octave 的版本是 6.1.1~hg.2020.12.27-1。 pkg list 命令给了我:

Package Name  | Version | Installation directory
--------------+---------+-----------------------
   dataframe  |   1.2.0 | /usr/share/octave/packages/dataframe-1.2.0
    parallel *|   4.0.0 | /usr/share/octave/packages/parallel-4.0.0
      struct *|  1.0.16 | /usr/share/octave/packages/struct-1.0.16

有趣的是,相同的代码在带有 Debian buster 和 4.14.150-odroidxu4 内核的 armv7l 上完美运行。即调用用户定义函数和匿名函数产生输出

parcellfun: 8/8 jobs done
vector_z =

    1    4    9   16   25   36   49   64

parcellfun: 8/8 jobs done
vector_z =

    1    4    9   16   25   36   49   64

在那台机器上,Octave 的版本是 4.4.1,pkg list 给出:

Package Name  | Version | Installation directory
--------------+---------+-----------------------
   dataframe  |   1.2.0 | /usr/share/octave/packages/dataframe-1.2.0
    parallel *|   3.1.3 | /usr/share/octave/packages/parallel-3.1.3
      struct *|  1.0.15 | /usr/share/octave/packages/struct-1.0.15

出了什么问题,我该如何解决这个问题?

解决方法

这可能是一个错误,但请注意,新版本的 parallel 已根据其 documentation(另请参阅最新的 release news)引入了一些限制,这可能与此处发生的情况有关。

说到这里,我想澄清一下这句话:

对用户定义函数的调用似乎不起作用,而与匿名函数一样起作用。

这不是正在发生的事情。在这两种情况下,您都在传递匿名函数。只是第一个在里面调用了mul,第二个调用了mtimes。

至于您的错误(错误?),这可能与 mul 作为“命令行”函数有关。从文档中不清楚命令行功能是否是一个限制,这只是文档中的一个疏忽,或者命令行功能的虐待是否是一个真正的错误。我认为如果你把它放在自己的文件中,它应该可以正常工作。 (同样,如果你这样做,值得直接将它作为句柄传递,而不是将它包装在另一个匿名函数中)。

话虽如此,我认为您看到的 -1 基本上是来自 pararrayfun 内部的“错误返回”。原因如下:如果不是将 mul 创建为命令行函数,而是将其设为匿名函数:

mul = @(x,y) x * y

观察下面三个调用返回的内容:

x = pararrayfun( nproc,@(x,y) mul(x,y),vector_x,vector_y )   # now it works as expected.
x = pararrayfun( nproc,mul,vector_y )   # same: mul is a valid handle expecting two inputs
x = pararrayfun( nproc,@mul,vector_y )  # x=-1,-1,-1

如果您使用普通数组 fun 尝试了最后一个命令,您会看到一个错误,因为当 mul 是正确的句柄时,您不小心传递了 @mul 而不是 mul。在 pararrayfun 中,它只是进行计算,大概 -1 是内部错误的返回值。

我不知道为什么命令行函数会失败,但大概与 pararrayfun 在幕后创建单独的八度音程实例有关,这些实例需要访问所有函数定义,也许还有命令行由于在当前会话中创建/编译函数的方式,函数不能像在父实例中那样容易地在新实例中传输/编译。

无论如何,我认为如果您创建一个外部函数或(如果处理足够简单的函数)匿名函数的句柄,而不是命令行函数定义,那么您将解决您的问题。

但是,我仍然会向 octave bug tracker 提交错误以帮助该项目:)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。