parallel-processing - 如何将多个参数传递给 Octave 中的并行操作?
问题描述
我编写了一个函数,作用于输入矩阵中的每个列组合。它使用多个 for 循环并且非常慢,所以我试图将它并行化以使用我计算机上的最大线程数。
我很难找到正确的语法来设置它。我正在使用倍频程的 Parallel 包,并尝试了几种方法来设置调用。以下是其中两个,以简化的形式,以及我认为有效的非并行版本:
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 不支持)
在这一点上我没有想法,可以使用帮助来弄清楚如何让它发挥作用。
解决方案
将我上面的评论转换为答案。
在执行并行操作时,将每个并行工作程序视为独立且独立的 octave 实例是很有用的,这些实例需要对它们需要的所有函数和变量具有适当的访问权限才能完成它们的独立工作。
因此,从主函数调用时不要依赖子函数parcellfun
,因为如果工作人员无法直接访问子函数,这可能会导致错误。
在这种情况下,将子函数分成自己的文件可以解决问题。
推荐阅读
- spring - Spring MVC 项目结构
- android - 当我滑动时,我的应用程序正在调用所有 TabBarView 内容
- pandas - 对整个 panda 数据框而不是系列进行切片会导致数据类型发生变化,并将第一个字段的值分配给 NaN,发生了什么?
- r - dfSummary() 图形未打印在 HTML 文件中
- algorithm - 使用动态编程和位掩码赢得特殊单淘汰锦标赛的概率
- for-loop - 在 Dart 中的 for 循环之前初始化迭代器
- git - git pull rebase 同时保持远程在顶部
- java - map操作后Stream.forEach为什么没有调用Object的toString?
- node.js - 无法通过 logstash 将 MongoDB 数据同步到 Elasticseach
- python - 绘制 timedelta 单圈时间