Parallel in fmincon: getappdata & indexing problem

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

8 Comments

CJ
CJ on 10 Aug 2018
Edited: CJ on 10 Aug 2018
Thank you! That helps with the getappdata problem.
Do you have a suggestion for the 2nd problem? It doesn't seem like parallel.pool.Constant will help with this case.
Your parfor index variable is ll (lower case L's). You would need to be indexing x00_i at that variable. With your current code, different values of your parfor index ll would result in the same locations being written to indexed by ii (lower-case I), which creates a conflict unless x_00 is only local instead of being output.
Thanks for the reply. I think if I can access the iteration count of fmincon then I can localize the x00 term.
So last follow question: is there a way to access the iteration count when doing parallelized fmincon? I saw a similar question you answered before but couldn't translate it to my case:
The iteration count is available to OutputFcn, which is typically called after several evaluations of the function. It is not available to each function evaluation.
When you use UseParallel, it is the finite differences that are estimated in parallel, so the different workers would be working on the same iteration count, so it is not obvious that you would want to be using the iteration count.
That's fine actually; I'm updating a certain thing that only needs updating once the parameters have changed a lot, which will only happen between iterations.
If these values are being used for computation, then you would be optimizing something different depending on the iteration number, which violates the working assumptions of fmincon that computing any one location multiple times would always yield exactly the same result.
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.
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

Community Treasure Hunt

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

Start Hunting!