Skip to content

[Metal] gather_qmm improvement - #4572

Merged
nastya236 merged 3 commits into
mainfrom
gather-qmm-tiling
Sep 28, 2026
Merged

nastya236 merged 3 commits into
mainfrom
gather-qmm-tiling

Conversation

@nastya236

Copy link
Copy Markdown
Collaborator

Same as in #4567

Given #4567 I asked Claude code to do the same for gather_qmm.

qwen3.5-397b-a17b:

Format N Before (ms) After (ms) Speedup
affine 512 8.08497 6.24240 1.30×
affine 713 8.75225 6.61468 1.32×
affine 1024 9.76828 7.38171 1.32×
affine 2048 13.55017 11.41791 1.19×
affine 4123 21.36925 16.61189 1.29×
affine 8192 36.69587 28.45843 1.29×
affine 16384 65.42287 53.63210 1.22×
nvfp4 512 8.23671 6.29423 1.31×
nvfp4 713 8.81961 6.66266 1.32×
nvfp4 1024 9.88744 7.52525 1.31×
nvfp4 2048 13.53901 11.54110 1.17×
nvfp4 4123 21.34495 16.66406 1.28×
nvfp4 8192 36.87975 28.73714 1.28×
nvfp4 16384 65.41614 54.00811 1.21×
mxfp8 512 12.06362 9.16402 1.32×
mxfp8 713 12.67015 9.46002 1.34×
mxfp8 1024 13.90283 10.22280 1.36×
mxfp8 2048 19.21845 14.19822 1.35×
mxfp8 4123 28.60970 19.87559 1.44×
mxfp8 8192 47.65744 33.30466 1.43×
mxfp8 16384 80.14714 60.24049 1.33×

@zcbenz zcbenz left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@nastya236
nastya236 merged commit 9008944 into main Sep 28, 2026
29 checks passed
@nastya236
nastya236 deleted the gather-qmm-tiling branch September 28, 2026 11:39
davidtai pushed a commit to Layr-Labs/mlx that referenced this pull request Sep 28, 2026
davidtai added a commit to Layr-Labs/mlx that referenced this pull request Oct 6, 2026
… call

The gather_qmm row-tile backport (ml-explore/mlx ml-explore#4572) makes the sorted
gather_qmm_rhs kernels read per-expert offsets. Those kernels give a
correct result only for sorted indices. Before the backport, the kernel
read the index of each row, so the expert-tile route could send a call
with unsorted indices (a sortedness retract) to it.

gather_qmm_rhs now returns false for a retracted call, and
GatherQMM::eval_gpu then runs the unsorted gather route. All other calls
are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Gajesh2007 pushed a commit to Layr-Labs/mlx that referenced this pull request Oct 6, 2026
…explore/mlx ml-explore#4567, ml-explore#4572) (#27)

* [Metal] Gather mm improvement (ml-explore#4567)

(cherry picked from commit a2a09fd)

* docs(forkdiff): describe the upstream gather_mm row-tile backport

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

* [Metal] gather_qmm improvement  (ml-explore#4572)

(cherry picked from commit 9008944)

* fix(metal): run the unsorted gather route for a retracted expert-tile call

The gather_qmm row-tile backport (ml-explore/mlx ml-explore#4572) makes the sorted
gather_qmm_rhs kernels read per-expert offsets. Those kernels give a
correct result only for sorted indices. Before the backport, the kernel
read the index of each row, so the expert-tile route could send a call
with unsorted indices (a sortedness retract) to it.

gather_qmm_rhs now returns false for a retracted call, and
GatherQMM::eval_gpu then runs the unsorted gather route. All other calls
are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Anastasiia Filippova <a_filippova@apple.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
davidtai added a commit to Layr-Labs/mlx that referenced this pull request Oct 7, 2026
Bring in #27, the gather_mm and gather_qmm row-tile scheduling backport
(ml-explore/mlx ml-explore#4567, ml-explore#4572).

- quantized_nax.h, affine_gather_qmm_rhs_nax: take main's kernel. Each
  threadgroup now holds rows of one expert (schedule_row_tile), so the
  per-tile expert-segment loop is gone. This branch's segment elision
  ran inside that loop. Without the loop, seg_lo is 0 and seg_hi is
  sgp_sm, so seg_partial is always false and seg_empty equals main's
  !sg_active. The sorted-endpoint probe has no probe to skip. Remove
  kGatherRhsSegmentElide, kGatherRhsSortedEndpointElide and the
  gather_rhs_load_frag_row / gather_rhs_mma_frag_row helpers, which have
  no caller. Keep this branch's row-strip simdgroup layout (SGM/SGN,
  DARKBLOOM_GEMMA4_NAX_GATHER_TILING) on main's kernel, and rewrite the
  note about how it composes with the row-tile schedule.
- fork.yaml: auto-merged; replace the segment-elision bullet with the
  row-strip layout of the NAX qmm_t and gather-rhs kernels.
- quantized.h: auto-merged; main changed the gather_qmm_rhs kernels and
  this branch changed the QMV kernels, which do not overlap.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
jonathan308 added a commit to Layr-Labs/mlx that referenced this pull request Oct 10, 2026
Upstream ml-explore/mlx c7ff35d ("Skip unnecessary simdgroup
computations for quantised MOE matmuls on NAX", ml-explore#4352) reached this fork
through the v0.32.2 squash (734241b), not by ancestry, in the form that
ml-explore#4572 later gave it: `const bool sg_active = sgp_sm > 0;` and two
`if (sg_active)` blocks around the MMA loop in each of
fp_gather_qmm_rhs_nax (fp_quantized_nax.h) and affine_gather_qmm_rhs_nax
(quantized_nax.h). This removes the flag and runs the MMA in every
simdgroup again, as before ml-explore#4352. It is the same change as the earlier
revert of ml-explore#4352 on 0.32.2 (e9debbe) and its re-application on the
0.32.3 kernels, hand-ported because the surrounding lines differ here.

Why: these kernels run only on GPUs with NAX. On a two-Mac JACCL pair
with one NAX GPU, mixture-of-experts serving with the skip present lost
all-reduce completions, and 92 to 96 GiB stayed wired on the host until
it was rebooted. The builds that served that pair afterwards carried the
revert. It is therefore kept out of every build that runs distributed on
mixed hardware.

Output is unchanged: stores stay bounded by sgp_sm, and the rows past
the tile that the MMA now reads are either inside M (rows_in_bounds) or
loaded as zeros by load_safe with sgp_sm rows.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

2 participants