Repository navigation
perf(highs): build the model in bulk from the row-wise matrix - #1118
FabianHofmann wants to merge 5 commits into
Conversation
Highs._build_solver_model built the model with addVars, changeColsIntegrality, changeColsCost and a row-wise addRows. HiGHS keeps an addRows matrix row-wise and transposes it at solve time. Pass the whole LP in one passModel call with a CSC matrix and a full-length integrality array instead, and compare the constraint sense as integer codes rather than unicode strings. On a 1.79M-variable / 4.29M-row / 7.18M-nnz network the HiGHS build stage drops from ~1.22 s to ~0.60 s with ~110 MB lower peak RSS. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F4nx8GJ8mSNvkTagja9dMj
Merging this PR will improve performance by 29.8%
Performance Changes
Tip Curious why performance improved? Comment Comparing Footnotes
|
|
Saw the same speedup in specsolve. |
Pass enums and the final objective sense to passModel, drop no-op dtype wrappers and redundant guards, fold the new test into test_to_highspy plus a two-case known-optimum test, and shorten the release note. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F4nx8KhK8QzSzHhpYKvcSx
nice! |
An all-continuous integrality array makes HiGHS write empty bin/gen/semi sections to LP files, which CBC, GLPK and COPT misread. Use passModel only when the model has discrete columns; otherwise add rows, then columns column-wise via addCols. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F4nx8JFY4SxxVLJEByWw8z
|
Just to mention it to you right now: Gurobi has more to gain: in specsolve, one gurobipy.loadModel call made loading 3–6× faster than addMVar + addMConstr (fluxopt/specsolve#1942). That's worth a separate PR. |
ah wonderful! let's try that out too! |
Converting the cached CSR matrix to CSC held a second copy of A during the build, which CodSpeed flagged as ~20% more memory in to_solver. HiGHS accepts the row-wise matrix directly: MILPs now use a row-wise passModel, LPs addCols without entries followed by one row-wise addRows. Build time stays at the level of the column-wise version, LP peak memory is back at master's, and MILP peak memory drops ~40%. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01F4nx8GJ8mSNvkTagja9dMj
Closes # (if applicable).
Changes proposed in this Pull Request
Note
The following content was generated by AI.
Highs._build_solver_model(direct API, also used bylinopy.io.to_highspy) built the HiGHS model in several calls:addVars,changeColsIntegrality,changeColsCost, thenaddRows.This PR passes the model in bulk and hands HiGHS the cached CSR matrix as is:
h.passModel(...)call (raw-array overload,MatrixFormat.kRowwise) with a full-lengthint32integrality array (0 continuous, 1 binary/integer, 2 semi-continuous). HiGHS rejects an empty array.addCols(cost and bounds, no matrix entries), then one row-wiseaddRows.passModelis not used here because an all-continuous integrality array makes HiGHS write emptybin/gen/semisections to LP files, which CBC, GLPK and COPT misread.M.senseas integer codes (view(np.uint32)) instead of unicode strings.An earlier version of this PR converted A to CSC first. That held a second copy of the matrix during the build, and CodSpeed flagged ~20% more memory in
test_to_solver[highs-*]. Passing the row-wise matrix directly is about as fast and removes that copy.Benchmark and test details
Synthetic model, 1.26M variables, 4.9M nonzeros. Build stage only, 3 fresh processes per variant, cloud VM. Peak RSS is the increase during the build.
Solve time on the same model is unchanged.
Tests:
test_highs_direct_known_optimumcovers a semi-continuous model and a model without constraints.test_to_highspy_pure_lp_writes_no_integer_sectionschecks that LPs get no empty integer sections.pytest test/test_io.py test/test_optimization.py: 655 passed, 16 skipped.ruff check,ruff formatandmypy .pass.Checklist
AGENTS.md).doc.doc/release_notes.rstof the upcoming release is included.Generated by Claude Code