Conversation
row_reduce_alloc(A, group, m_out) / row_reduce_fill_values(A, C) replace the sum_row_partition_alloc slot: C[j, :] = sum of rows i with group[i] == j. The input-nnz to output-position map lives on the result (bound_iwork), so the sum atom no longer owns an idx_map sized by the child's nnz. One generic kernel per kind replaces the three axis-specific ones: sparse builds the per-row column union with a marker array; permuted_dense keeps col_perm and collapses hit groups into a sorted row_perm; stacked_pd reduces per block and coalesce-accumulates, so sum of a stacked_pd child is now stacked_pd for every axis instead of a 1-row pd (axis -1) or a CSR fallback (axes 0/1). Deleted: the slot, sparse_sum_row_partition_alloc, the three CSR row-sum helpers, the three pd helpers and dispatcher, the spd fallback, and sum_expr.idx_map. The profile_log_reg baseline is ported to the primitive. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B6Bs765i1HTbqx3LUu6LMP
…cludes) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B6Bs765i1HTbqx3LUu6LMP
sum_all_rows_csr_alloc, sum_block_of_rows_csr_alloc and sum_evenly_spaced_rows_csr_alloc are standalone CSR operations worth keeping for a sparse linear algebra library even though the engine no longer calls them; tile_int likewise. Moved verbatim into the old-code folder, which is still compiled. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B6Bs765i1HTbqx3LUu6LMP
…+ col_to_pos Positions below the current row start mean "not in this row yet", so the same n-long array serves as the membership marker and, after sorting, as the column-to-position map. Saves one n-long transient at init. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B6Bs765i1HTbqx3LUu6LMP
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
Lesson 3, milestone 3. Stacked on #123 (the
problem_jacobianfix), which its problem-level test depends on; retarget tomainonce #123 merges.row_reduce_alloc(A, group, m_out)/row_reduce_fill_values(A, C):C[j, :]is the sum of rowsiofAwithgroup[i] == j. The input-nnz to output-position map is bound to the result (bound_iwork), so the fill takes no map. Fills zero the output and accumulate, never bumpvalues_version(the eval wrapper does), and are safe under the affine skip.sumbuildsgroupfrom its axis (0,i / d1,i % d1over the child's column-major rows) and calls the primitive.sum_expr.idx_mapandfree_type_dataare gone.col_permand collapses the hit groups into a sortedrow_perm; stacked_pd reduces per block and goes through the existing coalesce-accumulate skeleton, keeping the raw spd onpre_coalesce.sumof a stacked_pd child is stacked_pd for every axis. Previously axis -1 gave a 1-row pd and axes 0/1 fell back to CSR. Trade-off: the merged block takes the column union per row signature, so non-kron-shaped spd children can carry structural zeros where the CSR fallback had exact nnz (same trade-off astranspose_spd).sum_row_partition_alloc(slot, typedef, doc),sparse_sum_row_partition_alloc,sum_all_rows/sum_block_of_rows/sum_evenly_spaced_rows_csr_alloc, the three pd helpers plus dispatcher, the spd fallback, and two dead includes instacked_pd.c.accumulator, the trace helpers,sum_4_csr_alloc,compose_csr_idx_map_for_spdandsorted_union_int_arraysstay (other callers).tests/profiling/profile_log_reg.h: the manual "Path B" baseline now uses the primitive on the PD (note: it times the dense reduce rather than the CSR accumulator). Values still match Path A to 0.Tests
tests/utils/test_row_reduce.h: sparse (column merge, empty output row, NaN-poisoned fill proving the memset, refill), pd (non-monotone collapsing group,bound_iwork, twin match), spd cross-block accumulate on a shared column, spd within-block routing, spd all-to-one, and an alloc-free spd fill underSP_TRACK_MEMORY.sumof a 2-block spd child for axes -1/0/1 assertingis_stacked_pdplus numerical Jacobian check; axis 1 also checked exactly through the CSR view.sum(A @ X, axis=1)as a constraint reaches the aggregated Jacobian in row order.idx_map.457 tests Release, 460 with SP_TRACK_MEMORY. UBSan, guard-malloc + leaks, PROFILE_ONLY (built and run), clang-format clean. Mutation checks, each rebuilt in isolation: dropping the sparse memset, reading the wrong pd source row, plain scatter instead of accumulate in the spd fill, and swapping the atom's axis formulas all fail the suite.
🤖 Generated with Claude Code
https://claude.ai/code/session_01B6Bs765i1HTbqx3LUu6LMP