feat(csr): native soften for frozen constraints - #979
Conversation
9d20066 to
797c0d8
Compare
Constraint.soften moves to ConstraintBase; CSRConstraint appends slack terms to its sparse rows in place, keeps slack names through to_dense/freeze/netcdf, and add_constraints(penalty=, freeze=True) softens natively.
797c0d8 to
0b095a0
Compare
Merging this PR will regress 1 benchmark
|
| Benchmark | BASE |
HEAD |
Efficiency | |
|---|---|---|---|---|
| ❌ | test_to_lp[nodal_balance-severity=0] |
3.3 MB | 3.7 MB | -11.85% |
| ⚡ | test_to_lp[expression_arithmetic-n=10] |
1,338.9 KB | 718.6 KB | +86.33% |
| ⚡ | test_to_lp[sparse_network-n=10] |
1,337.8 KB | 718.3 KB | +86.23% |
| ⚡ | test_to_lp[qp-n=1000] |
2.6 MB | 2 MB | +30.22% |
| ⚡ | test_build[nodal_balance_sparse-severity=0] |
1.5 MB | 1.3 MB | +13.94% |
| ⚡ | test_build[nodal_balance_sparse-severity=100] |
1.5 MB | 1.3 MB | +13.94% |
| ⚡ | test_build[nodal_balance_sparse-severity=50] |
1.5 MB | 1.3 MB | +13.94% |
| ⚡ | test_to_lp[cumsum-severity=100] |
208.9 MB | 184.4 MB | +13.29% |
Tip
Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.
Comparing feat/csr-soften (0b095a0) with master (38fbd4a)2
Footnotes
-
181 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩
-
No successful run was found on
master(b9a698b) during the generation of this report, so 38fbd4a was used instead as the comparison base. There might be some changes unrelated to this pull request in this report. ↩
Build cost — v1 vs legacyv1 build peak & time relative to legacy, on this commit — not a comparison against master (that is CodSpeed).
Full table (time + peak, mean)📊 Interactive plots + CSV: download the semantics-report-v1-vs-legacy artifact from this run. Report-only · not a gate · refreshed on every push · obsolete once legacy is dropped. |
Closes #975. Part of #972 (PR 3), stacked on #974.
Note
The following content was generated by AI.
Changes proposed in this Pull Request
A frozen
CSRConstraintcan now be softened natively, without densifying:softenandslackmove fromConstrainttoConstraintBase. Validation (positive penalty, objective exists, registered constraint, no double softening, no mixed signs), slack creation (mask=self.mask,max_violationas upper bound) and the objective update are shared._attach_slack(slack, sign). Dense:update(lhs=...)as before. Frozen: appends one CSR entry per active row (two for==, same signs as dense) and widens the matrix to the current variable count.to_dense()/mutable(),Constraint.freeze(), pickle and netcdf.add_constraints(penalty=, freeze=True)no longer raises. The "soften needs freeze=False" error and its densify reason are removed.=), so it gets the same slack structure as dense.Tests
test_frozen_soften_matches_dense:<=,>=,==× no mask / mask / all masked ×soften,soften(max_violation=),penalty=withfreeze=Trueand with the model default. Compares rows and objective cell by cell with dense soften, checks no densify notice, the registered handle, netcdf round trip and.slackon all copies.sense="max"with aDataArraypenalty.test_constraint.pyare not repeated.A,b,sense,c, bounds and LP/MPS output against dense for masked rows, empty rows, variables added/removed after freezing, scalar and aux-coord constraints, row scaling, and both semantics, and rantrack_updates=Truere-solves. All identical.Local results
test/remote(oetc extras missing): 7086 passed, 0 failed (before review follow-ups);test_csr.py,test_constraint.py,test_constraints.py,test_io.pyafter follow-ups: 1011 passed, only the xpress license failures.ruff check,ruff format: clean.mypy: only the local-stub error attest/test_solvers.py:225, not present in CI.Checklist
AGENTS.md).doc.doc/release_notes.rstof the upcoming release is included.