Skip to content

Shared subgroup digit match (GPU Multisplit Alg. 3); OneSweep's WLMS built on it - #78

Merged
jowens merged 1 commit into
mainfrom
subgroup-multisplit-core
Oct 24, 2026
Merged

jowens merged 1 commit into
mainfrom
subgroup-multisplit-core

Conversation

@jowens

@jowens jowens commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator

Step 2 of the GPU Multisplit plan: factor out the ballot-based digit match, Algorithm 3 of Ashkiani et al. and the core of OneSweep's WLMS, so that a stable multisplit can reuse it.

  • subgroupDigitMatch({ key, shift, bits, rank, peer }) in wgslFunctions: one ballot per digit bit. It yields eq_mask (the lanes with my digit), <rank> (how many of them are below me) and <peer> (the highest of them). It emits statements rather than a function, so a caller's code is exactly what it would be if written inline.
  • subgroupLaneMasks() / subgroupLaneMaskLt(): the lane masks are u32, or vec4<u32> when the device's subgroups can be wider than 32. The choice is made when the WGSL is generated, as in OneSweep: support subgroups wider than 32 (AMD RDNA wave64) #75.
  • wideSubgroups moves from OneSweep to BasePrimitive.
  • OneSweep's WLMS is now one template built on these helpers, instead of separate 32-bit and wide copies.

Verification:

  • Generated code: I generated every OneSweep kernel before and after for subgroup ranges 32–32, 8–32, 32–64 and 4–128, with u32, i32, f32 and u64 keys, keys-only and key-value. With comments and whitespace removed, the WGSL is identical, so sort performance can't change.
  • Tests: on the simulated RDNA4 (gfx1201), all 82 small tests pass.

Generated by Claude Code

…WLMS built on it

subgroupDigitMatch (wgslFunctions) emits the ballot-based match that OneSweep's
WLMS used inline: for a digit of a key, the lanes of the subgroup with the
same digit, how many are below me, and the highest of them (Ashkiani et al.,
GPU Multisplit, Algorithm 3). It emits statements rather than a function, so
callers' code is as if written inline. subgroupLaneMasks/subgroupLaneMaskLt
supply the lane masks: u32, or vec4<u32> when the device's subgroups can be
wider than 32. wideSubgroups moves from OneSweep to BasePrimitive.

OneSweep's WLMS is now one template on these helpers instead of two copies.
Its generated WGSL, with comments and whitespace removed, is identical to
before for every configuration checked (subgroup ranges 32-32, 8-32, 32-64,
4-128; u32/i32/f32/u64; keys only and key-value), so sort performance is
unchanged. This is the core a stable multisplit can reuse.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kfNC6id65zEHzuAAH4jtJ
@jowens
jowens merged commit 2b0abbb into main Oct 24, 2026
4 checks passed
@jowens
jowens deleted the subgroup-multisplit-core branch October 24, 2026 05:23
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