Skip to content

Unify row_mul_mat! and row_mul_vec! into single methods#2545

Open
imreddyTeja wants to merge 1 commit into
mainfrom
tr/unified-column-helpers-main
Open

Unify row_mul_mat! and row_mul_vec! into single methods#2545
imreddyTeja wants to merge 1 commit into
mainfrom
tr/unified-column-helpers-main

Conversation

@imreddyTeja

@imreddyTeja imreddyTeja commented Jul 11, 2026

Copy link
Copy Markdown
Member

Note

The commit in this PR was authored by Claude (Claude Code), working on behalf of @imreddyTeja.

Summary

ext/cuda/column_matrix_helpers.jl contained 8 nearly identical row_mul_mat! methods (one per pair of matrix staggering shapes) and 4 nearly identical row_mul_vec! methods. This PR replaces them with one method each, shrinking the file from 431 to 119 lines (−376/+65).

The per-shape index arithmetic is factored into three small compile-time shape-trait helpers:

  • column_slot(v, d, shape) — converts entry d of the matrix row computed by thread v into the shared-memory slot of the value it multiplies (v + d, with ±half corrections for the mixed-staggering shapes)
  • n_column_slots(shape) — number of valid slots in the matrix's column space (blockDim().x for face columns, one fewer for center columns)
  • product_shape(shape1, shape2) — the shape of matrix1 * matrix2, used for the product-row bounds check in row_mul_mat!

All shapes are singleton types, so everything still resolves at compile time.

One deliberate behavior nuance: in the two CenterToFace-product cases, the old outer bounds check (v + pd + half < 1) admitted product column 0, which lies outside the matrix. The unified slot-based check zeroes that entry instead, matching the CPU reference multiply_matrix_at_index in src/MatrixFields/matrix_multiplication.jl.

Performance

This change is performance neutral. The unified helpers compile down to essentially the same machine code as the 12 hand-written methods: generated PTX is bit-identical for the same-staggered shape combinations (after normalizing session-dependent pointer constants and label numbering), and the mixed-staggering combinations differ only by register renumbering and equivalent bounds computations (e.g. < blockDim vs <= blockDim - 1), with equal or slightly lower register counts. Measured A100 kernel timings across all 12 shape combinations plus a chained product are unchanged (within run-to-run noise).

Verification (on an A100)

  • All test/MatrixFields/matrix_fields_broadcasting scripts (scalar 1–17, non-scalar 1–5) produce identical results before and after the refactor.
  • Per-case GPU kernel timings across all 12 shape combinations plus a chained product are unchanged (within run-to-run noise).
  • Generated PTX is bit-identical for the same-staggered shape combinations; the mixed-staggering combinations differ only by register renumbering and equivalent bounds computations (e.g. < blockDim vs <= blockDim - 1), with equal or slightly lower register counts.

🤖 Generated with Claude Code

https://claude.ai/code/session_011oirTEPPBEj5BWwhgYKMzn

@imreddyTeja imreddyTeja self-assigned this Jul 11, 2026
Replace the 8 row_mul_mat! methods and 4 row_mul_vec! methods in
ext/cuda/column_matrix_helpers.jl with one method each, driven by small
shape-trait helpers (column_slot, n_column_slots, product_shape) derived
from the AbstractMatrixShape types. Product-row entries outside the
product matrix are zeroed, matching multiply_matrix_at_index on the CPU.

Verified on GPU (A100): all matrix_fields_broadcasting tests pass, and
kernel timings/PTX are unchanged from the multi-method version.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011oirTEPPBEj5BWwhgYKMzn
@imreddyTeja imreddyTeja force-pushed the tr/unified-column-helpers-main branch from 97ce300 to d2a3537 Compare July 13, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant