如何将多个参数传递给 Octave 中的并行操作?



我编写了一个函数,用于作用于输入矩阵中的每个列组合。它使用多个 for 循环并且非常慢,因此我正在尝试并行化它以使用计算机上的最大线程数。

我很难找到正确的语法来设置它。我正在使用八度的并行包,并尝试了几种方法来设置呼叫。这里有两个简化的形式,以及我认为有效的非并行版本:

function A = parallelExample(M)
pkg load parallel;
# Get total count of columns
ct = columns(M);
# Generate column pairs
I = nchoosek([1:ct],2);
ops = rows(I);
slice = ones(1, ops);
Ic = mat2cell(I, slice, 2);
##  # Non-parallel
##  A = zeros(1, ops);
##  for i = 1:ops
##      A(i) = cmbtest(Ic{i}, M);
##  endfor
# Parallelized call v1
A = parcellfun(nproc, @cmbtest, Ic, {M});
## # Parallelized call v2
## afun = @(x) cmbtest(x, M);
## A = parcellfun(nproc, afun, Ic);
endfunction
# function to apply
function P = cmbtest(indices, matrix)
colset = matrix(:,indices);
product = colset(:,1) .* colset(:,2);
P = sum(product);
endfunction

对于这两个示例,我生成了两列的每个组合,并将这些对转换为 parcellfun 函数应拆分的单元格数组。首先,我尝试将输入矩阵 M 转换为 1x1 单元格数组,以便它以相同的形式进入每个并行实例。我收到错误"C 必须是单元格数组",但这必须是 parcellfun 函数的内部。在第二个中,我尝试定义一个包含矩阵的匿名函数。我在这里得到的错误指定"cmbtest"是未定义的。

(当然,我尝试应用的实际函数比这里的cmbtest复杂得多(

我尝试过的其他事情:

  • 将 M 放入全局变量中,这样就不需要传递它。似乎不可能将全局变量放在函数文件中,尽管我可能只是遇到了语法问题。
  • 使cmbtest成为嵌套函数,以便它可以访问M(parcellfun不支持(

在这一点上,我没有想法,可以使用帮助弄清楚如何使其工作。

将我上面的评论转换为答案。

在执行并行操作时,将每个将生成的并行工作线程视为独立且独立的八度实例很有用,这些实例需要对它们完成独立工作所需的所有函数和变量具有适当的访问权限。

因此,从主函数调用parcellfun时不要依赖子函数,因为如果工作线程无法直接在后台访问子函数,这可能会导致错误。

在这种情况下,将子函数分离到其自己的文件中可以解决问题。

最新更新