필터 지우기
필터 지우기

Constructing class objects within a parfor loop?

조회 수: 10 (최근 30일)
Wouter
Wouter 2017년 5월 9일
편집: Matt J 2017년 5월 10일
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.

채택된 답변

Wouter
Wouter 2017년 5월 9일
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
Wouter
Wouter 2017년 5월 10일
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 2017년 5월 10일
편집: Matt J 2017년 5월 10일
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.

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Matt J
Matt J 2017년 5월 9일
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.

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품

Community Treasure Hunt

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

Start Hunting!

Translated by