Octave并行包:用户自定义函数调用问题
Octave parallel package: User-defined function call issues
我无法使用 pararrayfun 调用用户定义的函数(对于 parcellfun 也是如此)。当我执行以下代码时:
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, @(x,y) x*y, vector_x, 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 (also see the latest release news) 引入了一些限制,这可能与此处发生的事情有关。
说到这里,我想澄清一下这句话:
the call to the user-defined funtion does not seem to work, whereas the same as an anonymous function is working.
事实并非如此。在这两种情况下,您都传递了一个匿名函数。只是第一次在里面调用了mul,第二次调用了mtimes。
至于你的错误(错误?),这可能与 mul 是一个 'command-line' 函数有关。从文档中不清楚命令行功能是否是一个限制,这只是文档中的疏忽,或者对命令行功能的虐待是否是一个真正的错误。我想如果你把它放在自己的文件中它应该可以正常工作。 (同样,如果你这样做,值得直接将其作为句柄传递,而不是将其包装在另一个匿名函数中)。
话虽如此,我认为您看到的 -1 基本上是 pararrayfun 内部的“错误 returns”。原因如下:如果不是将 mul 创建为命令行函数,而是将其设为匿名函数:
mul = @(x,y) x * y
观察下面三个调用的内容return:
x = pararrayfun( nproc, @(x,y) mul(x,y), vector_x, vector_y ) # now it works as expected.
x = pararrayfun( nproc, mul, vector_x, vector_y ) # same: mul is a valid handle expecting two inputs
x = pararrayfun( nproc, @mul, vector_x, vector_y ) # x=-1,-1,-1,-1,-1,-1,-1,-1
如果您尝试过使用普通数组 fun 的最后一个命令,您会看到一个错误,该错误与您不小心传递了 @mul 而不是 mul 相关,而 mul 是一个正确的句柄。在 pararrayfun 中,它只是进行计算,并且大概 -1 是来自内部错误的 return 值。
我不知道为什么命令行函数会失败,但大概与 pararrayfun 在后台创建单独的八度实例有关,它需要访问所有函数定义,也许还有命令-line 函数不能像在父实例中那样容易地在新实例中传输/编译,因为它们在当前会话中创建/编译的方式。
无论如何,我认为如果您创建一个外部函数或(如果处理的函数足够简单)一个匿名函数的句柄而不是命令行函数定义,您将解决您的问题。
但是,我仍然会向 octave bug tracker 提交错误以帮助项目:)
我无法使用 pararrayfun 调用用户定义的函数(对于 parcellfun 也是如此)。当我执行以下代码时:
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, @(x,y) x*y, vector_x, 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 (also see the latest release news) 引入了一些限制,这可能与此处发生的事情有关。
说到这里,我想澄清一下这句话:
the call to the user-defined funtion does not seem to work, whereas the same as an anonymous function is working.
事实并非如此。在这两种情况下,您都传递了一个匿名函数。只是第一次在里面调用了mul,第二次调用了mtimes。
至于你的错误(错误?),这可能与 mul 是一个 'command-line' 函数有关。从文档中不清楚命令行功能是否是一个限制,这只是文档中的疏忽,或者对命令行功能的虐待是否是一个真正的错误。我想如果你把它放在自己的文件中它应该可以正常工作。 (同样,如果你这样做,值得直接将其作为句柄传递,而不是将其包装在另一个匿名函数中)。
话虽如此,我认为您看到的 -1 基本上是 pararrayfun 内部的“错误 returns”。原因如下:如果不是将 mul 创建为命令行函数,而是将其设为匿名函数:
mul = @(x,y) x * y
观察下面三个调用的内容return:
x = pararrayfun( nproc, @(x,y) mul(x,y), vector_x, vector_y ) # now it works as expected.
x = pararrayfun( nproc, mul, vector_x, vector_y ) # same: mul is a valid handle expecting two inputs
x = pararrayfun( nproc, @mul, vector_x, vector_y ) # x=-1,-1,-1,-1,-1,-1,-1,-1
如果您尝试过使用普通数组 fun 的最后一个命令,您会看到一个错误,该错误与您不小心传递了 @mul 而不是 mul 相关,而 mul 是一个正确的句柄。在 pararrayfun 中,它只是进行计算,并且大概 -1 是来自内部错误的 return 值。
我不知道为什么命令行函数会失败,但大概与 pararrayfun 在后台创建单独的八度实例有关,它需要访问所有函数定义,也许还有命令-line 函数不能像在父实例中那样容易地在新实例中传输/编译,因为它们在当前会话中创建/编译的方式。
无论如何,我认为如果您创建一个外部函数或(如果处理的函数足够简单)一个匿名函数的句柄而不是命令行函数定义,您将解决您的问题。
但是,我仍然会向 octave bug tracker 提交错误以帮助项目:)