Skip to content

Require a power-of-two block_size for MergeSort - #173

Merged
maleadt merged 1 commit into
JuliaGPU:mainfrom
AzamatB:ab/merge-sort-pow2-block-size
Oct 27, 2026
Merged

maleadt merged 1 commit into
JuliaGPU:mainfrom
AzamatB:ab/merge-sort-pow2-block-size

Conversation

@AzamatB

@AzamatB AzamatB commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

The merge tile kernel sorts a tile of 2 * block_size elements in passes that double the run length while it is at most block_size, and hands runs to threads as if the run length divided block_size. With any other block_size, part of each tile is never merged, and the last pair of runs reaches past the tile in local memory. MergeSort's field check accepted any positive size, and its docstring said so. On main, sort!, sortperm! and sort_by_key! with e.g. MergeSort(block_size=3) return wrong orders. With block_size=96 they corrupt the data or hit CUDA_ERROR_ILLEGAL_ADDRESS once the input spans a few tiles.

This PR rejects such sizes with an ArgumentError, as BitonicSort and RadixSort already do. Resolution checks the fields after filling them from the tuning, so a tuned merge_block_size is checked too. The default of 256, and the power of two it shrinks to for large elements, are unaffected.

Supporting any block size in the kernel would take more passes and guards against the tile's end. That isn't worth it for a setting that is a power of two in practice.

Fixes #172.

The merge tile kernel sorts a tile of 2 * block_size elements in passes
that double the run length while it is at most block_size, and hands
runs to threads as if the run length divided block_size. Any other
block_size leaves part of each tile unmerged and indexes local memory
past the tile: sort!, sortperm! and sort_by_key! returned wrong orders,
or hit an illegal address once the input spanned more than a few tiles.

Check for a power of two in MergeSort's field checks, as BitonicSort
and RadixSort do. Resolution runs them after filling the fields from
the tuning, so a tuned block size is checked too.

Fixes JuliaGPU#172.
@maleadt
maleadt force-pushed the ab/merge-sort-pow2-block-size branch from 490789a to 613e08f Compare October 26, 2026 19:03
@maleadt

maleadt commented Oct 26, 2026

Copy link
Copy Markdown
Member

Rebased and slightly reworked.

@maleadt
maleadt merged commit f071b79 into JuliaGPU:main Oct 27, 2026
34 of 35 checks passed
@AzamatB
AzamatB deleted the ab/merge-sort-pow2-block-size branch October 28, 2026 03:12
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.

MergeSort with a block_size that is not a power of two sorts wrongly or throws a BoundsError

2 participants