fix(metabolism_redux): cvxpy solver fallback on GLOP failure - #440
fix(metabolism_redux): cvxpy solver fallback on GLOP failure#440eagmon wants to merge 2 commits into
Conversation
MetabolismRedux's NetworkFlowModel.solve() would hard-fail (SolverError or a raised ValueError on non-optimal status) whenever the primary GLOP LP solver hit a transient/numerical failure, killing the whole simulation seed. Add solve_with_fallback(), which tries GLOP first and, on SolverError or a non-optimal status, retries with PDLP, then CLARABEL, then SCS (all installed in this env), logging a warning on each fallback attempt. Raises the original error with context only if every solver fails. No change to the optimization problem/objective.
🔍 Vulnerabilities of
|
| digest | sha256:a07425ac99a8f15f8f5ce479d591be2008a455828781684457518e5a81bfc132 |
| vulnerabilities | |
| platform | linux/amd64 |
| size | 975 MB |
| packages | 904 |
📦 Base Image debian:13-slim
| also known as |
|
| digest | sha256:486b1c3d3a6a836d2518d5ac1a7b522050a034ae83b47c063fd45d550b2b9dbf |
| vulnerabilities |
Description
Description
Description
Description
Description
Description
Description
Description
Description
Description
Description
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
Description
Description
Description
Description
Description
Description
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Description
|
|
Usually when the solver fails, it's because the problem posed is poor. GLOP sometimes is weird though. Do the other solvers not fail for the same simulations that the GLOP solver fails on? As far as I'm aware there's no tests for this process running in the simulation. |
… a transient GLOP failure
Addresses Cyrus's review note ("no tests for this process running in the
simulation") and resolves the `# TODO (Cyrus) Add test for entire process`.
Adds test_ecoli_metabolism_redux_solver_fallback (@pytest.mark.slow) in
ecoli/experiments/metabolism_redux_sim.py: runs the full MetabolismRedux
process inside a short EcoliSim, injects one transient GLOP SolverError on
the first in-sim solve, and asserts the run completes — i.e. a fallback
solver reaches an optimal solution on the *same* FBA problem GLOP choked on,
so the tick and the seed survive. Complements the standalone-LP unit tests in
ecoli/processes/test_metabolism_redux_solver_fallback.py.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks Cyrus — Addressed in "Do the other solvers fail on the same simulations GLOP fails on?" Two distinct cases, and the fallback is deliberately scoped to only one of them:
"No tests for this process running in the simulation." Added one, and resolved the
I've added the One thing I can't synthesize from the outside is a naturally-occurring GLOP failure — the injected test proves the mechanism, but if you have a seed/tick where GLOP reproducibly fails in-sim, I'll add it as a regression fixture so we're asserting on a real failure rather than a simulated one. |
NetworkFlowModel.solve()calls cvxpyproblem.solve(solver=GLOP). GLOP intermittently raisescvxpy.error.SolverError(or returns a non-optimal status) on some ticks/seeds, which currently raises immediately and — in ensemble runs — kills that whole simulation seed.Change
Adds
solve_with_fallback(problem, primary_solver=GLOP, fallback_solvers=(PDLP, CLARABEL, SCS)): GLOP is tried first (fast path); onSolverErroror a non-optimal status it retries with each fallback in turn, logging a warning per attempt. If every solver fails, the original error is re-raised with the list of attempted solvers. No change to the optimization problem/objective — only the solve invocation's solver selection + error handling. Thesolve()call site now delegates to this helper (replacing the prior immediate-raise-on-failure).Fallback solvers were chosen from
cvxpy.installed_solvers()in this env:['CLARABEL','ECOS','ECOS_BB','GLOP','OSQP','PDLP','SCIPY','SCS'].Tests
ecoli/processes/test_metabolism_redux_solver_fallback.py(3 tests): forces the primary solve to raise / return non-optimal and asserts the fallback path returns a solution, and that an all-fail case re-raises. Passing locally (against a built tree; a temp-worktree run only fails on the unbuilt_build_sequencesCython extension, unrelated to this change).🤖 Generated with Claude Code