Compact permuted_dense (no inverse-permutation arrays) for kron-path blocks - #108
Draft
Transurgeon wants to merge 1 commit into
Draft
Compact permuted_dense (no inverse-permutation arrays) for kron-path blocks#108Transurgeon wants to merge 1 commit into
Transurgeon wants to merge 1 commit into
Conversation
…blocks Every permuted_dense allocated col_inv (global n ints) and row_inv (global m ints) at construction. On the dense left_matmul kron path this metadata dominates: p independent blocks each carry a full n_vars-sized col_inv, O(p*n_vars + p^2*m0) ints per node against exact-nnz values (5.9 GB engine peak on the OptimalAdvertising benchmark where true nnz needs ~5 MB). This introduces a compact PD variant whose storage stays proportional to the block rather than the global shape, scoped to the kron-csc family: - new_permuted_dense_compact leaves both inverse arrays NULL; the default constructor is unchanged, so every other PD keeps today's layout and O(1) code paths. - BA_pd_csc_alloc builds its output compact, and compactness propagates through copy_sparsity/transpose/index chains of compact sources. - Init-path membership tests (idxs_hits_set callers, index_pd_alloc) gate on a NULL inv and fall back to binary-search scans of the sorted perms (sorted_pos / sorted_hits in utils). - Eval-path consumers ensure the operand-side array at alloc time only when the product is non-empty (permuted_dense_ensure_col_inv / _row_inv), keeping every fill kernel untouched (asserted in BA_pd_csc_fill_values); index_pd_fill_values of a compact source reads a source-row map precomputed into kernel_iwork at alloc. - The mutable kron scratch keeps its arrays (its kernels write col_inv). New peak-memory regression test builds the row-sum + col-sum Jacobian shape at 128x128: init peak drops from 1324 to 292 bytes/var (21.7 MB to 4.8 MB); the test asserts < 400 bytes/var. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Transurgeon
force-pushed
the
lazy-inv-arrays
branch
from
August 2, 2026 23:16
12d8c9d to
960e02b
Compare
Transurgeon
marked this pull request as draft
August 3, 2026 00:39
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.
Every
permuted_denseallocatedcol_inv(globalnints) androw_inv(globalmints) at construction. On the denseleft_matmulkron path this metadata dominates: p independent blocks each carry a full n_vars-sizedcol_inv,O(p*n_vars + p^2*m0)ints per node against exact-nnz values — 5.9 GB engine peak on OptimalAdvertising where true nnz needs ~5 MB.Change
This introduces a compact PD variant — storage proportional to the block, not the global shape — scoped to the kron-csc family:
new_permuted_dense_compactleaves both inverse arrays NULL; the default constructor is untouched, so every non-kron PD keeps today's layout and code paths.BA_pd_csc_allocbuilds its output compact; compactness propagates throughcopy_sparsity/transpose/indexchains of compact sources.idxs_hits_setcallers,index_pd_alloc) gate on NULL and fall back to binary-search scans of the sorted perms (sorted_pos/sorted_hits).permuted_dense_ensure_col_inv/_row_inv), so every fill kernel is untouched —BA_pd_csc_fill_valuesasserts the contract (inv != NULL || C->n0 == 0);index_pd_fill_valuesof a compact source reads a source-row map precomputed intokernel_iwork.col_inv).Verification
leaksclean). New peak-memory regression test (row-sum + col-sum Jacobian at 128x128): init peak 1324 -> 292 bytes/var (21.7 MB -> 4.8 MB), asserted < 400 bytes/var.get_problem_data, CLARABEL): CVaR, SDP, Huber, TvInpainting, QuantumHilbertMatrix MATCH exactly; OptimalAdvertising matches except one pre-existing NaN-constant-folding difference (identical on the baseline engine).BA_pd_pd_alloc/BTA_pd_spd_allocoutputs are still full by scope). Extending compactness there is the natural follow-up.Before merge
🤖 Generated with Claude Code