Parallel in fmincon: getappdata & indexing problem

1 view (last 30 days)
I want to parallelize the finite differences calculations of fmincon. Doing that gives an error and I've isolated the two causes.
I've recreated the issue below, where the code inside the parfor is from my objective function for fmincon.
If I run fmincon without 'UseParallel',true then it works fine.
If I run fmincon with 'UseParallel',true, then I get the same errors as are generated using the parfor example below.
I understand why I get the error but I really need a workaround as using setappdata/getappdata between fmincon iterations helps with speed.
--------------
Cause #1 - grabbing part of a vector set from getappdata
Cause #2 - the indexing of x00_i in the code below.
x00_i=zeros(2,2,1);
x00=ones(2,2);
setappdata(0,'x00',x00)
parpool
parfor ll=1:1:2
%%%%%%%%cause 1
x1= getappdata(0,'x00');
x=x1(1,:);
%%%%%%%%
%%%%%%%%cause 2
for ii= 1:1:2
y=x(ii);
x00_i(ii,:,:)=y;
end
%%%%%%%%
end
FOLLOW-UP: If someone has a similar issue as this, I found a workaround for my case. I save x00 to multiple files indexed by the number of workers and then load/save it within each parallel loop by referring to the worker with: "t = getCurrentTask(); t.ID" . Labindex doesn't work as fmincon's parallel is akin to parfor, not spmd.
That way I can read and write and update it between iterations. In my case it doesn't matter if the worker number switches around.
In the end Walter's suggestions did not really help but it may help others.

Accepted Answer

Walter Roberson
Walter Roberson on 10 Aug 2018
  8 Comments
CJ
CJ on 11 Aug 2018
I have an intermediary fsolve() within the objective function. I use old solved values as new starting values for new iterations as that gives a huge speed boost. The result is the same using fixed starting values it just takes longer.
Walter Roberson
Walter Roberson on 11 Aug 2018
Work around:
Before fmincon, use parfevalOnAll to initialize the starting values.
Use an fmincon OutputFcn that does whatever calculations are needed to figure out what the new parameters should be, and have it run parfevalOnAll to update values on all of the workers.
Inside the objective function, pull values from the place they were written by the parfevalOnAll.
Note that it is legal to use global for this purpose. global is not disabled inside parallel workers: the issue with global is that the global values are in no way synchronized between workers.
Instead of using global, another approach would be to store UserData against the parallel task object; see https://www.mathworks.com/help/distcomp/parallel.task.html

Sign in to comment.

More Answers (0)

Categories

Find more on Parallel Computing Fundamentals 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!