如何解决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 举报,一经查实,本站将立刻删除。