Skip to content

fix(rocsparse): write the base and use n for csxsldu_preprocess column walks (AISPARSE-906) - #14480

Merged
kliegeois merged 1 commit into
ROCm:developfrom
kliegeois:task/aisparse-906-csxsldu-col-ptr0
Oct 28, 2026
Merged

kliegeois merged 1 commit into
ROCm:developfrom
kliegeois:task/aisparse-906-csxsldu-col-ptr0

Conversation

@kliegeois

Copy link
Copy Markdown
Contributor

JIRA ID : AISPARSE-906.

Summary

  • rocsparse::csxsldu_preprocess_template (the internal CSR/CSC triangular split behind the itilu0 sync-split path) computes the L and U pointer arrays by writing the index base into element 0, counting the entries of each row or column into elements 1..n, and running an inclusive scan.
  • The base write was only in the row-direction case. The column-direction case went straight to the count kernel, which never writes element 0, so the scan started from whatever the caller had left in element 0. Every pointer and the returned lnnz / unnz were off by that value.
  • The counts were also read back at ptr[m] in both directions. A column walk has n + 1 pointers, so for m < n the counts covered only the first m columns, and for m > n the read went past the last pointer.
  • The base write (and the stream synchronization that follows it) now runs before the direction switch, so both directions start the scan from the base, and the counts are read at ptr[m] for the row walk and at ptr[n] for the column walk. The row path does the same work as before.
  • The count kernel dispatch status was dropped in both directions, so an unsupported diagonal combination (both non-unit) still returned success after a scan of stale counts. It is now returned. The itilu0 caller passes unit diagonals for both factors, so it is not affected.
  • Unit tests in develop's clients/unittests/unit_test_host_internal_branches.cpp:
    • HostInternalBranches.csxsldu_directions runs the buffer-size direction combinations and the preprocess walks on a 2x2 diagonal matrix: row direction with row and with column factors, and column direction with column factors and a unit or non-unit lower diagonal (the column case also runs with the handle buffer dropped, so the scan allocates its own scratch). This restores the two column walks that develop's version of the test dropped.
    • New HostInternalBranches.csxsldu_preprocess_reference, with the sldu_case / sldu_reference host reference helpers, compares every pointer and both counts with a host reference on non-square matrices (2x3 and 3x2, by column, and 3x2 by row) with strictly lower and upper entries, one-based input, distinct L and U bases, factors in the other direction, whose pointers go to the scratch buffer, and an empty (3x0) column walk. It also checks that two non-unit diagonals are rejected with invalid_value in both directions. Non-zero bases tell "write the base" apart from "write 0".
    • The output arrays start at a -7 sentinel, and arrays that preprocess must not write are checked to keep it.
  • No build file changes: develop already compiles the csxsldu buffer-size and preprocess translation units into the unit test binary, because their symbols are hidden in librocsparse.
  • No CHANGELOG entry: the routine is internal, and its only library caller (itilu0 sync-split) uses the row direction on square matrices, so no public behaviour changes.

Test plan

  • gfx1201: rocsparse-unit-test (23 tests) and rocsparse-unit-test-device (1270 passed, plus the 27 existing skips) pass in full; HostInternalBranches.* 13 passed. rocsparse-test --gtest_filter='*quick*csritilu0*:*pre_checkin*csritilu0*' (the sync-split caller) passes (668 tests).
  • With the whole library change reverted, both column walks of csxsldu_directions fail: every pointer and both counts are offset by the -7 left in element 0 (the unit/unit walk gives lptr / uptr {-7, -7, -7} and lnnz -7 instead of {0, 0, 0} and 0; the non-unit-lower walk gives lptr {-7, -6, -5} and lnnz -5 instead of {0, 1, 2} and 2), and csxsldu_preprocess_reference fails on every column case, including the empty one, and on the non-unit/non-unit check, which returns success. The row-direction reference case passes with and without the change.
  • With only the count index reverted, csxsldu_preprocess_reference fails on the 2x3 column cases (unnz counts only the first two columns), and the 3x2 column case returns an error from the read past the last pointer.
  • With only the dispatch status check reverted, only the non-unit/non-unit check fails (in both directions).
  • CI

…n walks (AISPARSE-906)

rocsparse::csxsldu_preprocess_template writes the index base into
element 0 of the L and U pointer arrays before the count kernel, which
only writes ptr[seq + 1], and the inclusive scan. That write sat in the
row-direction case only. In the column direction element 0 kept
whatever the caller had left in the arrays, so the scan offset every
pointer and the returned lnnz / unnz by that value.

The counts were also read back at ptr[m] in both directions. The column
walk has n + 1 pointers, so for m < n the counts covered only the first
m columns, and for m > n the read went past the last pointer.

The base write and the stream synchronization now happen before the
direction switch, so both directions start the scan from the base, and
the counts are read at ptr[m] for the row walk and ptr[n] for the
column walk. The status of the count kernel dispatch, which was
dropped, is now returned, so two non-unit diagonals give invalid_value
instead of a scan of stale counts.

Test: unit_test_host_internal_branches.cpp extends
HostInternalBranches.csxsldu_directions, which runs the buffer-size
direction combinations and the preprocess walks (row direction with row
and column factors, column direction with column factors and a unit or
non-unit lower diagonal) on a 2x2 diagonal matrix; the two column walks
were missing from develop's version. It adds
HostInternalBranches.csxsldu_preprocess_reference, which compares the
pointers and counts with a host reference on 2x3, 3x2 and empty 3x0
matrices with strictly lower and upper entries, one-based input,
distinct L and U bases, and factors in the other direction (pointers in
the scratch buffer), and checks that two non-unit diagonals are
rejected. The output arrays start at a -7 sentinel.
@kliegeois
kliegeois requested a review from a team as a code owner October 27, 2026 16:14
@therock-pr-bot

therock-pr-bot Bot commented Oct 27, 2026 •

Copy link
Copy Markdown

✅ All Checks Passed — Ready for Review

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/unittests/unit_test_host_internal_branches.cpp, projects/rocsparse/library/src/conversion/rocsparse_csxsldu_preprocess.cpp; no test file found
🔎 pre-commit ✅ Pass —
🚫 Draft PR 🔜 To Be Enabled —
🚩 Feature Flag 🔜 To Be Enabled —
📊 Code Coverage 🔜 To Be Enabled —
🤖 therock-pr-bot ✅ Pass —

🎉 All checks passed! This PR is ready for review.

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

🙋 Wish to Override Policy?

@therock-pr-bot

Copy link
Copy Markdown

🎉 All checks passed! This PR is ready for review.

@YvanMokwinski YvanMokwinski left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

good it's tested.

@jsandham jsandham left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Review

The three changes in csxsldu_preprocess_template match the three failure modes, and the new tests lock each one separately.

Base write. csxtril_count_kernel only stores per-sequence counts at ptr[seq + 1]. The inclusive scan therefore needs element 0 to already hold the factor base. Moving the lbase / ubase copies, and the stream sync that keeps those stack sources alive, ahead of the direction switch makes the column walk start from the base the same way the row walk already did. Distinct L and U bases in csxsldu_preprocess_reference separate "write the base" from "write zero".

Count index. The scan covers m + 1 pointers on a row walk and n + 1 on a column walk. Reading lptr[nseq] / uptr[nseq], with nseq = (dir == row) ? m : n, matches that length. A 2×3 column matrix would report a short unnz if this stayed at m, and a 3×2 column matrix would read past the last pointer. The row reference case is 3×2, so using n on the row path would fail there too.

Dispatch status. Both diagonals non-unit is rocsparse_status_invalid_value from csxtril_count_kernel_dispatch. That status was discarded, so the routine scanned whatever was already in the pointer arrays and returned success. It is now returned, in both directions. Dropping the LCOV_EXCL around that return is consistent with the new test actually executing it.

The column call still passes (udiag, ldiag, uptr, lptr). That swap is right: in CSC, seq > ind is the upper triangle, so the first count belongs to U. I walked the host reference against that kernel mapping for every case in the new test (2×3 and 3×2, one-based indices, distinct bases, factors in the other direction, the empty 3×0 column walk, and the 2×2 diagonal walks). Pointers and both counts match, including which array receives the scratch output (buffer when only one factor is in the other direction, buffer + nseq + 1 for U when both are).

The itilu0 sync-split caller still uses the row direction with m == n and unit diagonals, so its preprocess results are unchanged. csxsldu_compute_template already sizes its walk with (dir == row) ? m : n, so preprocess now agrees with it.

The unit-test bot warning is a filename heuristic. The new coverage lives in the existing unit_test_host_internal_branches.cpp, which is where the other host-internal branches are tested.

No functional issues found.

@codecov

codecov Bot commented Oct 27, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.57143% with 3 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ry/src/conversion/rocsparse_csxsldu_preprocess.cpp 78.57% 0 Missing and 3 partials ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##           develop   #14480   +/-   ##
========================================
  Coverage    76.89%   76.89%           
========================================
  Files         2886     2886           
  Lines       481037   481041    +4     
  Branches     72377    72381    +4     
========================================
+ Hits        369847   369864   +17     
+ Misses       86832    86821   -11     
+ Partials     24358    24356    -2     
Flag Coverage Δ *Carryforward flag
TensileLite-CPP 48.93% <ø> (ø) Carriedforward from cf0d592
TensileLite-Unit 83.71% <ø> (ø) Carriedforward from cf0d592
hipBLAS 90.62% <ø> (ø) Carriedforward from cf0d592
hipBLASLt 66.20% <ø> (ø) Carriedforward from cf0d592
hipCUB 82.68% <ø> (ø) Carriedforward from cf0d592
hipDNN 86.85% <ø> (ø) Carriedforward from cf0d592
hipFFT 38.02% <ø> (ø) Carriedforward from cf0d592
hipRAND 76.12% <ø> (ø) Carriedforward from cf0d592
hipSOLVER 69.67% <ø> (ø) Carriedforward from cf0d592
hipSPARSE 86.99% <ø> (ø) Carriedforward from cf0d592
rocBLAS 68.72% <ø> (ø) Carriedforward from cf0d592
rocFFT 46.05% <ø> (ø) Carriedforward from cf0d592
rocRAND 57.31% <ø> (ø) Carriedforward from cf0d592
rocSOLVER 76.74% <ø> (ø) Carriedforward from cf0d592
rocSPARSE 83.52% <78.57%> (+0.02%) ⬆️
rocSPARSE-integration 74.85% <42.86%> (-<0.01%) ⬇️
rocSPARSE-unit 78.95% <78.57%> (+0.02%) ⬆️
rocThrust 93.15% <ø> (ø) Carriedforward from cf0d592

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

Files with missing lines Coverage Δ
...ry/src/conversion/rocsparse_csxsldu_preprocess.cpp 85.96% <78.57%> (+7.79%) ⬆️
🚀 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.

@kliegeois
kliegeois merged commit 03a05bd into ROCm:develop Oct 28, 2026
237 of 251 checks passed
@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.

3 participants