-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
ENH:MAINT:optimize: Rewrite SLSQP and NNLS in C #22524
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I'll add check boxes above so we don't forget that this PR may not actually close all those issues. Some of them are feature requests, and without testing, we won't know whether some of the bug fixes are fixed by the translation or if they are inherent to the algorithm. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Impressive! Still, would it make sense to do nnls
first and then a second PR for slsqp
? The previous nnls
rewrites caused quite some churn.
That's the idea. Obviously there will be tests later once I get some feedback. If we don't have any changes to be done then it closes all of them since I have looked into them. So not sure if I am getting the point. Is there anything we need to add or remove from SLSQP in your opinion? I linked one comment above about the clipping of the bounds and it seems like it is bounding already but #13009 added on top of the F77 code. I don't know why clipping of Fortran code did not suffice. I am basically looking for such things to fix inherent issues about the F77 code.
Yes and this is still the corrected version. I just changed the language. If there is a change, SLSQP also goes down under spectacularly. |
Perhaps I'm missing them, but does this add the Lagrange multipliers to the output of SLSQP to address gh-14394 or the |
Returning the multipliers at the low level is quite easy since they are always computed. The more important part is if the API wants to expose it. I think we can have that conversation once everything is in place. I'm more interested in whether you want to do something with the bounds or API changes if things are going to be much easier if we change the calling structure etc. I did not follow the If you think there are ways in which you don't need to form big arrays or whatever I think I can accomodate for it now that I'm a bit more familiar with its inner workings. |
I think I am coming to the conclusion that we should have used Highs QP solver for SLSQP. In fact this is already mentioned by Dieter Kraft already back in the day, for using an alternative solver and use the current code as a last resort scipy/scipy/optimize/slsqp/slsqp_optmz.f Lines 174 to 189 in 52a0913
but nobody rose up to the challenge apparently. I am hoping that I made the algorithm a bit more clearer for a brave soul to jump on it. Anyways, there is one last segfault left that I'm chasing. But in the meantime, code won't be changing too much hence all feedback welcome. |
@j-bowhay This is getting a test failure of
But I only removed |
Also weirdly enough some tests can't find EDIT: Dangit, nevermind it's apparently a new alias numpy/numpy#16469 |
(by the way, I realised that we don't need |
suspiciously off by almost exactly a factor of 10?
|
Free threading job is a bit funky, occasionally tripping up on different tests. Let me rerun it.
Ha! cargo cult programming on my side, thanks. |
And now it is gone. I have the feeling that something is going on in this free-threaded job that we have yet to uncover. |
I saw that failure in gh-22695, too, btw. |
Not completely unexpected at the moment, I'll go through the previous 3 days of runs and assess the failures. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only skimmed the code really (too much to be able to review in detail). This looks like another good step forward (🚀). The C code isn't the prettiest with goto
's etc., but I'm sure you already knew that - it's certainly much easier to work on it in the future compared to the Fortran code.
I added only a couple of comments. The test suite being pretty much unchanged and extra benchmarking passing give good confidence. PRs like these are hard to review in detail, but that's also not always needed (or even feasible) - I'd be happy to see this go in soon.
OK free-thread is coughing again but the rest is OK.
Yes I thought about removing gotos (which is only in the actual SLSQP code) but they are not just conditional jump instructions to unroll but they are also the reentry points to the code. So did not want to entangle things a bit more. That part needs a proper rewrite from scratch. As I mentioned above, the unicorn move would be to detach the LSQ part out and put Highs QP solver in. |
If there are no other comments, I would like to click the button with this. |
Thank you all for the reviews and benchmarks, much appreciated. |
Well done @ilayn |
Awesome work Ilhan! Question about the list of issues with (unchecked) check boxes: is the idea that those weren't actually closed by this PR yet, but are now more tractable to work on? |
They are more of algorithm issues and not F77 problems. I wanted to do something about them but did not attempt as I don't have a full grasp of what other functions are doing in |
* MAINT:optimize:Remove Cython nnls for the new C implementation * ENH:optimize: Rewrite nnls in C * ENH:optimize: Rewrite slsqp in C - header * MAINT:optimize: Adjust meson file for slsqp/nnls C rewrite * MAINT:optimize.nnls: Work with ints in NNLS * ENH:optimize: Add LDP and LSI C code to SLSQP module * ENH:MAINT:optimize: Rework the SLSQP header file for the extension module * ENH:MAINT:optimize: Implement lsei for SLSQP * MAINT:optimize: Add Python lsei_wrapper to SLSQP * MAINT:optimize: Adjust the error code of NNLS on Python caller * MAINT:optimize: Silence unused parameter warnings in SLSQP * ENH:optimize: Add LSE branch to LSEI problem * MAINT:optimize: Change the error code in __nnls.c * MAINT:optimize.nnls: Tidy up the NNLS header * ENH:optimize: Add lsq function to SLSQP - implementation * ENH:optimize: Add lsq function to SLSQP - header * ENH:optimize: Add slsqpb function to SLSQP - implementation * ENH:optimize: Add slsqpb function to SLSQP - header * MAINT:optimize: Remove unnecessary allocation in nnls * MAINT:optimize: Cleanup in SLSQP C file * MAINT:optimize: Add license and clean SLSQP header file * MAINT:optimize: Reimplement slsqp_body for a simpler structure * ENH:MAINT:optimize: Add the dictionary parsing to SLSQP header * MAINT:optimize: Adjust the python caller for the SLSQP code rewrite * MAINT:optimize: Delete SLSQP Fortran code after C rewrite * MAINT:optimize: Some fixes after SLSQP rewrite - C * MAINT:optimize: More adjustments to the new SLSQP C code * BUG: optimize: Fix the workspace size in SLSQP * MAINT:optimize: Add early return to NNLS * MAINT:optimize: More .h fixes after SLSQP rewrite * MAINT:optimize: Clarified the license info for NNLS * BUG: optimize: Fix SLSQP iteration counter * MAINT:optimize: Remove SLSQP debugging compiler flags * MYPY:optimize: Add SLSQP C code to ignore list * MAINT: optimize: Remove zeros from the deprecated import list * MAINT: optimize: Various lint and import fixes to SLSQP * MAINT: optimize: Fix import typo in SLSQP * MAINT:optimize: Add some more comments to SLSQP * DOC:optimize: Add workspace details and acc explanation * TST:optimize: Relax test tolerance for SLSQP that failed on Windows * MAINT:optimize: Adjust SLSQP workspace calc for missing ineq constratints * MAINT:optimize: Use hypot in slsqp function LSEI * MAINT:optimize: Add missing restrict to the SLSQP C code * MAINT:optimize: Move the slow SLSQP bound check into C level * MAINT:optimize: Implement changes to SLSQP Python code for performance * TST:optimize: Add SLSQP test for warnings and segfault avoidance * STY:optimize: Fix PEP8 issues in SLSQP * MAINT:optimize: Resolve meson conflicts * FIX: optimize: Remove spurious shape check return from LSEI * TST: optimize: Check for 2D RHS input in NNLS * TST: optimize: Change NNLS test to a well-conditioned one * MAINT: optimize: Rename the struct clearer
This PR introduces new C code both for F77 SLSQP and the previously translated NNLS. (Superseeds #19121)
NNLS changes
SLSQP changes
Reference issue
Towards #18566
What does this implement/fix?
I'll just copy/paste the list @dschmitz89 collated in #19130
Closes #6689
Closes #7518
Closes #10416
Closes #14915
Closes #19362
slsqp
optimizer #19130 : META issue for the SLSQP issuesargs
argument needs to be coerced into tupleslsqp
converges to maximum, not minimumAdditional information
I did not mean to open the PR prematurely but I think there are some design issues that we have been suffering, for example #13009 (comment) from @andyfaff hence if anything needed to be done, please let me know so I can incorporate.