Skip to content

feat(rocsparse): implement rocsparse_spsort for CSR matrices - #12556

Merged
jsandham merged 8 commits into
users/jsandham/spsort-coofrom
users/jsandham/spsort-csr
Oct 12, 2026
Merged

jsandham merged 8 commits into
users/jsandham/spsort-coofrom
users/jsandham/spsort-csr

Conversation

@jsandham

@jsandham jsandham commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Motivation

Adds CSR support to rocsparse_spsort. It sorts the column indices, and the corresponding values, within each row. The direction must be rocsparse_direction_row, and any other direction returns rocsparse_status_invalid_value. Out of place, in place and strided batched matrices are supported.

Batches must be uniform: every batch has the same sparsity pattern, so the column indices are sorted once and the resulting permutation is applied to the values of every batch.

Batch rules:

  • The columns/values batch stride must be at least nnz.
  • The offsets batch stride must be 0 (shared row pointer) or at least m + 1.
  • B may only share its row pointer if A does.

Changes:

  • Adds the internal rocsparse::csrsort_buffer_size and rocsparse::csrsort in the existing rocsparse_csrsort.cpp, which take the source and target sparse matrix descriptors like the COO ones. They wrap rocsparse::csxsort_buffer_size and rocsparse::csxsort, which CSC reuses in the next PR.
  • Turns the existing csrsort implementation in the same file into file local templates on the row pointer and column index types, dispatched on the index types right before the call. The rocsparse_csrsort C API now calls those templates.
  • Adds the mixed 32-bit key and 64-bit value segmented radix sort instantiations needed for 64-bit row pointers with 32-bit column indices.

Test plan

  • Built the library and ran example_rocsparse_spsort.
  • Ran the existing csrsort and cscsort tests (quick and pre_checkin).
  • Ran the spsort_csr tests added later in the stack against this library (quick and pre_checkin).

JIRA ID: AISPARSE-717

Stack

This PR is part of a stack. Review and merge in order:

  1. feat(rocsparse): add the rocsparse_spsort public API #12553
  2. feat(rocsparse): implement rocsparse_spsort for COO matrices #12555
  3. feat(rocsparse): implement rocsparse_spsort for CSR matrices #12556 ⬅ this PR
  4. feat(rocsparse): implement rocsparse_spsort for CSC matrices #12557
  5. test(rocsparse): add rocsparse_spsort tests and benchmarks for COO #12558
  6. test(rocsparse): add rocsparse_spsort tests and benchmarks for CSR #12559
  7. test(rocsparse): add rocsparse_spsort tests and benchmarks for CSC #12560

@codecov

codecov Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 39.78723% with 283 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...parse/library/src/conversion/rocsparse_csrsort.cpp 42.21% 231 Missing and 25 partials ⚠️
...sparse/library/src/conversion/rocsparse_spsort.cpp 0.00% 21 Missing ⚠️
...ry/src/conversion/rocsparse_spsort_buffer_size.cpp 0.00% 6 Missing ⚠️
Additional details and impacted files
@@                      Coverage Diff                      @@
##           users/jsandham/spsort-coo   #12556      +/-   ##
=============================================================
- Coverage                      72.06%   72.02%   -0.04%     
=============================================================
  Files                           2871     2871              
  Lines                         474479   474862     +383     
  Branches                       70065    70141      +76     
=============================================================
+ Hits                          341889   341981      +92     
- Misses                        108819   109094     +275     
- Partials                       23771    23787      +16     
Flag Coverage Δ *Carryforward flag
TensileLite-CPP 49.33% <ø> (ø) Carriedforward from ad34233
TensileLite-Unit 83.30% <ø> (ø) Carriedforward from ad34233
hipBLAS 90.62% <ø> (ø) Carriedforward from ad34233
hipBLASLt 38.91% <ø> (ø) Carriedforward from ad34233
hipCUB 82.68% <ø> (ø) Carriedforward from ad34233
hipDNN 86.66% <ø> (ø) Carriedforward from ad34233
hipFFT 43.43% <ø> (ø) Carriedforward from ad34233
hipRAND 76.12% <ø> (ø) Carriedforward from ad34233
hipSOLVER 68.96% <ø> (ø) Carriedforward from ad34233
hipSPARSE 86.99% <ø> (ø) Carriedforward from ad34233
rocBLAS 48.24% <ø> (ø) Carriedforward from ad34233
rocFFT 51.45% <ø> (ø) Carriedforward from ad34233
rocRAND 57.45% <ø> (ø) Carriedforward from ad34233
rocSOLVER 76.83% <ø> (ø) Carriedforward from ad34233
rocSPARSE 73.44% <39.79%> (-0.24%) ⬇️
rocThrust 93.15% <ø> (ø) Carriedforward from ad34233

*This pull request uses carry forward flags. Click here to find out more.

Files with missing lines Coverage Δ
...primitives/rocsparse_segmented_radix_sort_keys.cpp 69.03% <ø> (ø)
...rimitives/rocsparse_segmented_radix_sort_pairs.cpp 96.15% <ø> (ø)
...ry/src/conversion/rocsparse_spsort_buffer_size.cpp 0.00% <0.00%> (ø)
...sparse/library/src/conversion/rocsparse_spsort.cpp 0.00% <0.00%> (ø)
...parse/library/src/conversion/rocsparse_csrsort.cpp 45.22% <42.21%> (-47.88%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jsandham
jsandham removed this pull request from stack #12562 September 24, 2026 22:14
@jsandham
jsandham force-pushed the users/jsandham/spsort-csr branch from 5ec8b02 to 960a065 Compare September 24, 2026 22:14
@jsandham
jsandham added this pull request to stack #12575 September 24, 2026 22:15
@therock-pr-bot

therock-pr-bot Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

⏳ Waiting on Required Checks

⏳ Required checks have not all concluded yet. This bot run is exiting without failing so those checks can report independently.

Check Status Details
📝 PR Description ✅ Pass —
⛔ Forbidden Files ✅ Pass —
🧪 Unit Test ⚠️ Warning Error: Source/code files changed without an accompanying unit test.
Expected: add at least one test file named like test_<name>.py / test_<name>.cpp (or <name>_test.*).
Current: code file(s) changed: projects/rocsparse/clients/samples/documentation_examples/generic/example_rocsparse_spsort.cpp, projects/rocsparse/library/include/internal/generic/rocsparse_spsort.h, projects/rocsparse/library/src/conversion/csrsort_device.h, projects/rocsparse/library/src/conversion/rocsparse_csrsort.cpp, projects/rocsparse/library/src/conversion/rocsparse_csrsort.hpp (+4 more); no test file found
🔎 pre-commit ⏳ Pending ⏳ Still running…
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —

⏳ Required checks are still running or have not started yet.
This PR is not ready for review until they complete.

📖 Need help? See the Policy FAQ for details on every check and how to fix failures.

🙋 Wish to Override Policy?

@therock-pr-bot

therock-pr-bot Bot commented Sep 24, 2026 •

Copy link
Copy Markdown

⏳ Waiting for required checks to start or finish:

  • ⏳ pre-commit

@jsandham
jsandham force-pushed the users/jsandham/spsort-csr branch from 960a065 to 88371d1 Compare September 24, 2026 23:44
@jsandham
jsandham force-pushed the users/jsandham/spsort-csr branch 2 times, most recently from d394df4 to a8cdd65 Compare September 25, 2026 20:23
@jsandham
jsandham force-pushed the users/jsandham/spsort-csr branch 2 times, most recently from ca74c3b to ea3b30a Compare September 28, 2026 16:12
@jsandham
jsandham force-pushed the users/jsandham/spsort-csr branch 2 times, most recently from 1672150 to 3262da5 Compare September 30, 2026 16:35
@jsandham
jsandham force-pushed the users/jsandham/spsort-csr branch from 4d2eeb8 to 74acb8a Compare October 6, 2026 15:10
@jsandham
jsandham force-pushed the users/jsandham/spsort-csr branch 2 times, most recently from 92a827d to 70adf71 Compare October 6, 2026 15:24
jsandham and others added 8 commits October 8, 2026 13:56
Sorts the column indices, and the corresponding values, within each row of a
CSR matrix, out of place or in place, and for strided batched matrices. The
direction must be rocsparse_direction_row.

Adds rocsparse::csrsort_buffer_size and rocsparse::csrsort, which take the
arrays of both the input and output matrices and loop over the batches. The
existing csrsort implementation is turned into templates on the row pointer
and column index types, which the rocsparse_csrsort C API now calls. The
segmented radix sort gains the mixed 32-bit key and 64-bit value
instantiations needed for 64-bit row pointers with 32-bit column indices.

Co-authored-by: Cursor <cursoragent@cursor.com>
Only uniform batches are supported, so every batch shares the sparsity pattern
of the first one. Its indices are sorted once, copied with the offsets into
every batch of the target, and the resulting permutation is applied to the
values of each batch. The batch strides are converted to bytes once, up front.

Co-authored-by: Cursor <cursoragent@cursor.com>
Replace csrsort_template and the gcsrsort wrappers with non-templated
csrsort_buffer_size_compute and csrsort_compute routines that take the
offsets and indices types at runtime, keeping the type dispatch only at
the rocPRIM and kernel calls. Pass the buffer size to the index sort so
it can check the buffer is large enough, and remove an unused
segmented_radix_sort_keys instantiation.

Co-authored-by: Cursor <cursoragent@cursor.com>
The CSR and CSC formats always sort the indices within each row or
column, so the direction is ignored for them.

Co-authored-by: Cursor <cursoragent@cursor.com>
…batch

Co-authored-by: Cursor <cursoragent@cursor.com>
Give the size of csrsort_shift_kernel the type of its offsets, and
describe the csxsort direction as selecting the CSR or CSC format.

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Support 32-bit offsets with 64-bit indices, which needs the matching
segmented radix sort instantiations. Set the single offset of a target
without rows to the index base when the source has no offsets array,
instead of leaving it uninitialized, explain why every batch of the target
receives the sorted indices, remove the unused rocsparse_csrsort_alg, and
use static_cast in csrsort_shift_kernel.

Co-authored-by: Cursor <cursoragent@cursor.com>
@jsandham
jsandham force-pushed the users/jsandham/spsort-csr branch from b2f82d6 to eef1505 Compare October 8, 2026 14:47
@jsandham
jsandham merged commit 6b1351a into develop Oct 12, 2026
129 of 146 checks passed
@jsandham
jsandham deleted the users/jsandham/spsort-csr branch October 12, 2026 13:46
danila-permogorskii pushed a commit to danila-permogorskii/rocm-libraries that referenced this pull request Oct 12, 2026
## Motivation
First PR of a stack adding a generic sparse matrix sort,
`rocsparse_spsort`. It sorts an input matrix A into an output matrix B,
or in place when the same descriptor is passed for both. COO, CSR and
CSC are supported, including uniform strided batched matrices (every
batch has the same sparsity pattern, and only the values differ).

This PR adds only the public API and its documentation, so the interface
can be reviewed on its own:
- `rocsparse_spsort_buffer_size` and `rocsparse_spsort` in
`internal/generic/rocsparse_spsort.h`.
- The `rocsparse_spsort_descr` descriptor with
`rocsparse_spsort_descr_create`, `rocsparse_spsort_descr_destroy` and
`rocsparse_spsort_set_input`.
- The `rocsparse_spsort_alg`, `rocsparse_spsort_input` and
`rocsparse_spsort_stage` enums.
- Entries in the reference docs and in the hipGraph support table.

The functions are declared but not implemented until the following PRs
in the stack. The doc example snippets are added together with the
examples.

## Test plan
- Compiled a C and a C++ translation unit including `rocsparse.h` and
using the new types.
- Built the library with this PR.

JIRA ID: AISPARSE-717

## Stack
This PR is part of a stack. Review and merge in order:

1. ROCm#12553 ⬅ this PR
2. ROCm#12555
3. ROCm#12556
4. ROCm#12557
5. ROCm#12558
6. ROCm#12559
7. ROCm#12560

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
danila-permogorskii pushed a commit to danila-permogorskii/rocm-libraries that referenced this pull request Oct 12, 2026
)

## Motivation
Implements the SpSort descriptor, `rocsparse_spsort_buffer_size` and
`rocsparse_spsort` for COO matrices:
- Sorts by row (`rocsparse_direction_row`) or by column
(`rocsparse_direction_column`).
- Out of place (A into B) or in place (the same descriptor for A and B).
- Uniform strided batched matrices, where A and B may have different
batch strides. Every batch has the same sparsity pattern, so the indices
are sorted once and the resulting permutation is applied to the values
of every batch.

Adds the internal `rocsparse::coosort_buffer_size` and
`rocsparse::coosort` in the existing `rocsparse_coosort.cpp`. They take
the algorithm, the direction, the source and target sparse matrix
descriptors and the buffer size, and gather the values of each batch
with the shared permutation. The index type dispatch happens right
before the kernel launch through the existing `gcoosort` routines, so
the coosort templates are unchanged.

The SpSort descriptor is defined in `rocsparse_spsort.hpp`, with
`rocsparse_spsort_descr.cpp` (descriptor and
`rocsparse_spsort_set_input`), `rocsparse_spsort_buffer_size.cpp` and
`rocsparse_spsort.cpp`.

The extra gather buffer for the values is only allocated when sorting in
place. CSR and CSC return `rocsparse_status_not_implemented` until the
next PRs.

## Test plan
- Built the library and ran `example_rocsparse_spsort_coo`.
- Ran the existing `coosort` tests (quick and pre_checkin).
- Ran the `spsort_coo` tests added later in the stack against this
library (quick and pre_checkin).

JIRA ID: AISPARSE-717

## Stack
This PR is part of a stack. Review and merge in order:

1. ROCm#12553
2. ROCm#12555 ⬅ this PR
3. ROCm#12556
4. ROCm#12557
5. ROCm#12558
6. ROCm#12559
7. ROCm#12560

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
danila-permogorskii pushed a commit to danila-permogorskii/rocm-libraries that referenced this pull request Oct 12, 2026
)

## Motivation
Adds CSC support to `rocsparse_spsort`. It sorts the row indices, and
the corresponding values, within each column. Out of place, in place and
strided batched matrices are supported, with the same batch rules as
CSR, using n + 1 for the column pointer.

Adds the internal `rocsparse::cscsort_buffer_size` and
`rocsparse::cscsort` in the existing `rocsparse_cscsort.cpp`. They take
the source and target sparse matrix descriptors and reuse
`rocsparse::csxsort_buffer_size` and `rocsparse::csxsort` from the CSR
PR, which sort a CSC matrix as the CSR layout of its transpose.

## Test plan
- Built the library.
- Ran the existing `csrsort` and `cscsort` tests.
- Ran the `spsort_csc` tests added later in the stack against this
library (quick and pre_checkin).

JIRA ID: AISPARSE-717

## Stack
This PR is part of a stack. Review and merge in order:

1. ROCm#12553
2. ROCm#12555
3. ROCm#12556
4. ROCm#12557 ⬅ this PR
5. ROCm#12558
6. ROCm#12559
7. ROCm#12560

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
danila-permogorskii pushed a commit to danila-permogorskii/rocm-libraries that referenced this pull request Oct 12, 2026
…OCm#12558)

## Motivation
Adds tests and a benchmark for `rocsparse_spsort` with COO matrices:
- Checks out of place results (A unchanged) and in place results against
a host reference, for both directions.
- Covers strided batched matrices, with A padded between batches to
check that its stride is honoured.
- Checks the SpSort argument handling: descriptor inputs, stage
ordering, matching A and B, and batch counts and strides.
- Adds the `spsort_coo` benchmark.

The test times are about 0.6 s for quick, 6 s for pre_checkin and 67 s
for nightly.

## Test plan
- `rocsparse-test --gtest_filter='*spsort*'`: 382 tests passed.
- `rocsparse-bench -f spsort_coo`

JIRA ID: AISPARSE-717

## Stack
This PR is part of a stack. Review and merge in order:

1. ROCm#12553
2. ROCm#12555
3. ROCm#12556
4. ROCm#12557
5. ROCm#12558 ⬅ this PR
6. ROCm#12559
7. ROCm#12560

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
danila-permogorskii pushed a commit to danila-permogorskii/rocm-libraries that referenced this pull request Oct 12, 2026
…OCm#12559)

## Motivation
Adds tests and a benchmark for `rocsparse_spsort` with CSR matrices:
- Checks out of place and in place results against a host reference that
sorts each row.
- Covers all supported row pointer and column index type combinations
(i32/i32, i64/i32, i64/i64).
- Covers strided batched matrices, with A's offsets and columns/values
padded between batches.
- Checks the CSR specific argument handling: the direction and the batch
stride rules.
- Adds the `spsort_csr` benchmark.

The test times are about 0.5 s for quick, 5 s for pre_checkin and 35 s
for nightly.

## Test plan
- `rocsparse-test --gtest_filter='*spsort*:-nightly*spsort_coo*'`: 486
tests passed, including 179 nightly `spsort_csr` tests.
- `rocsparse-bench -f spsort_csr`

JIRA ID: AISPARSE-717

## Stack
This PR is part of a stack. Review and merge in order:

1. ROCm#12553
2. ROCm#12555
3. ROCm#12556
4. ROCm#12557
5. ROCm#12558
6. ROCm#12559 ⬅ this PR
7. ROCm#12560

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
danila-permogorskii pushed a commit to danila-permogorskii/rocm-libraries that referenced this pull request Oct 12, 2026
…OCm#12560)

## Motivation
Adds tests and a benchmark for `rocsparse_spsort` with CSC matrices:
- Checks out of place and in place results against a host reference that
sorts each column.
- Covers all supported column pointer and row index type combinations.
- Covers strided batched matrices.
- Checks the CSC specific argument handling: the direction and the batch
stride rules.
- Adds the `spsort_csc` benchmark.

The test times are about 0.5 s for quick, 5 s for pre_checkin and 33 s
for nightly.

## Test plan
- `rocsparse-test
--gtest_filter='quick*spsort*:pre_checkin*spsort*:nightly*spsort_csc*'`:
651 tests passed.
- `rocsparse-bench -f spsort_csc`

JIRA ID: AISPARSE-717

## Stack
This PR is part of a stack. Review and merge in order:

1. ROCm#12553
2. ROCm#12555
3. ROCm#12556
4. ROCm#12557
5. ROCm#12558
6. ROCm#12559
7. ROCm#12560 ⬅ this PR

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
kliegeois pushed a commit that referenced this pull request Oct 12, 2026
## Motivation
Adds the `BUILD_WITH_SPSORT` build option, which gates
`rocsparse_spsort` so that it can be enabled or disabled at build time,
in the same way as `BUILD_WITH_DIAGONAL_SOLVE`. The option is `ON` by
default.

When the option is `OFF`, `ROCSPARSE_WITH_SPSORT` is not defined in
`rocsparse-config.h` and the following are left out:
- The `rocsparse_spsort` and `rocsparse_spsort_buffer_size`
declarations, the `rocsparse_spsort_descr_create`,
`rocsparse_spsort_descr_destroy` and `rocsparse_spsort_set_input`
declarations, and the `rocsparse_spsort_descr`, `rocsparse_spsort_alg`,
`rocsparse_spsort_input` and `rocsparse_spsort_stage` types.
- The implementation of those routines. Their sources are still listed
in the library, but compile to nothing.
- The `spsort_coo`, `spsort_csr` and `spsort_csc` tests and benchmarks.
- The `rocsparse_spsort` documentation examples, which build as a stub
that prints that rocSPARSE was built without `rocsparse_spsort`.

`ROCSPARSE_WITH_SPSORT` is also added to the Doxygen `PREDEFINED` list
so the documentation is still generated.

The legacy `coosort`, `csrsort` and `cscsort` routines, and the fixes
made to them earlier in the stack, are not gated.

This PR only adds the guards. It does not change the code of the PRs
below it, so their CI results are unaffected.

## Test plan
- Build with `-DBUILD_WITH_SPSORT=OFF`: the library, `rocsparse-test`,
`rocsparse-bench` and the samples build, `librocsparse.so` exports no
`rocsparse_spsort*` symbols, and the spsort examples print the stub
message. `rocsparse-test
--gtest_filter='*coosort*:*csrsort*:*cscsort*'`: 556 tests passed.
- Build with `-DBUILD_WITH_SPSORT=ON`: `rocsparse-test
--gtest_filter='*spsort*'`: 1482 tests passed.

JIRA ID: AISPARSE-717

## Stack
This PR is part of a stack. Review and merge in order:

1. #12553
2. #12555
3. #12556
4. #12557
5. #12558
6. #12559
7. #12560
8. #13392 ⬅ this PR

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
@assistant-librarian

Copy link
Copy Markdown
Contributor

TheRock Submodule Bump Activity

Newest first

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants