Repository navigation
OneSweep: fix global_hist layout when KEY_BITS < key width - #53
Merged
Merged
Conversation
global_hist always builds one 256-bucket histogram per 8-bit digit of the full key (4 for 32-bit keys, 8 for 64-bit keys), but laid out its per-segment workgroup-memory histograms with stride RADIX * SORT_PASSES and sized hist[] as SORT_PASSES * RADIX. With KEY_BITS < bits per key (SORT_PASSES < digits per key), the second segment overlaps the first segment's upper-digit region and the low-digit histograms are corrupted, so the sort produces wrong results. Default configurations (KEY_BITS = full key width) are unchanged: DIGITS_PER_KEY == SORT_PASSES there. - add DIGITS_PER_KEY (JS + WGSL); ALL_RADIX = RADIX * DIGITS_PER_KEY - histSize = DIGITS_PER_KEY * RADIX * 4; passHistSize keeps SORT_PASSES segments - CPU reference histogram in validate() covers every digit Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015kfNC6id65zEHzuAAH4jtJ
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.
OneSweep: fix
global_histhistogram layout whenKEY_BITSis less than the key widthProblem
global_histalways builds one 256-bucket histogram per 8-bit digit of the full key: 4 for 32-bit keys, 8 for 64-bit keys. The digit offsets are hard-coded (+256u,+512u,+768u, …). But the per-segment workgroup-memory histograms were laid out with strideALL_RADIX = RADIX * SORT_PASSES, andhist[]was sized asSORT_PASSES * RADIX.With
KEY_BITSsmaller than the key width (soSORT_PASSES< digits per key), segment 1 (threads 64–127) writes into segment 0's upper-digit region. The final reduction then adds the wrong counts into the low-digit histograms, and the global atomics intohist[]for the upper digits go out of bounds. The sort output is wrong. For example, a 32-bit keys-only sort withKEY_BITS: 16produces invalid output.The default configurations are unaffected, because there
KEY_BITSequals the key width andSORT_PASSES == digits per key.Fix
DIGITS_PER_KEY = ceil(bitsPerElement / RADIX_LOG)in JS and as a WGSL constant, and setALL_RADIX = RADIX * DIGITS_PER_KEY.histSize = DIGITS_PER_KEY * RADIX * 4.passHistSizestill usesSORT_PASSESsegments, which is allonesweep_scan/onesweep_passread.validate(), the CPU reference histogram now covers every digit, so it matches whatglobal_histwrites.For default configurations, every buffer size and the generated WGSL are unchanged, apart from the new constant and comments.
Testing
KEY_BITS32 and 16, u32 key-value with 8, i32 keys-only with 24, and u64 with 64 and 40.KEY_BITS16 and 24 (2 and 3 passes) at n = 2^22. Over 8 seeds, every output was a valid permutation with keys correctly ordered by their lowKEY_BITSbits. Without the change, all 2- and 3-pass runs were invalid; 4-pass runs were fine in both cases.Follow-up (not in this PR)
validate()compares against a full sort, so it can't yet check a sort withKEY_BITSless than the key width. That needs a stable-sort-by-low-bits reference, and then a regression case forKEY_BITS< key width.Generated by Claude Code