YALMIP is not working with parfor loop

Hello,
I have the problem with decision variables and solving multiple problems using parfor loop.
I define some decision variables before parfor loop and when I run parfor loop I got the error: "Matrix dimensions must agree", because my decision variables are now empty vectors/matrices.
Here I attach a piece of my code for which I already get the error.
rep = 100;
n=2;
m=2;
T=4;
P_min=[0.0800; 0.0800];
P_max=[0.2; 0.2];
Pd = [1.0800 1.0800 1.0800 1.0800;
0.9700 0.9700 0.9700 0.9700];
Qd = [0.2200 0.2200 0.2200 0.2200;
0.2000 0.2000 0.2000 0.2000];
lambda_l = sdpvar(m,1);
lambda_u = sdpvar(m,1);
lambda = sdpvar(n,1);
h_bas = 0;
h_bas = h_bas + sum(lambda_l.*P_min.*(~isinf(P_min))-lambda_u.*P_max.*(~isinf(P_max)));
cons_bas = [];
cons_bas = [cons_bas, lambda_l>=0,lambda_u>=0];
for t=1:T
parfor k=1:rep
h = h_bas + sum(lambda.*Pd(:,t));
cons = [cons_bas];
options = sdpsettings('solver','mosek','verbose',0);
optimize(cons,-h,options);
end
end
Could you please help me to fix this problem?
Best,
Adriana

Answers (2)

YALMIP permits you to define variables using calls such as
P = sdvpar(1)
and it expects that variable to be distinguished from
Q = sdvpar(1)
That can only happen if YALMIP is retaining state about which variables have been created and what their properties are.
In MATLAB, the methods of recording state like this are:
  • in graphics objects (not likely at all to be the case here)
  • in the base workspace
  • in persistent variables
  • in global variables
  • in handle objects
  • in class variables
However, graphics objects, base workspace, persistent variables, and global variables are not copied to parallel workers.
Objects (that are plainly referenced) are copied to parallel workers, but through a method equivalent of "save" and "load" --- a process that copies only serializable data, and loses dynamic properties, and effectively disconnects the copied clones from the original objects.
I suspect that the code was not designed with parallel use in mind.

7 Comments

Thank you for your comment, but I still don't know if I can solve this problem.
You are right that this code doesn't make sense to be written with parfor loop, but as I wrote it is only part of long code which already allows to show the problem I have.
I could probably define all variables in parfor loop, but is there any other solution?
Yes, there is another solution. Source code for YALMIP is available, and you could modify it to become robust for use in parallel programming.
Depending exactly how YALMIP is implemented, there is a possibility that it might be possible to send its state information to the workers using a construct such as parpool constants.
... You might have noticed by now that the easiest approach is to construct the YALMIP variables in the workers.
There is one strange thing in this problem. When I change the problem to one-dimensional problem (m=1 and comment second dimension of P_min, P_max, Pd, Qd), the code is working and there is no error. Could you explain it somehow?
I want to add also that the code was working and at some point when I increased rep, the error appeared. That's way I had hope that this problem can be easily solved.
Copying from my answer below, as it is relevant for Walters response here
To my surprise, the code runs (in 2018 and 2020, in 2016 it crashes as that version of uses save and load to communicate data between workers and those are not available for sdpvar and constraint objects, leading to your error message)
Hence, I assume the save/load now is done using built-in machinery which circumvents the overloading of load/save. I'm not sure of he consequences of this though, as it would mean there are local databases of the YALMIP internals on every worker, but it appears to behave as expected now.
I was running above code in 2020b and it crushed there...
Crashed? Weird, runs without issues on both 2018 and 2020 for me (windows)
As I wrote, I got the above error that "Matrix dimensions must agree" and it was using the MATLAB version 2020b. Unfortunately this problem appeared after some runs, when I increased the number of repetitions. That's why it is difficult for me to find what's wrong.
Have you run exactly the same code I attached or maybe you modified it to one-dimensional version?

Sign in to comment.

Johan Löfberg
Johan Löfberg on 9 Mar 2021
Edited: Johan Löfberg on 9 Mar 2021
EDIT: Works now in newer MATLAB version!
YALMIP does not work with parfor, and it cannot be fixed or circumvented.
For YALMIP specific questions, you are much better off posting quetions on the YALMIP google groups forum.

3 Comments

To my surprise, the code runs (in 2018 and 2020, in 2016 it crashes as that version of uses save and load to communicate data between workers and those are not available for sdpvar and constraint objects, leading to your error message)
Hence, I assume the save/load now is done using built-in machinery which circumvents the overloading of load/save. I'm not sure of he consequences of this though, as it would mean there are local databases of the YALMIP internals on every worker, but it appears to behave as expected now.
BTW, your code is going to run much faster using an optimizer construct, to the extent that the for parfor might be redundant, as most of the time in your version is spent in general overhead. I think this version survuves parfor in 2016 too, as an optimizer object is disconnected from YALMIPs global database and can be saved/loaded
c = sdpvar(m,1);
Solver = optimizer(cons_bas,h_bas + c'*lambda,options,c,lambda);
for t=1:T
parfor k=1:rep
Solver(Pd(:,t))
end
end
Thank you Johan for your suggestion, I will try to use optimizer.

Sign in to comment.

Asked:

on 3 Mar 2021

Commented:

on 9 Mar 2021

Community Treasure Hunt

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

Start Hunting!