Fix GDPopt LBB solver error handling - #4041
Open
william-xue wants to merge 1 commit into
Open
william-xue wants to merge 1 commit into
william-xue wants to merge 1 commit into
Conversation
13 tasks
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.
Fixes #4023.
Summary/Motivation:
GDPopt LBB currently catches every
RuntimeErrorraised by a node subproblem solver and converts it into infeasible bounds:A solver infrastructure, licensing, or interface failure is not proof of mathematical infeasibility. Treating it as such can prune a feasible branch of the search tree, and hides a failed local screening solve — the user sees
infeasible/a converged bound instead of an infrastructure error. This affects both the evaluated-node path and the local-screening path inpyomo/contrib/gdpopt/branch_and_bound.py.Changes proposed in this PR:
RuntimeErrorfrom both the evaluated-node solve and the local-screening solve instead of converting it into synthetic infeasible bounds.pyomo/contrib/gdpopt/tests/test_LBB.pycovering both paths with a fake subsolver that raisesRuntimeError(one-variable bounded model,SubproblemErrorstest class).AI-Use Disclosure
or
AI tools contributed to the development of this PR
Review process (select ONE):
Notes for reviewers (optional):
Least confident point, and the reason for the focused question below: whether re-raising is the preferred contract here, or whether LBB should instead catch a narrower exception and surface a distinct status. I kept the change minimal (re-raise + regressions) so the decision stays with the maintainers. Note also that the local-screening path is behavior-visible: a subsolver
RuntimeErrorthere previously produced a bound that could hide the failure, and now propagates out ofsolve().Supersedes #4032, which was closed by policy because its description did not use this repository's PR template. Same commit and same diff; the template is now used unmodified, as requested.
Validation (re-run on current
main, no upstream changes inpyomo/contrib/gdpoptsince the branch point).venv/bin/python -m pytest -q pyomo/contrib/gdpopt/tests/test_LBB.py -k "SubproblemErrors"—2 passed, 13 deselected.venv/bin/python -m pytest -q pyomo/contrib/gdpopt/tests/test_LBB.py—2 passed, 11 skipped, 2 deselected.venv/bin/python -m black --check pyomo/contrib/gdpopt/branch_and_bound.py pyomo/contrib/gdpopt/tests/test_LBB.py—2 files would be left unchangedgit diff --check— cleanLegal Acknowledgement
By contributing to this software project, I have read the contribution guide and agree to the following terms and conditions for my contribution: