【问题标题】:Using parfor with options to parallelize code使用带有选项的 parfor 来并行化代码
【发布时间】:2021-01-29 02:20:25
【问题描述】:

我有以下 MATLAB 代码:

n_part = 5; %count the participants
options.params.cutoff=1;
options.params.lags=0;% use zero, to set n=0 as in eq 4 in the paper, otherwise you will include historical values in the model (one connectivity matrix per historical value) 
options.params.autocorrelation=0; % to exclude self dependancies, since we have already take care of this. This makes the diagonal values equal to zero in the model
options.params.concurrent=1; % must be one to include the concurrent information
options.params.pass_th=0;
options.perc=[0.7 0.3]; % First argument is the partition size to calculate SV, second argument is the size of the test sample
options.rep_svd=10; % how many times to repeat the svd decomposition to maximize out of sample data predictions
options.rep_model=1; % if number of frames not empty, how many times recalculate the model based on the minimum required frames

parfor i=1:n_part
    display(['Running participant ' num2str(i)])
    options.min_frames=size(signal,1); %how many frames to include in the model
    options.SV=SV; %assign SV to options
end

我想优化for 循环,因为每次迭代都是独立的。所以,首先,我尝试了这个:

parfor i=1:n_part
    .
    .
    .
end

这给了我这个错误:

Error: The variable options in a parfor cannot be classified.

错误发生在这一行:

parfor i=1:n_part

然后我尝试了这个:

parpool(2);
parfor i=1:n_part
    display(['Running participant ' num2str(i)])
    y=TC{i};
    TC_no_AC_LS{i}=remove_autocorrelation(y,n_ar);
    
    frameSV(i).signal=TC_no_AC_LS{i}; % pick the signal with no autocorrelation
    [SV, R]=model_tsvd(signal,options); %calculate the SVD
    
    frameSV(i).min_frames = size(frameSV(i).signal, 1);
    frameSV(i).SV = SV;
end

for i = 1 : n_part
    options.min_frames= frameSV(i).min_frames; %how many frames to include in the model
    options.SV = frameSV(i).SV; %assign SV to options
    signal = frameSV(i).signal;
    m(:,:,i) = make_model_tsvd(signal, options); % calculate the model
end

但是得到了这个错误:

Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 2).
Error using connectotyping_example2>(parfor supply)
Undefined function 'frameSV' for input arguments of type 'double'.

Error in connectotyping_example2 (line 27)
parfor i=1:n_part

有没有办法解决这个问题,所以循环的迭代可以并行运行?

【问题讨论】:

  • 它在哪一行抛出该错误?您能否发一个minimal reproducible example,即我们可以运行的代码?您似乎正在使用嵌套在单元格中的单元格和/或在循环中增长数组。前者可能是parfor 的问题,后者肯定是。您可能还想查看spmd,这在某些情况下更容易。
  • 它出现在parfor i=1:n_part 行。
  • 我做了一个简短的独立示例。

标签: matlab parfor


【解决方案1】:

问题在于以下两行:

options.min_frames=size(signal,1); %how many frames to include in the model
options.SV=SV; %assign SV to options

Parfor 循环必须确保每次循环迭代都独立于下一次。在上面的代码中,看起来options 在每次迭代中都会更新,然后在下一次迭代中使用更新后的结构。这不能使用 parfor 完成,因为 技术上 不能保证迭代 ii+1 将在同一台机器上完成。

如果 min_framesSV 不需要成为选项结构的一部分,您可以在每次迭代中以与数据无关的方式存储它们的值:

parfor i=1:n_part
    % ...
    frameSV(i).min_frames = size(signal,1);
    frameSV(i).SV = SV;
end
% Do some calculation with frameSV to get the data you need, after the loop

这将创建一个 1 x n_part 结构数组,其中独立存储来自每个循环迭代的 min_framesSV 的值。

同样,这一切都假设options 的值不需要在一次迭代中更新并​​在下一次迭代中使用。

【讨论】:

  • frameSV 是如何声明的,在哪里声明的?
  • 在循环中创建,在循环后存在。例如,在命令窗口中尝试输入:>> someVar(1).SV = 1,它将创建一个变量someVar,其中包含字段 SV。下一次迭代someVar(2).SV = 2 将第二个元素添加到结构数组中。
  • 我尝试按照我的理解执行您的建议。我克服了最初的错误,但仍然出现错误。我用该代码和错误消息更新了问题。
  • 小提示:你不能在 parfor 循环中“增长”数组,即你需要将结构 frameSV 初始化为适当的大小。
猜你喜欢
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 2013-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多