Skip to content

Optimize Radix Sort.#97

Draft
shreyas-omkar wants to merge 2 commits into
JuliaGPU:mainfrom
shreyas-omkar:sh/radix-optim-no-ballot
Draft

Optimize Radix Sort.#97
shreyas-omkar wants to merge 2 commits into
JuliaGPU:mainfrom
shreyas-omkar:sh/radix-optim-no-ballot

Conversation

@shreyas-omkar

Copy link
Copy Markdown
Member

CUDA (RTX 5080), 4M elements

Type AK radix (ms) torch.sort (ms) AK / torch
UInt32 1.11 0.49 2.25×
Float32 1.12 0.49 2.31×
UInt64 1.85 1.35 1.37×
Float64 1.68 1.33 1.27×

AMD (RX 9060 XT), 4M elements

Type AK radix (ms) torch.sort (ms) AK / torch
UInt32 2.74 1.83 1.50×
Float32 2.76 1.75 1.58×
UInt64 5.70 5.84 0.98×
Float64 5.84 4.43 1.32×

shreyas-omkar and others added 2 commits July 8, 2026 04:29
_accumulate_block!'s inclusive path re-read global `v` from inside a
single-thread branch after the scan barriers — a divergent global read
that faults or hangs on backends other than CUDA. Capture everything the
inclusive shift needs at load time (each thread's own last element, plus
the array's final element in a shared slot) so no divergent global read
remains. Fixes accumulate!/cumsum and the GPU radix sort (which relies on
accumulate!) on non-CUDA backends.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Rework the opt-in GPU LSD radix sort to be fast and portable across
backends, with no dependency on sub-group / warp intrinsics:

- Shared-atomic histogram (O(1)/element) where the backend reports
  shared-memory atomics support; portable per-bucket scan otherwise.
- Chunked stable scatter rank: O(32)/element instead of O(block_size),
  via per-chunk sub-histograms plus a cross-chunk exclusive prefix;
  gated on atomics support, broadcast-scan fallback otherwise.
- block_size default 256 (the scatter rank cost scales with block_size,
  so this is the portable sweet spot).
- Fused min/max range in one reduction; skip passes where every element
  shares a byte; reuse the accumulate! scratch across passes; a single
  final sync instead of per-kernel syncs.

Supports UInt32/64, Int32/64, Float32/64; custom lt/by fall back to
merge_sort!. Correct across all types, sizes and directions. On backends
without sub-group ballot, radix now beats merge_sort for every supported
type (previously slower on several). Adds Atomix as a dependency.

Co-Authored-By: Claude Sonnet 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.

1 participant