Skip to content

OneSweep: size the tile for the adapter's narrowest subgroups - #110

Open
jowens wants to merge 1 commit into
mainfrom
narrow-subgroups
Open

jowens wants to merge 1 commit into
mainfrom
narrow-subgroups

Conversation

@jowens

@jowens jowens commented Nov 11, 2026

Copy link
Copy Markdown
Collaborator

OneSweep sorted wrongly on adapters whose subgroups can be 8 lanes wide (llvmpipe reports 8; Intel GPUs report 8 to 32), and so did everything built on it (SuffixArray).

Why. onesweep_pass stages each subgroup's digit histogram (RADIX = 256 counts) in the tile, so the tile (KEYS_PER_THREAD × 256 keys) must hold (256 / subgroup width) × 256 entries: KEYS_PER_THREAD ≥ 256 / width. The floor took the width as max(32, subgroupMinSize), so it assumed 32 lanes (8 keys per thread) whatever the adapter reported. With 8-lane subgroups the pass needs 32 keys per thread and got the default 15.

Fix.

  • The floor uses the narrowest width the adapter reports (subgroupMinSize), and the default keys per thread is raised to it (16-lane: 16).
  • 8 lanes need 32 keys per thread, a 32 KB tile of 32-bit keys, which doesn't fit with the pass's other workgroup memory. When the narrowest subgroups' tile can't fit, OneSweep emulates 32-lane subgroups instead: slower, but correct (CI already runs the whole suite emulated).
  • SUBGROUP_MIN_SIZE, which sizes the scan's workgroup memory, is now the width that will run: 32 when emulated (it took the adapter's value even when emulating, or RADIX when unknown).

Devices whose subgroups are 32 lanes or wider (NVIDIA, Apple, AMD) are unchanged: same keys per thread, hardware subgroups.

Test. A regression test checks the choice for adapters reporting 4- to 64-lane subgroups (keys per thread, hardware or emulated, the scan width), without running a sort, so it runs on any device. It fails without the fix.

Note: on llvmpipe, emulated subgroups are very slow (they spin-wait between invocations, which a CPU runs one at a time), so OneSweep there is now correct but impractically slow, rather than wrong.


Generated by Claude Code

…e if it cannot fit

Each subgroup's histogram is staged in the tile, so KEYS_PER_THREAD must be
at least RADIX / subgroup width. The floor assumed 32 lanes whatever the
adapter reported, so with 8-lane subgroups (llvmpipe; Intel reports 8 to 32)
the default 15 keys per thread sorted wrongly (it needs 32). Now the floor
uses subgroupMinSize, the default is raised to it (16-lane: 16), and where
the narrowest subgroups' tile cannot fit workgroup memory OneSweep emulates
32-lane subgroups instead. SUBGROUP_MIN_SIZE (which sizes the scan memory)
is now the width that will run: 32 when emulated. Test: the choice for
4- to 64-lane adapters, which fails without the fix.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015kfNC6id65zEHzuAAH4jtJ

This branch has not been deployed

No deployments
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