Helpful error when a solver can't handle the PH quadratic proximal term (issue #762, part 1)#768
Open
DLWoodruff wants to merge 1 commit into
Open
Helpful error when a solver can't handle the PH quadratic proximal term (issue #762, part 1)#768DLWoodruff wants to merge 1 commit into
DLWoodruff wants to merge 1 commit into
Conversation
…issue Pyomo#762) Progressive Hedging's proximal term makes the subproblem objective quadratic (unless --linearize-proximal-terms is used). A solver that cannot handle a quadratic objective then fails -- and for HiGHS on an MIQP the failure is cryptic (TerminationCondition=unknown). Detect this and tell the user what to do, via two complementary checks in iterk_loop: - Proactive: before the first proximal solve, if the solver reports via the legacy has_capability API that it cannot handle a quadratic objective (e.g. cbc, glpk), raise immediately with guidance. - Reactive: after the first proximal solve, if no subproblem anywhere produced a solution, raise with guidance. This covers solvers that do not expose has_capability (e.g. HiGHS via the APPSI / contrib.solver interfaces). The "no solution anywhere" test uses allreduce_or so the raise decision is identical on every rank. Both checks no-op unless a non-linearized proximal term is actually active, and the reactive check is limited to iteration 1 (if the first quadratic solve works, the solver supports quadratic objectives). Adds sputils.solver_quadratic_objective_capability (tri-state probe) and a solver-independent unit test, wired into run_coverage.bash and the CI workflow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
@tvalenciaz this addresses part 1 of #762 — please review it when you get a chance. |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #768 +/- ##
==========================================
+ Coverage 74.13% 74.16% +0.02%
==========================================
Files 166 166
Lines 21181 21207 +26
==========================================
+ Hits 15703 15728 +25
- Misses 5478 5479 +1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part 1 of issue #762
When Progressive Hedging uses a quadratic proximal term and the solver cannot handle a quadratic objective, the run fails confusingly. For HiGHS on a problem with integers/binaries (an MIQP), the failure is the cryptic
status=unknown, TerminationCondition=unknown. This adds an actionable message.Approach
PH's proximal term makes the subproblem objective quadratic unless
--linearize-proximal-termsis set, so this is a quadratic-objective/solver mismatch. Pyomo's capability information is uneven (the legacyhas_capabilityAPI reports it for solvers like cbc/glpk, but the APPSI andpyomo.contrib.solverwrappers used for HiGHS don't expose it), so a single up-front check isn't enough. Two complementary checks inphbase.iterk_loopcover both cases:has_capability) that it cannot handle a quadratic objective, raise immediately with guidance. Catches e.g.cbc,glpkbefore wasting a solve.allreduce_or, so the raise decision is identical on every rank (no MPI desync).Both checks no-op unless a non-linearized proximal term is actually active, and the reactive check is limited to iteration 1 — if the first quadratic solve succeeds, the solver supports quadratic objectives, so a later failure is a genuine optimization issue, not a capability problem. The error message points the user at
--linearize-proximal-terms(and--linearize-binary-proximal-termsfor binaries).Changes
mpisppy/utils/sputils.py:solver_quadratic_objective_capability()— tri-state probe (True/False/None, whereNonemeans "unknown", never "unsupported").mpisppy/phbase.py:_prox_is_quadratic,_check_prox_solver_capability(proactive),_check_prox_solve_succeeded(reactive); wired intoiterk_loop.mpisppy/tests/test_prox_solver_compat.py: solver-independent unit tests (probe tri-state, both guards, MPI-consistency viaallreduce_or), wired intorun_coverage.bashand.github/workflows/test_pr_and_main.yml.Validation
test_ef_ph.py): pass, with no false positives on a quadratic-capable solver (one unrelated pre-existing failure,test_scenario_lpwriter_extension, fails identically onmain).glpk(no QP) atPHIterLimit=1now raisesSolver 'glpk' reports that it cannot handle a quadratic objective ... Re-run with --linearize-proximal-terms ...; the same run with--linearize-proximal-termscompletes.🤖 Generated with Claude Code