Can you use functions inside a matlab parfor loop? for instance I have a code that looks like:
matlabpool open 2
Mat=zeros(100,8);
parfor(i=1:100)
Mat(i,:)=foo();
end
Inside the function I have a bunch of other variables. In particular there is a snippet of code that looks like this:
function z=foo()
err=1;
a=zeros(10000,1);
p=1;
while(err>.0001)
%statements to update err
% .
% .
% .
p=p+1;
%if out of memory allocate more
if(p>length(a))
a=[a;zeros(length(a),1)];
end
end
%trim output after while loop
if(p<length(a))
a(p+1:end)=[];
end
%example output
z=1:8;
end
I read somewhere that all variables that grow inside of a for loop nested inside of a matlab parfor loop must be preallocated, but in this case I have a variable that is preallocated, but might grow later. matlab did not give me any errors when i used mlint, but I was wondering if there are issues that I should be aware of.
Thanks,
-akt
According to Mathworks' documentation, your implementation of the matrix
Mat
is a sliced variable. That means you update different "slices" of the same matrix in different iterations, but the iterations do not affect each other. There is no data dependency between the loops. So you are ok to go.Growing
a
inside functionfoo
does not affect theparfor
, becausea
is a regular variable located infoo
's stack. You can do anything witha
.There do exist several issues to notice:
Don't use
i
andj
as iteration countersDefining
i
orj
in any purpose is bad.I have never been bored to refer people to this post - Using i and j as variables in Matlab.
Growing
a
is badEvery time you do
a=[a;zeros(length(a),1)];
the variable is copied as a whole into a new empty place in RAM. As its size doubles each time, it could be a disaster. Not hard to imagine.A lighter way to "grow" -
Here, you grow a list of pointers, a cell array
c
. It's smaller, faster, but still it needs copying in memory.Use minimal amount of memory
Suppose you only need a small part of
a
, that is,a(end-8:end)
, as the function output. (This assumption bases on the callerMat(i,:)=foo();
wheresize(Mat, 2)=8
. )Suppose
err
is not related to previous elements ofa
, that is,a(p-1)
,a(p-2)
, .... (I will loosen this assumption later.)You don't have to keep all previous results in memory. If
a
is used up, just throw it.The second assumption may be loosen to that you only need a certain number of previous elements, while this number is already known (hopefully it's small). For example,
Trimming is not that complicated
Proof:
The reason is
end
is10
(although you can't use it as a stanalone variable), and11:10
gives an empty array.