在parfor内清除了fitoption?

时间:2017-10-25 12:20:58

标签: matlab parfor

我试图通过使用并行性来加速MATLAB中大量数据的拟合,并且我面临着一个非常奇怪的问题。

我试图找出问题,希望有人可能知道发生了什么。这是示例代码:

f = @(a, x) a*x;
fitopt = fitoptions(f);

for i = 1:5
  disp(fitopt);
end

如果我运行上面的代码,fitopt的内容将按预期写入5次。但是,如果我将for替换为parfor循环,fitopt将设置为空并且不会显示任何内容。

有什么可能出错的线索?

我的配置:Windows 7上的MATLAB 2014a,64位

1 个答案:

答案 0 :(得分:2)

以下内容基于MATLAB版本R2016b ...

据我所知,这似乎是MATLAB能够正确broadcast(或不)某些parfor工人的类对象的问题。 fitoptions函数返回示例中的类curvefit.nlsqoptions的对象。通过Curve Fitting Toolbox代码,可以看到这些对象仍然使用较旧的UDD类系统定义(Donn Shull的一个很好的介绍可以在Undocumented MATLAB上找到)。虽然多年前引入了较新的MCOS(MATLAB类对象系统),但您仍然可以找到使用UDD定义的大量对象。

在您的示例中,fitopt应该broadcast(即复制)给每个工作人员,而fitopt[]内设置为parfor }循环。如果我们尝试使用更新的类系统定义的另一个类对象(如fittype创建的那个),那么广播工作正常。例如,此测试代码:

f = @(a, x) a*x;
uddObj = fitoptions(f);
mcosObj = fittype(f);

parfor i = 1:3
  fprintf('\nWorker %d:\n', i);
  uddObj
  mcosObj
end

生成此输出:

Worker 2:

uddObj =
     []

mcosObj = 
     General model:
     mcosObj(a,x) = a*x

Worker 1:

uddObj =
     []

mcosObj = 
     General model:
     mcosObj(a,x) = a*x

Worker 3:

uddObj =
     []

mcosObj = 
     General model:
     mcosObj(a,x) = a*x

因此,简而言之,parfor循环似乎无法正确地广播UDD样式对象。一种解决方法是在parfor循环中创建这些对象,避免广播:

f = @(a, x) a*x;

parfor i = 1:5
  fitopt = fitoptions(f);  % Function handle f broadcasts just fine
  disp(fitopt);
end

您还可以通过创建索引的对象数组来创建sliced variable

f = @(a, x) a*x;
fitopt = repmat(fitoptions(f), [1 5]);

parfor i = 1:5
  disp(fitopt(i));
end