cbcgo performance: pivot-budgeted cuts, hypersparse btran, warm heuristic solves#13
Merged
Conversation
…ed factors Sparse-LU kernel elimination rewrites rows in place (write index never passes the read index, fill-in appended after the scan, O(1) mark-array membership): ColdSolve 300x300 -31% time, -74% bytes, -64% allocs. btran gathered every singleton pivot's column regardless of rhs sparsity while ftran already skipped zero pivots naturally. A factorize-time row->readers graph now activates only reachable pivots for mostly-zero rhs (dualRun's unit vectors); skipped pivots would compute exactly 0, so results match the dense path bitwise (A/B property test included). Activation uses epoch stamps and a written-rows restore, so a sparse solve does no O(m) clears. pivot's three O(m) alpha passes (value update, nnz count, eta extraction) fuse into one with exact-size copies. Per-factor data is int32-compacted (triPivot 24B->16B, rowKIdx) and arena-consolidated, and all solve scratch lives once on the per-LP factorWS: a refactorization allocates a handful of buffers instead of a dozen (020 end-to-end: 1.54GB -> 1.21GB allocated). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…solves Single-row MIR cuts (CglMixedIntegerRounding2-style, VUB/bound substitution with a divisor search) seed the first two root rounds on large instances; later rounds are measured-negative (row bloat, face drift). Root bound on the target case: 0.334 -> 0.355. Cut rounds are budgeted in pivots (10x rows) instead of wall clock: every large instance was ending the loop by the MaxTime/5 deadline (a round's ColdSolve dying there reads as poison), making the cut set a wall-clock artifact that reshuffled with every engine speed change. A budget exit retracts the final never-revalidated batch, matching the poison path's semantics. The wall box remains as a safety cap. 016 2.3s -> 0.5s and 018 2.8s -> 1.2s shed rounds that were pure waste. Heuristic child solves warm-start like ordinary nodes: RINS and completePoint were the only cold ones (a full phase-1 ColdSolve per attempt). The trivial MIP start is no longer polished — instrumented reducedCostFix fixes 0 columns at any cutoff that far above the optimum, so the 45k-pivot polish fed nothing downstream; tree heuristics still polish real incumbents. Root-pipeline dedups: the mipstart block's root solve doubles as cut round 0 when rc-fixing left the LP untouched (ledger-compensated so the cut set is unchanged), and the slack-drop pass reuses the loop's final state. SOLVER_DEBUG now reports probe productivity, per-round cut pivots, phase wall-clock marks, rc-fix counts, and per-heuristic pivot attribution. Case 020 end to end: 22.6s at session start, 9.0s after the tabu fix, 6.9s now (PuLP/CBC reference: 1.0s). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…sparse btran, factor arenas Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
Summary
Three-commit performance push on the target MILP workload: 020 goes 9.0s → 6.9s end to end (22.6s at the start of this effort; PuLP/real-CBC reference 1.0s), 016 2.3s → 0.5s, 018 2.8s → 1.2s, 021 5.6s → 4.7s. All 13 golden cases green throughout.
simplex — hypersparse BTRAN (activation-graph guarded, bitwise-identical to the dense path, A/B property-tested), in-place sparse-LU row elimination (−31% time / −74% bytes on ColdSolve microbench), fused pivot passes, and int32/arena-consolidated factors with per-LP shared solve scratch (020 end-to-end allocations 1.54GB → 1.21GB).
mip — the structural centerpiece plus cut/heuristic work:
Measured dead ends documented along the way: event-terminated cut rounds, maxEtas 64/128, fixed-column pricing skips, DSE re-test — all regress or fail 020.
Test plan
go test ./...green; gofmt clean; every commit builds standalone🤖 Generated with Claude Code