Constructing class objects within a parfor loop?

10 views (last 30 days)
So I build a class called 'realization', from which working with individual objects works fine.
Now, from a script, stored in the same folder as the classdef file, I want to initialize objects of the class in the following way
parfor Fit=1:length(powering)
for relnr=1:Nrel
traject(Fit,relnr)=realization(powering(Fit),U,gamma,delta);
traject(Fit,relnr)=traject(Fit,relnr).pcountrun();
traject(Fit,relnr)=traject(Fit,relnr).homodynerun();
end
end
Where powering is a short array of numbers,Nrel an integer and U,gamma,delta plain numbers. Previously, I did make a very similar construction in the parfor before switching to OO-programming and that one seemed to work out fine. However, when trying to execute the piece of code above, I receive an error
An UndefinedFunction error was thrown on the workers for 'traject'. This might be because the file containing 'traject' is
not accessible on the workers. Use addAttachedFiles(pool, files) to specify the required files to be attached. See the
documentation for 'parallel.Pool/addAttachedFiles' for more details.
Caused by:
Undefined function 'traject' for input arguments of type 'double'.
First of all, I never intended 'traject' to be a function, just a matrix of realization-objects. But in my non OO-implementation, MATLAB did use it the way I intended, so I wouldn't think the assignment is improper use of parfor by itself.
What I have already tried:
  • Add
addAttachedFiles(gcp,'realization.m')
just before the for-loop, to ensure every worker has access to the class definition. This doesn't make a difference, though.
  • According to question <https://nl.mathworks.com/matlabcentral/answers/93826-are-matlab-user-defined-objects-supported-in-parfor-in-parallel-computing-toolbox-4-1-r2009a Are MATLAB user defined objects supported in PARFOR in Parallel Computing Toolbox 4.1 (R2009a)?>Which is possibly outdated with R2016b I am using, the issue might get solved by ensuring the existence of a argumentless constructor. But according to the MATLAB webinar on OO programming, I already wrote the constructor as
function thisRealization=realization(f,u,gam,delt)
if nargin==4
thisRealization.F=f;
thisRealization.U=u;
thisRealization.gamma=gam;
thisRealization.delta=delt;
end
end
such that if there are zero arguments, the condition nargin==4 is not satisfied and MATLAB returns to the default constructor.
  • Ordinary for-loop instead of parfor works fine (this was a question from Matt J).
As a final note I am a beginner to OO-programming in MATLAB and also fairly new with regard to parallel computations. Therefore, I used a Value class in order not to complicate things too much from the start, but I may consider switching to Handle class later if that is faster (methods pcountrun and homodynerun are computationally expensive and produce large matrices of data as class properties). If you would already recommend me to switch to handle classes already because it matches better with parfor, I can do that though.

Accepted Answer

Wouter
Wouter on 9 May 2017
As inspired by Matt J's answer, everything seems to work when first constructing the objects in an ordinary for-loop and only later bring them to the parallel pool. That is,
for Fit=1:length(powering)
for relnr=1:Nrel
traject(Fit,relnr)=realization(powering(Fit),U,gamma,delta);
end
end
parfor Fit=1:length(powering)
for relnr=1:Nrel
traject(Fit,relnr)=traject(Fit,relnr).pcountrun();
traject(Fit,relnr)=traject(Fit,relnr).homodynerun();
end
end
MATLAB complains that preallocating is recommended now, but doing so isn't worth it for my purposes as in that case I would need to define another realization-array class as desribed in creating-object-arrays.
  3 Comments
Wouter
Wouter on 10 May 2017
Thanks for your comment, I'll try it. It seems a bit weird to me though, that the constructor has to be executed twice for each object then.
Matt J
Matt J on 10 May 2017
Edited: Matt J on 10 May 2017
It doesn't have to be executed twice. Once you've pre-allocated the object array using the constructor, you are free to start assigning property values to the objects directly, without calling the constructor a second time.

Sign in to comment.

More Answers (1)

Matt J
Matt J on 9 May 2017
I recommend pre-allocating the traject array before passing it to the parfor loop. It appears you are relying on parfor to do this via the argument-less constructor. I also recommend testing with parfor replaced by an ordinary for-loop.

Categories

Find more on Loops and Conditional Statements in Help Center and File Exchange

Products

Community Treasure Hunt

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

Start Hunting!