function with unknown number of outputs within parfor

9 views (last 30 days)
Dear all,
I am facing this apparently simple problem: I am trying to write a parfor loop that containts a function call with an unknown number of output arguments. The way I tried to implement it is as follows
Tank=initialize_tank();
parfor ii=1:n
[outputs{:}]=myfunction(a,b,c,d);
Tank(:,ii)=outputs(:);
end
But due to the way variable outputs is used, I get a complaint from parfor. Does anybody know the workaround to this?
Thanks

Accepted Answer

Edric Ellis
Edric Ellis on 20 Aug 2015
The trick here is that (unfortunately) you need to assign the outputs of your function to a temporary variable, and convince parfor that the variable is indeed a temporary. Like so:
numOut = 3;
n = 7;
out = cell(numOut, n);
parfor idx = 1:n
% This line is required by PARFOR to ensure that 'tmp' is treated
% as a temporary loop variable:
tmp = cell(1, numOut);
% Call the function with a variable number of outputs:
[tmp{1:numOut}] = deal(rand());
% Assign into the output:
out(:, idx) = tmp;
end
Without the tmp = cell(1, numOut); statement, parfor thinks you are assigning to only part of tmp in the following line, and therefore concludes that your loop is order-dependent. By assigning to tmp without any indexing, parfor realises that you are creating a whole new value.

More Answers (1)

Matt J
Matt J on 20 Aug 2015
Tank=initialize_tank();
numOutputs=size(Tank,1);
parfor ii=1:n
[outputs{1:numOutputs}]=myfunction(a,b,c,d);
Tank(:,ii)=outputs(:);
end
  4 Comments
Matt J
Matt J on 20 Aug 2015
Hmmmm. Well, one solution would be to return just a single argument from myfunction. I.e., have it return "outputs" already in cell array form, like below. Even if you don't want to rewrite myfunction, it should be easy to write a wrapper for it that will do this.
n=10;
a=1;b=1;c=1;d=1;
Tank=initialize_tank(n);
numOutputs=size(Tank,1);
parfor ii=1:n
out=myfunction(a,b,c,d,numOutputs);
Tank(:,ii)=out(:);
end
function T=initialize_tank(n)
T=nan(4,n);
function out=myfunction(a,b,c,d, numOutputs)
out=cell(1,numOuputs);
Patrick Mboma
Patrick Mboma on 20 Aug 2015
Matt,
This workaround using a wrapper function would work brilliantly. Edric, below, proposes an alternative solution but which also requires an extra step. Both solutions work very well. Thank you very much.

Sign in to comment.

Categories

Find more on Parallel for-Loops (parfor) in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!