Skip to content

Add hybrid sorting with [HybridSortingNetwork] attribute#108

Open
jonathanpeppers wants to merge 8 commits into
mainfrom
jonathanpeppers/avx512-hybrid-sort
Open

Add hybrid sorting with [HybridSortingNetwork] attribute#108
jonathanpeppers wants to merge 8 commits into
mainfrom
jonathanpeppers/avx512-hybrid-sort

Conversation

@jonathanpeppers
Copy link
Copy Markdown
Owner

@jonathanpeppers jonathanpeppers commented May 3, 2026

Adds a new [HybridSortingNetwork] attribute and source generator pipeline that generates hybrid quicksort methods (Sort, PartialSort, NthElement) for arbitrary-size arrays, using sorting networks as the base case for small sub-arrays.

What's included

  • HybridSortingNetworkAttribute — new attribute (like [SortingNetwork] but for arbitrary sizes)
  • HybridSortEmitter — source generator emitter producing:
    • Sort(Span<T>) / Sort(T[]) — full hybrid quicksort
    • PartialSort(Span<T>, int k) — sort only first k elements
    • NthElement(Span<T>, int n) — quickselect for nth element
    • 3-way partitioning (Dutch National Flag) with median-of-three pivot
    • Introsort depth limit (2 * log2(n)) with MemoryExtensions.Sort() fallback for O(n log n) worst case
    • Sorting network base case for sizes 2-64
  • Generator pipeline in SortingNetworkGenerator with deduplication, fully-qualified hint names
  • 486 tests passing (42 new: 36 functional + 6 generator compilation)
  • Benchmarks for int and long hybrid sort

Benchmark results (Ubuntu x64, .NET 10)

Hybrid sort vs Array.Sort baseline — the hybrid sort is a scalar quicksort (no SIMD partitioning yet), so it's expected to be slower than BCL for most sizes. The value is in the API surface and sorting network base case:

Size Random Sorted Reversed Duplicates
32 16.0x 16.0x 20.6x 14.7x
64 17.8x 21.4x 21.3x 22.0x
100 12.7x 24.6x 14.9x 11.8x
1,000 1.51x 3.58x 1.78x 1.42x
10,000 1.16x 5.05x 2.05x 0.35x 🎉

At 10k elements with duplicates, hybrid sort wins (0.35x = ~3x faster) thanks to 3-way partitioning skipping equal elements.

Existing [SortingNetwork] benchmarks show no regression — all ratios unchanged from main.

What's NOT included (future work)

Review fixes addressed

  • Fixed PartialSort(span, 1) being a no-op (k <= 1 changed to k <= 0)
  • Fixed network data allocation (static readonly arrays instead of property accessors)
  • Added introsort depth limit with MemoryExtensions.Sort() fallback
  • Added HashSet deduplication for type requests
  • Fixed hint name collisions with fully-qualified namespace.class chain
  • Removed incorrect AVX-512 claim from XML docs
  • Added full type coverage: byte, sbyte, short, ushort, int, uint, long, ulong, char, float, double

Implement a hybrid quicksort that uses 3-way partitioning for large
arrays (n > 64) and sorting-network base cases for small sub-arrays
(n <= 64). This allows sorting arrays of any size without requiring
user-supplied OnFallback methods.

New features:
- [HybridSortingNetwork(typeof(T))] attribute for code generation
- Sort(Span<T>) / Sort(T[]) for arbitrary-length arrays
- PartialSort(Span<T>, int k) for top-k sorting
- NthElement(Span<T>, int n) for quickselect
- 3-way Dutch National Flag partition (handles duplicates well)
- Embedded optimal sorting network data for sizes 2-64
- Support for int, byte, short, long, float, double types
- HybridSortEmitter generates all code via source generator

SIMD partition using AVX-512F Compress / AVX-512 VBMI2 Compress is
scaffolded as a future optimization on top of the scalar partition.

Resolves #34

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 3, 2026 01:20
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new hybrid-sorting source-generation path alongside the existing fixed-size sorting-network generator. It introduces a [HybridSortingNetwork] attribute intended to generate Sort, PartialSort, and NthElement APIs for arbitrary-length inputs by combining quicksort-style partitioning with sorting-network base cases.

Changes:

  • Adds a new public [HybridSortingNetwork(typeof(T))] attribute in the runtime package.
  • Extends the incremental generator with a hybrid pipeline and a new HybridSortEmitter.
  • Adds generator tests and end-to-end tests for generated hybrid sorters.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
SortingNetworks/HybridSortingNetworkAttribute.cs Adds the new public attribute that opts classes into hybrid sort code generation.
SortingNetworks.Tests/HybridSorter.cs Declares a test partial class annotated with the new hybrid attribute for several primitive types.
SortingNetworks.Tests/HybridSortTests.cs Adds functional tests for generated hybrid Sort, PartialSort, and NthElement APIs.
SortingNetworks.Tests/GeneratorTests.cs Adds generator-compilation assertions for hybrid source emission.
SortingNetworks.Generators/SortingNetworkGenerator.cs Registers and wires a second incremental pipeline for hybrid generation.
SortingNetworks.Generators/HybridSortEmitter.cs Implements hybrid code emission, including quicksort/select logic and embedded network data.

Comment thread SortingNetworks.Generators/SortingNetworkGenerator.cs
Comment thread SortingNetworks.Generators/SortingNetworkGenerator.cs
Comment thread SortingNetworks.Tests/HybridSortTests.cs
Comment thread SortingNetworks.Tests/HybridSorter.cs
Comment thread SortingNetworks.Generators/SortingNetworkGenerator.cs
Comment thread SortingNetworks/HybridSortingNetworkAttribute.cs Outdated
Comment thread SortingNetworks.Generators/HybridSortEmitter.cs
Comment thread SortingNetworks.Generators/HybridSortEmitter.cs Outdated
Comment thread SortingNetworks.Generators/HybridSortEmitter.cs Outdated
Comment thread SortingNetworks.Generators/HybridSortEmitter.cs Outdated
jonathanpeppers and others added 3 commits May 2, 2026 21:29
Add HybridIntSortingBenchmarks (sizes 32-10000, all InputKinds) and
HybridLongSortingBenchmarks (sizes 32-10000, Random) to measure
hybrid quicksort with sorting-network base cases against Array.Sort
and Span.Sort baselines.

- Add HybridSorters class with [HybridSortingNetwork] for int and long
- Update CI benchmark summary to describe hybrid benchmarks correctly

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Fix PartialSort(span, 1) bug: k<=1 early return changed to k<=0
  so k=1 correctly places the minimum element at index 0
- Fix network data allocation: use static readonly arrays instead of
  ReadOnlySpan property accessors that allocated per call
- Add introsort depth limit (2*log2(n)) with fallback to span.Sort()
  to guarantee O(n log n) worst case
- Deduplicate type requests in hybrid generator (HashSet<SpecialType>)
- Use fully qualified hint name (namespace.class) to avoid collisions
- Handle nested classes in hint name generation
- Fix XML doc: remove AVX-512 SIMD claim (not yet implemented)
- Add HybridSortingNetworkAttribute to PublicAPI.Unshipped.txt
- Add PartialSort k=1 test
- Add tests for sbyte, ushort, uint, ulong, char types
- Add HybridSorter coverage for all supported primitive types
- Merge main branch

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
jonathanpeppers and others added 4 commits May 3, 2026 14:34
Resolve merge conflicts in SortingNetworkGenerator.cs and GeneratorTests.cs,
keeping both hybrid sort methods and IEquatable/incremental caching changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Add decimal element size (16 bytes) in HybridSortEmitter.GetElementSize
- Add [HybridSortingNetwork(typeof(decimal))] to test fixture
- Add Sort_Decimal_200Elements functional test
- Add decimal to HybridSort_GeneratesCode generator test

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve PublicAPI.Unshipped.txt conflict: keep only new
HybridSortingNetworkAttribute entries since SortingNetworkAttribute
was shipped to PublicAPI.Shipped.txt on main.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.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.

2 participants