Parfor:没有足够的输入参数

时间:2014-08-08 07:43:22

标签: matlab parallel-processing

我在matlab中发现了parfor功能的奇怪行为。看看下面的代码:

function [x,y,z] = parForTest(test3)

x = zeros(100,1);
y = zeros(100,1);
z = zeros(100,1);

test1 = ones(1,100);
test2 = zeros(1,100);
useSameTest2 = false;
if nargin == 1
    test3Given = true;
else
    test3Given = false;
end

parfor s = 1:numel(test1)
    if useSameTest2
        tmpTest = test2(1);
        if test3Given, tmpTest3 = test3(1); end
    else
        tmpTest = test2(s);
        if test3Given, tmpTest3 = test3(s); end
    end
    if test3Given
        [xt, yt, zt] = oneCombi(test1(s), tmpTest, tmpTest3);
    else
        [xt, yt, zt] = oneCombi(test1(s), tmpTest);
    end
    %% store results
    x(s) = xt;
    y(s) = yt;
    z(s) = zt;
end

end

function [xt, yt, zt] = oneCombi(t1, tmpTest, tmpTest3)
if nargin == 3
    xt = 1;
    yt = 1;
    zt = 1;
else
    xt = 0;
    yt = 0;
    zt = 0;
end
end

如果通过输入“[x,y,z] = parForTest();”来调用此函数你会得到一个错误,说没有足够的输入参数。如果用“for”而不是“parfor”来运行整个事情,它就会起作用。当你调用“[x,y,z] = parForTest(ones(100,1))时,它也会起作用;”有人可以解释一下这种行为吗?这似乎与我有一个可选参数这一事实有关。如果我添加“test3 = [];”行在“test3Given = false”之后它也会起作用。

Matlab2014a与并行计算工具箱。

1 个答案:

答案 0 :(得分:4)

您正在使用可选输入功能。我注意到,即使函数声明为F(),matlab有时也允许调用类型function result = F(x, y)。如果在执行期间未使用变量xy,则允许此调用。我知道这很奇怪。

现在,您的问题与您使用并行计算工具箱的事实有关。使用parfor时,Matlab对parfor-loop中使用的变量更加严格,这就是为什么它与for-loop一起使用而不是parfor。 Matlab需要确保所有工作人员都能获得正确的信息,正确切片并正确定义(无论执行路径如何)。

要解决您的问题,您需要将输入参数定义为varargin,然后使用nargin对不同的输入进行操作。您需要按如下方式修改函数(无论您将其称为parForTest()还是parForTest(无论如何),请查看变量test3如何始终定义:

function [x,y,z] = parForTest(varargin)

x = zeros(100,1);
y = zeros(100,1);
z = zeros(100,1);

test1 = ones(1,100);
test2 = zeros(1,100);
useSameTest2 = false;

if nargin == 1
    test3Given = true;
    test3 = varargin{1};
else
    test3Given = false;
    test3 = [];
end

parfor s = 1:numel(test1)
    if useSameTest2
        tmpTest = test2(1);
        if test3Given, tmpTest3 = test3(1); end
    else
        tmpTest = test2(s);
        if test3Given, tmpTest3 = test3(s); end
    end
    if test3Given
        [xt, yt, zt] = oneCombi(test1(s), tmpTest, tmpTest3);
    else
        [xt, yt, zt] = oneCombi(test1(s), tmpTest);
    end
    % store results
    x(s) = xt;
    y(s) = yt;
    z(s) = zt;
end