osqp / osqp-matlab

Matlab interface for OSQP
https://osqp.org/
Apache License 2.0
42 stars 25 forks source link

MATLAB crashes when calling code-generated function #30

Open steradiant opened 3 years ago

steradiant commented 3 years ago

Hello, I'm using the code-generation feature to speed up the solver. The code generation is done like shown in the documentation:

settings.verbose = false;
prob = osqp;
prob.setup(H, q, Aeq, beq, beq, settings); 
prob.codegen('osqp_codegen','parameters','matrices');

I then want to run the solver in a for loop where I update the bounds and the A-matrix accordingly

emosqp('update_bounds', beq, beq);
[~,~,Ax] = find(Aeq);
emosqp('update_A', Ax, [], 0);
res = emosqp('solve');

When the 'update_A' function is called, MATLAB crashes. I uploaded the crash report. I'm using MATLAB 2020b under Ubuntu 20.04 LTS. matlab crash osqp2.txt

Note: At my first try to generate the mex-file I got the following errors in MATLAB

cmake: /usr/local/MATLAB/R2020b/bin/glnxa64/libcurl.so.4: no version information available (required by cmake)
cmake: /usr/local/MATLAB/R2020b/sys/os/glnxa64/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by cmake)
cmake: /usr/local/MATLAB/R2020b/sys/os/glnxa64/libstdc++.so.6: version `GLIBCXX_3.4.26' not found (required by /usr/lib/x86_64-linux-gnu/libjsoncpp.so.1)

after some googling, I found a solution where I preload the library path as follows (executing the following command in the shell before I start matlab from the same shell): export LD_PRELOAD="/usr/lib/x86_64-linux-gnu/libstdc++.so.6"

goulart-paul commented 3 years ago

I confirm a crash on this line: emosqp('update_A', Ax, [], 0);

There appears to be a problem with the generated code interface in the case that the whole of the A matrix is updated. Updating the matrix in the objective function using a similar style also crashes. I will create a separate issue for this problem.

For the moment, you can do this:

emosqp('update_bounds', beq, beq);
[~,~,Ax] = find(Aeq);
emosqp('update_A',Ax,1:nnz(A),nnz(A));
[x,y,st,iter,run_time] = emosqp('solve')
steradiant commented 3 years ago

Thanks for the workaround. The code doesn't crash anymore. Fyi: you have a typo in the third line of your code snippet - the name of the matrix which is passed to the update-function emosqp is Ax rather than A.

Nevertheless, another issue arose. The solver seems to be numerically less stable and even has a worse performance (takes longer to solve the problem) after code generation. In my example, I first solve the problem with the 'normal' functions and then with the code-generated function. The matrix Aeq and the vector beq are generated the same way both times.

goulart-paul commented 3 years ago

It is possible that the code generated for you does not have the rho adaptation feature enabled, while the solver you get through the ordinary matlab interface does.

I made a small example to check, and it seems that the following happens (with all options default):

1) the adaptive_rho parameter in the generated code is set to true. 2) the adaptive_rho_interval is set to 0, which ordinarily forces a time-based adaptation interval. 3) PROFILING is undefined (I think), which means that the adaptive_rho_fraction parameter is left out.

It is possible that the net effect is that there is no rho adaptation effect in the embedded code, which would explain the difference in performance.

Could you try generating your embedded code with adaptive_rho_interval set to a fixed value (say 50 as a starting point)? If that gives identical performance then it would perhaps confirm the above.

Otherwise, please send an MWE and we can have a closer look.

steradiant commented 3 years ago

Thanks for the fast answer. The performance got way better with this option ( adaptive_rho_interval=50 ) set. Nevertheless, the results of the code generated solver are not satisfying. The non-code-generated solver delivers really decent results but the code-generated is quite off at some points.

imciner2 commented 3 years ago

Please note that the crash when the matrix size isn't specified has been fixed in 0.6.2 released earlier this year.