Conversation
Implements a pyoptsparse wrapper for the UNO (Unified Nonlinear Optimizer) using the unopy package. Follows the pyIPOPT pattern: COO sparse Jacobian format, constraint reordering via getOrdering, and MPI rank-0/waitLoop split. unopy callbacks receive x as unopy.Vector and output arrays as unopy.PointerToDouble, neither of which expose the buffer protocol. x is converted via np.fromiter using the callback's nv count parameter. Output arrays are mapped to writable numpy views via a two-level ctypes dereference through pybind11's simple_value_holder layout, avoiding per-element Python/C++ round-trips for bulk array writes.
…Filling out tests.
|
@cvanaret I would appreciate your review again. Theres a skipped test of problem 109 (TP109) from the Schittkowski test that I wasn't able to get to converge with Uno. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #483 +/- ##
=======================================
Coverage 82.99% 82.99%
=======================================
Files 1 1
Lines 147 147
=======================================
Hits 122 122
Misses 25 25 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
tests/test_tp109.py
Outdated
| @@ -205,11 +196,13 @@ def test_uno_informs(self): | |||
| optOptions={"time_limit": 1e-15, "logger": "INFO"}) | |||
There was a problem hiding this comment.
That was a test to make sure the solution inform indicates that the time limit was reached.
|
@robfalck thanks for the PR! I have an AMPL model of I think I should monitor progress and flush the limited memory if the solver stalls. Note that I'm also planning to implement interior points with L-BFGS in the next few days. Will the exact Hessian callback be available in the near future? |
|
Thanks for checking. That last question is up to the mdolab folks since it's a significant change. |
|
unopy v0.4.1 is out with:
uno_solver.set_preset("ipopt")
# either set the Hessian model explicitly
uno_solver.set_option("hessian_model", "LBFGS")
# or let Uno default to L-BFGS if no Hessian is provided
uno_solver.set_logger_stream(sys.stdout)
uno_solver.optimize(model)
sys.stdout.flush()
# or
with open("log.txt", "w") as f:
uno_solver.set_logger_stream(f)
uno_solver.optimize(model)
f.flush() |
It would be a very cool capability to add since most gradient-based optimizers should support that, but I don't believe that the lab (pinging @A-CGray @eirikurj ) is interested in adding this capability in the near term. Most of the (high-fidelity) codes used for engineering MDAO do not provide second derivatives. I haven't thought this through yet but I think it would require a change in API of the |
I wouldn't complain if somebody else implemented it, but we have no plans to. We are rarely (if ever) solving problems where the Hessian is computable in any practical sense. If somebody was going to implement this, we may as well implement the ability to use jacobian-vector products as well. Thanks for doing this work @robfalck , I have been meaning to try out Uno for a long time, now I might actually get around to it! |
Purpose
This pull request adds an interface to Uno to pyoptsparse.
Uno is a C++ package for nonlinear constrained optimization, with a python interface (unopy).
Uno provides another option that provides both SQP and interior-point capability depending on the settings.
Other notes about the Uno interface
This implementation requires unopy 0.4.0 or later.
Expected time until merged
A few weeks (not urgent).
Type of change
Testing
Running the test suite will test Uno against several existing test problems.
Checklist
ruff checkandruff formatto make sure the Python code adheres to PEP-8 and is consistently formattedfprettifyor C/C++ code withclang-formatas applicableResolves cvanaret/Uno#318