Skip to content

fix(hipblaslt): build without rocRoller when HIPBLASLT_ENABLE_ROCROLLER is off - #14086

Merged
jaopaulolc merged 9 commits into
developfrom
users/jolabega/hipblaslt-drop-rocroller-headers
Nov 4, 2026
Merged

jaopaulolc merged 9 commits into
developfrom
users/jolabega/hipblaslt-drop-rocroller-headers

Conversation

@jaopaulolc

@jaopaulolc jaopaulolc commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

JIRA ID

  • AIHPBLAS-5236
  • AIHPBLAS-5246

Motivation

With HIPBLASLT_ENABLE_ROCROLLER off, a checkout may omit the rocRoller sources. The tile ranker is compiled in both builds. It included rocRoller's headers only to name a number format and a scale layout, so a checkout without those sources failed to compile, and the build also fetched libfmt, the formatting library those headers use.

Technical Details

A kernel's operands are now described with the names hipBLASLt already uses. An element format is a hipDataType. A scale layout is RocblasltContractionProblem::ScalingFormat. ScaleType::format starts as ScalingFormat::None, which means the operand is not scaled.

KernelType and ScaleType are defined in kernel_type.hpp. That header includes hipBLASLt's own type headers and does not include rocRoller.

hip2RocRollerType, in rocroller_interop.hpp, converts a hipDataType into rocRoller's format name. Only three files include it: gemm.cpp, rocroller_host.cpp, and runtime_args_selection.cpp. Those files are built into hipblaslt-rocroller, the library created only when rocRoller generation is on. A scale layout is not converted. The generator calls isBlockScaling() and reads the format's own block sizes.

The ranker library hipblaslt-rocroller-selection no longer adds rocRoller's include directory and no longer links libfmt. Its sources are rocroller_selected.cpp and solution_selection.cpp.

normalizeOperandType maps both 8-bit E4M3 spellings onto HIP_R_8F_E4M3, and both E5M2 spellings onto HIP_R_8F_E5M2. A format no ranked kernel handles becomes HIPBLASLT_DATATYPE_INVALID, which matches no tile.

Each tile is still emitted in both non-temporal forms. solution_selection.cpp sets non_temporal_a_available and non_temporal_b_available on all three tile configs, because rank_configs reads those flags.

The package-build workflow runs check_rocroller_selection_deps.sh on the ranker's compiler dependency files. The script fails when a file names rocRoller/ or fmt/. The in-tree directory rocroller/ does not match rocRoller/.

This pull request is based on develop.

Test Plan

Host compilation only. Both builds used -DGPU_TARGETS=gfx950 and a Release configuration, on commit 3685ce7d7c4, before develop was merged into this branch.

  1. Configure with HIPBLASLT_ENABLE_ROCROLLER=OFF in a checkout that does not contain shared/rocroller. Link libhipblaslt.so and libhipblaslt-rocroller-selection. Run ninja -t deps on solution_selection.cpp.o and rocroller_selected.cpp.o, then run check_rocroller_selection_deps.sh on the ranker's dependency directory.
  2. Configure the on build with -DCMAKE_POLICY_VERSION_MINIMUM=3.5, because rocRoller's bundled yaml-cpp declares a CMake minimum that CMake 4 rejects. Build the target hipblaslt-rocroller.
  3. Do not treat a kernel-selection comparison as part of this branch. None was run on this head.

Test Result

Completed on 3685ce7d7c4, before the develop merge. Not repeated on the current head. The only commit after 749e9f2f1bd rewords comments.

  • The off build linked libhipblaslt.so and libhipblaslt-rocroller-selection. ninja -t deps for the two ranker objects named no rocRoller/ header and no fmt/ header. check_rocroller_selection_deps.sh failed because ninja wrote no .d files.
  • ninja hipblaslt-rocroller exited 0. parameter_selection.cpp, gemm.cpp, and rocroller_host.cpp are in libhipblaslt-rocroller.a, and librocroller.so linked.

Automated GitHub checks on the current head are pending. No kernel-selection comparison was run on this branch.

Submission Checklist

Risk level

Medium (3/5). The ranker compares formats using hipDataType values, which differ from rocRoller's numbering, so the tile it keeps can change. hip2RocRollerType stops the run when a format has no translation, rather than generating a different format. The public functions hipBLASLt exposes to callers are unchanged.

@therock-pr-bot

therock-pr-bot Bot commented Oct 21, 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/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/custom_kernels.cpp, projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/gemm.cpp, projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/include/analytical_utils.hpp, projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/include/gemm.hpp, projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/include/kernel_type.hpp (+8 more); 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

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

Copy link
Copy Markdown

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

@codecov

codecov Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 55.75758% with 73 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...rocblaslt/src/rocroller/runtime_args_selection.cpp 0.00% 23 Missing ⚠️
...cblaslt/src/rocroller/include/analytical_utils.hpp 0.00% 18 Missing ⚠️
...ry/src/amd_detail/rocblaslt/src/rocroller/gemm.cpp 78.43% 0 Missing and 11 partials ⚠️
...blaslt/src/rocroller/include/rocroller_interop.hpp 66.67% 8 Missing and 3 partials ⚠️
..._detail/rocblaslt/src/rocroller/rocroller_host.cpp 14.29% 4 Missing and 2 partials ⚠️
...laslt/src/rocroller/include/solution_selection.hpp 40.00% 0 Missing and 3 partials ⚠️
...il/rocblaslt/src/rocroller/parameter_selection.cpp 83.33% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff            @@
##           develop   #14086   +/-   ##
========================================
  Coverage    77.66%   77.66%           
========================================
  Files         2903     2904    +1     
  Lines       490366   490404   +38     
  Branches     74218    74237   +19     
========================================
+ Hits        380819   380870   +51     
+ Misses       84597    84572   -25     
- Partials     24950    24962   +12     
Flag Coverage Δ *Carryforward flag
TensileLite-CPP 50.96% <ø> (ø) Carriedforward from 125e062
TensileLite-Unit 84.33% <ø> (ø) Carriedforward from 125e062
hipBLAS 90.62% <ø> (ø) Carriedforward from 125e062
hipBLASLt 68.88% <55.76%> (+0.11%) ⬆️
hipCUB 82.68% <ø> (ø) Carriedforward from 125e062
hipDNN 87.25% <ø> (ø) Carriedforward from 125e062
hipFFT 42.47% <ø> (ø) Carriedforward from 125e062
hipRAND 76.12% <ø> (ø) Carriedforward from 125e062
hipSOLVER 69.67% <ø> (ø) Carriedforward from 125e062
hipSPARSE 87.03% <ø> (ø) Carriedforward from 125e062
rocBLAS 69.20% <ø> (ø) Carriedforward from 125e062
rocFFT 49.54% <ø> (ø) Carriedforward from 125e062
rocRAND 57.32% <ø> (ø) Carriedforward from 125e062
rocSOLVER 76.74% <ø> (ø) Carriedforward from 125e062
rocSPARSE 83.54% <ø> (ø) Carriedforward from 125e062
rocThrust 93.15% <ø> (ø) Carriedforward from 125e062

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

Files with missing lines Coverage Δ
..._detail/rocblaslt/src/rocroller/custom_kernels.cpp 68.78% <100.00%> (+0.11%) ⬆️
...md_detail/rocblaslt/src/rocroller/include/gemm.hpp 28.36% <ø> (ø)
...il/rocblaslt/src/rocroller/include/kernel_type.hpp 100.00% <100.00%> (ø)
...il/rocblaslt/src/rocroller/parameter_selection.cpp 78.10% <83.33%> (ø)
...laslt/src/rocroller/include/solution_selection.hpp 59.52% <40.00%> (-0.94%) ⬇️
..._detail/rocblaslt/src/rocroller/rocroller_host.cpp 35.99% <14.29%> (-0.09%) ⬇️
...ry/src/amd_detail/rocblaslt/src/rocroller/gemm.cpp 65.19% <78.43%> (-0.04%) ⬇️
...blaslt/src/rocroller/include/rocroller_interop.hpp 66.67% <66.67%> (ø)
...cblaslt/src/rocroller/include/analytical_utils.hpp 0.00% <0.00%> (ø)
...rocblaslt/src/rocroller/runtime_args_selection.cpp 0.00% <0.00%> (ø)

... and 1 file with indirect coverage changes

🚀 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.

@jaopaulolc jaopaulolc changed the title build(hipblaslt): build the rocRoller tile ranker without rocRoller headers fix(hipblaslt): build without rocRoller when HIPBLASLT_ENABLE_ROCROLLER is off Oct 21, 2026
@jaopaulolc
jaopaulolc marked this pull request as ready for review October 21, 2026 15:01
@jaopaulolc
jaopaulolc requested review from a team as code owners October 21, 2026 15:01
@jaopaulolc
jaopaulolc marked this pull request as draft October 21, 2026 16:28

@AlexBrownAMD AlexBrownAMD 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.

Tested on a local repo with no rocroller checkout and it works. Thanks!

@jaopaulolc
jaopaulolc added this pull request to stack #14149 October 21, 2026 20:31
@jaopaulolc
jaopaulolc marked this pull request as ready for review October 21, 2026 20:32
@jaopaulolc
jaopaulolc removed this pull request from stack #14149 October 23, 2026 17:20
@jaopaulolc
jaopaulolc added this pull request to stack #14297 October 23, 2026 17:20
@jaopaulolc
jaopaulolc force-pushed the users/jolabega/hipblaslt-drop-rocroller-headers branch from 28ef88b to e290401 Compare October 23, 2026 20:11
@jaopaulolc
jaopaulolc enabled stacked auto-merge (squash) October 23, 2026 20:33
@jaopaulolc
jaopaulolc disabled stacked auto-merge October 26, 2026 15:12
@jaopaulolc
jaopaulolc force-pushed the users/jolabega/hipblaslt-drop-rocroller-headers branch from 1d0cb23 to e6175fd Compare October 26, 2026 17:29
@jaopaulolc
jaopaulolc removed this pull request from stack #14297 October 27, 2026 15:38
@jaopaulolc
jaopaulolc requested review from Alex-Vasile and removed request for Alex-Vasile October 27, 2026 15:46

@Alex-Vasile Alex-Vasile 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.

Changes look good.

@jaopaulolc
jaopaulolc requested a review from peymanr October 28, 2026 21:50

@peymanr peymanr 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.

Thanks, I reran the PR Pundit agent and it did not find anything new.

@peymanr

peymanr commented Oct 28, 2026

Copy link
Copy Markdown
Contributor

PR Pundit review

(testing PR Pundit Code Review agent. Not all comments may be relevant. Please reach out to @peymanr for suggestions and feedback.)

# Finding Where
1 🟠 Ninja deps fallback passes object paths that never match targets projects/hipblaslt/library/src/amd_detail/rocblaslt/src/check_rocroller_selection_deps.sh:82-88
2 🔵 build.ninja search loop can hang on relative depdir projects/hipblaslt/library/src/amd_detail/rocblaslt/src/check_rocroller_selection_deps.sh:68-76
3 🔵 CI guard never exercises the rocRoller-off build it claims to protect .github/workflows/hipblaslt-drop-build.yml:194-208
4 🔵 Unsupported-format lookup throws through C API instead of empty list projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/solution_selection.cpp:166-169
5 🔵 Diagnostics mention non-called function and print bare integer types projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/rocroller_host.cpp:373-388
6 🔵 Integer-comparison comment contradicted by direct enum use elsewhere projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/solution_selection.cpp:238-246
7 🔵 Changed files not clang-formatted, adding unrelated diff noise projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/runtime_args_selection.cpp:18-29
8 🔵 No test covers new type-translation and cache-key mapping layer projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/custom_kernels.cpp:93-110
9 🔵 SingleScale mode silently removed and genScaleModeString misnamed projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/gemm.cpp:67-72
10 🔵 Long historical comments narrate past tree state and go stale projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/include/gemm.hpp:11-13
11 🔵 Unused rocroller_interop.hpp include pulls in rocRoller headers projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/rocroller_host.cpp:13

1. 🟠 Should fix: Ninja deps fallback passes object paths that never match targets

projects/hipblaslt/library/src/amd_detail/rocblaslt/src/check_rocroller_selection_deps.sh:82-88

The Ninja fallback in check_rocroller_selection_deps.sh passes object paths from find "$depdir" (cwd-relative or absolute) to ninja -C <builddir> -t deps. Ninja names targets relative to the build directory, so the lookup fails with unknown target and set -e exits non-zero, even when the deps are clean. The Ninja support the header comment advertises therefore only works when the script runs from the build root with a build-relative path. Make the object paths relative to $ninjafile before calling ninja -t deps. The CI drop build is not affected because it uses Makefiles and reads the .d files.

Who is affected: Developers who run the check by hand on a Ninja-generated build tree from anywhere other than the build root; the Makefile-based CI workflow never reaches this path.

Verified by running it.

2. 🔵 Nit: build.ninja search loop can hang on relative depdir

projects/hipblaslt/library/src/amd_detail/rocblaslt/src/check_rocroller_selection_deps.sh:68-76

The walk-up loop in check_rocroller_selection_deps.sh stops only at /. For a relative depdir (the workflow passes one from find projects/hipblaslt/build), dirname settles at . and the loop never ends if no build.ninja is found. This is reached only when the target directory has no usable dependency records, so the script hangs until the job timeout instead of failing fast. Canonicalize depdir first (depdir=$(cd "$depdir" && pwd -P)), or also stop on ..

Who is affected: Anyone running the check script with a relative directory that has no .d records and no build.ninja above it; a normal successful Linux CI build does not hit it.

Verified by running it.

3. 🔵 Nit: CI guard never exercises the rocRoller-off build it claims to protect

.github/workflows/hipblaslt-drop-build.yml:194-208

The new Check ranker dependency files omit rocRoller and fmt step only checks the ranker's compiler dependencies in a default rocRoller-ON build. invoke build is given no --skip-rocroller, so HIPBLASLT_ENABLE_ROCROLLER=OFF is never set, and shared/rocroller is still sparse-checked-out. The OFF / no-checkout configuration this PR fixes is therefore not built by any CI job, and this workflow runs only on schedule or dispatch, not on PRs. A manual dispatch with a rocm_libraries_ref older than this PR lacks check_rocroller_selection_deps.sh, so the job fails before packaging. Consider adding a --skip-rocroller build, or skip the step when the script is absent.

Who is affected: Only maintainers who manually dispatch the drop build against a ref older than this PR, plus the general lack of CI coverage for HIPBLASLT_ENABLE_ROCROLLER=OFF.

4. 🔵 Nit: Unsupported-format lookup throws through C API instead of empty list

projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/solution_selection.cpp:166-169

The new comments in solution_selection.cpp (above INSTANTIATE_TILE_LIST_FOR and on normalizeOperandType) say an operand that normalises to HIPBLASLT_DATATYPE_INVALID 'is left with no tiles'. In fact getTileListForKernelType throws std::runtime_error("Unsupported DataType combination") on a map miss, and rankRocRollerSelectedTiles does not reject an invalid typeA/typeB first. Through hipblasLtMatmulAlgoGetHeuristic the throw is caught by catch(...) and returns HIPBLAS_STATUS_INTERNAL_ERROR, not an empty result. Through the C++ ext GemmInstance::algoGetHeuristic, which has no try block, the exception reaches the caller. The throw predates this PR; fix the comments, or reject HIPBLASLT_DATATYPE_INVALID operands with rocblaslt_status_invalid_value before ranking.

Who is affected: Callers whose problem takes the rocRoller path (useRocRoller: env-forced, or block scaling) with an A/B format outside the eight ranked formats; they get INTERNAL_ERROR from the C API or an exception from the C++ ext heuristic API.

Verified by running it.

5. 🔵 Nit: Diagnostics mention non-called function and print bare integer types

projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/rocroller_host.cpp:373-388

The rocRoller rejection messages in getRocRollerBestSolutions now print static_cast<int>(scale_type) and static_cast<int>(kernelType.typeAcc), where base printed readable rocRoller::DataType names. The AssertFatals in gemm.cpp likewise print static_cast<int>(...format) instead of a scale-mode name. Using hipDataType_to_string and rocblaslt_scaling_format_to_string (both in utility.hpp, already included) would keep the logs readable. The comment about hip2RocRollerType is not stale: it explains why the message avoids that throwing converter.

Who is affected: Users reading stderr or assert diagnostics when hipBLASLt rejects a rocRoller problem for a non-F32 scale or accumulation type (log readability only).

6. 🔵 Nit: Integer-comparison comment contradicted by direct enum use elsewhere

projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/solution_selection.cpp:238-246

Comments say HIP_R_6F_E2M3 etc. must be compared as integers because some headers declare them as constants, yet the same PR uses those names directly as hipDataType values, template arguments, map keys and case labels, which would not compile if they were int constants. Either the workaround is dead or the comment is wrong; reconcile them.

Who is affected: Maintainers reading normalizeOperandType and rocroller_interop.hpp; there is no runtime or build impact in any configuration.

Verified by running it.

7. 🔵 Nit: Changed files not clang-formatted, adding unrelated diff noise

projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/runtime_args_selection.cpp:18-29

The PR lengthens three already over-limit lines in runtime_args_selection.cpp (18-20, from 104 to 134 columns), against .clang-format ColumnLimit: 100. Line 29 was already 159 columns in base and is 156 now. The rewritten INSTANTIATE_TILE_LIST / INSTANTIATE_TILE_LIST_FOR macros in solution_selection.cpp have misaligned \ continuations, contrary to AlignEscapedNewlines: Left. Run the repo's clang-format over the touched hunks.

Who is affected: Code readers and anyone later running clang-format on these files; there is no functional impact.

Verified by running it.

8. 🔵 Nit: No test covers new type-translation and cache-key mapping layer

projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/custom_kernels.cpp:93-110

There are no unit tests for the new mapping helpers normalizeOperandType, accumulationType, hipDataType_to_analytical_type and hip2RocRollerType. The hand-built mxfp4 KernelType in preloadCustomKernels also hard-codes blockRowSize, preSwizzleTile and preTile instead of calling preSwizzleSizeForScale/preTileSizeForScaleA/B. Today these values match what genKernelType derives for Block_32_UE8M0_32_8_EXT, and the new format field is set to that format, so the cache key agrees. A small test asserting genKernelType(prob) == mxfp4Kernel would guard against future drift. Alternatively, build the custom kernel from the same helpers.

Who is affected: Only future edits to the scale-format helpers or the custom-kernel table could cause a mismatch, which would make the preloaded mxfp4 kernels miss the cache; no current configuration is affected.

Related past reviews: #372 on projects/hipblaslt/clients/include/testing_auxiliary.hpp

9. 🔵 Nit: SingleScale mode silently removed and genScaleModeString misnamed

projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/gemm.cpp:67-72

genScaleModeString now takes a RocblasltContractionProblem::ScalingFormat format and only reports whether it is block scaling ("B" or ""). The name still refers to rocRoller's ScaleMode, which this PR removes from ScaleType. Consider renaming it, e.g. genScalingFormatString or blockScalingTag. Dropping the 'S' branch is safe: nothing ever set ScaleMode::SingleScale.

Who is affected: Readers and maintainers of the rocRoller gemm code; there is no runtime effect.

Verified by running it.

10. 🔵 Nit: Long historical comments narrate past tree state and go stale

projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/include/gemm.hpp:11-13

Some comments added by this PR describe past history or are wrong. In gemm.hpp, the comment above #include <rocRoller/Operations/Command.hpp> ('Reached through kernel_type.hpp until hipBLASLt stopped...') describes an earlier tree; kernel_type.hpp no longer includes any rocRoller header. In solution_selection.cpp, the comments above INSTANTIATE_TILE_LIST_FOR and normalizeOperandType say an unsupported format is 'left with no tiles'. In fact getTileListForKernelType throws std::runtime_error("Unsupported DataType combination") when the tileListGenerators lookup misses. Reword these as present-tense reasons (e.g. 'gemm.hpp builds Commands, so it includes Command.hpp') and describe the throw correctly.

Who is affected: Maintainers reading the rocRoller ranker sources; there is no runtime impact.

Verified by running it.

Related past reviews: #7717 on projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/CMakeLists.txt

11. 🔵 Nit: Unused rocroller_interop.hpp include pulls in rocRoller headers

projects/hipblaslt/library/src/amd_detail/rocblaslt/src/rocroller/rocroller_host.cpp:13

The PR adds #include "rocroller_interop.hpp" to rocroller_host.cpp, but nothing in the file uses it. hip2RocRollerType appears only in a comment, and the scale-type check now prints static_cast<int>(scale_type) instead. The file already gets rocRoller headers through gemm.hpp and solution_cache.hpp, so the cost is a misleading dependency rather than new headers. Drop the include.

Who is affected: Maintainers only, in builds with rocRoller enabled; there is no runtime or build-time effect.

Verified by running it.

Shared from a pilot of PR Pundit, an agentic code reviewer that builds and tests the change and reads the project's past reviews. Reviewed at e3c07742; findings checked and posted by @peymanr; points already raised on this PR are left out.

@jaopaulolc
jaopaulolc removed this pull request from stack #14498 October 29, 2026 17:05
@jaopaulolc
jaopaulolc added this pull request to stack #14674 October 29, 2026 17:05
@jaopaulolc
jaopaulolc force-pushed the users/jolabega/hipblaslt-drop-rocroller-headers branch from e3c0774 to 8b8a122 Compare October 29, 2026 19:40
@jaopaulolc

jaopaulolc commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor Author

Addressed the review of e3c07742 in 8b8a1226501.

  1. The ninja fallback now passes object paths relative to the build directory. Checked with a stand-in ninja that rejects absolute targets.
  2. The dependency directory is canonicalized before the walk, so a relative path cannot spin on ..
  3. The drop-build step skips the check when this ref has no script. That job still builds the rocRoller-on packages it ships; the check fails if those ranker objects opened rocRoller or fmt headers.
    4, 10. The comments now say getTileListForKernelType throws on an unmapped operand. The throw itself is unchanged.
  4. Rejection messages use hipDataType_to_string and rocblaslt_scaling_format_to_string. The note that hip2RocRollerType throws stays.
  5. The FP4 and FP6 formats are switch cases, the same as the other hipDataType values.
  6. clang-format on the over-long lines in runtime_args_selection.cpp and the tile-list macros.
  7. The preloaded mxfp4 kernel takes its block size and pre-swizzle tiles from the same helpers genKernelType uses.
  8. genScaleModeString is now genBlockScalingTag.
  9. Dropped the unused rocroller_interop.hpp include from rocroller_host.cpp.

@jaopaulolc
jaopaulolc removed this pull request from stack #14674 October 30, 2026 14:48
@jaopaulolc
jaopaulolc added this pull request to stack #14754 October 30, 2026 14:49
@jaopaulolc
jaopaulolc force-pushed the users/jolabega/hipblaslt-drop-rocroller-headers branch 3 times, most recently from e15c463 to b056b96 Compare November 3, 2026 05:10
…eaders

The tile ranker in hipblaslt-rocroller-selection is built in every
configuration, including HIPBLASLT_ENABLE_ROCROLLER=OFF, and reached
shared/rocroller/lib/include for two enumerations: rocRoller::DataType
and rocRoller::Operations::ScaleMode. It calls no rocRoller function and
links no rocRoller symbol, but those two includes pulled in 80 headers
and a FetchContent clone of libfmt, and made the target unbuildable in a
checkout that omits shared/rocroller.

Declare the twelve DataType and two ScaleMode enumerators the ranker
names in rocroller_enums.hpp, generated from the single list in
rocroller_enum_list.hpp. kernel_type.hpp and analytical_utils.hpp pick
rocRoller's headers only when HIPBLASLT_HAVE_ROCROLLER_HEADERS is
defined, which is true of hipblaslt-rocroller alone.
rocroller_enum_conformance.cpp expands the same list into static
assertions against rocRoller's headers, so the two declarations of
KernelType that meet in a rocRoller-enabled build cannot disagree.

Drop the rocRoller include directory, the libfmt FetchContent and link,
and the now-unused ROCROLLER_USE_HIP definition from the ranker target.
… plainly

Review feedback on the previous commit. No behaviour change: the ranker's
instruction stream for chooseSolutionIndexParameters, genKernelType,
hipDataType_to_rocRoller_type and rankRocRollerSelectedTiles is unchanged.

Drop the HIPBLASLT_HAVE_ROCROLLER_HEADERS definition and read the existing
HIPBLASLT_USE_ROCROLLER instead. It already discriminates the two targets:
it is private to hipblaslt-rocroller, whose sources are the only ones built
against rocRoller's headers, and it is absent from the ranker target.
kernel_type.hpp and analytical_utils.hpp are internal headers that nothing
outside library/src/amd_detail/rocblaslt/src includes, so the definition
being public on hipblaslt does not reach a translation unit that would then
look for rocRoller headers it has no path to.

Using the hipBLASLt declarations in every configuration is not possible:
solution_cache.hpp includes both gemm.hpp, which includes rocRoller's
headers, and kernel_type.hpp, so one translation unit would define
rocRoller::DataType twice.

Replace the X-macro list and its two expansions with plain declarations in
rocroller_enums.hpp and explicit static assertions in
rocroller_enum_conformance.cpp, one per enumerator. The list no longer keeps
the two in step by construction, so each file carries a comment pointing at
the other. All 14 values and both underlying types were read back out of
rocRoller's headers at run time before being written down.
rocroller_enums.hpp reuses rocRoller's namespace and type names, so no
translation unit includes both declarations.
HIPBLASLT_USE_ROCROLLER already selects the mirror header. The Windows uint shims no longer include anything that needs them.
… headers

The compiler dependency files for the ranker sources are the check.
The ranker copied rocRoller's DataType and ScaleMode so a build with
HIPBLASLT_ENABLE_ROCROLLER=OFF could compile without rocRoller. Use
hipDataType and RocblasltContractionProblem::ScalingFormat instead, and
translate to rocRoller only in rocroller_interop.hpp, which the ranker
does not include.
The comments named the conversion they replaced. They now say what normalizeOperandType and hip2RocRollerType do, and why the comparison is an integer compare.
hip2RocRollerType throws on a format it cannot name, and the public
catch turns that into an internal error. The reject path now prints the
hipDataType and returns invalid_value.

The ranker dependency check only flags rocRoller and fmt headers, and
reads ninja -t deps when a Ninja build left no Makefile .d files.
The ninja dependency fallback asked for objects by a path ninja does not
use as a target, and the ranker comments described a throw as an empty
tile list.
@jaopaulolc
jaopaulolc force-pushed the users/jolabega/hipblaslt-drop-rocroller-headers branch from b056b96 to 7696adb Compare November 3, 2026 16:33
@jaopaulolc
jaopaulolc enabled stacked auto-merge (squash) November 3, 2026 16:35
stacked auto-merge was automatically disabled November 3, 2026 23:26

Auto-merge was disabled for another pull request in the stack

@jaopaulolc
jaopaulolc merged commit 43e2cb7 into develop Nov 4, 2026
342 of 349 checks passed
@jaopaulolc
jaopaulolc deleted the users/jolabega/hipblaslt-drop-rocroller-headers branch November 4, 2026 00:01
jaopaulolc added a commit that referenced this pull request Nov 4, 2026
…me matching (#14043)

JIRA ID : AIHPBLAS-5261

## Motivation

Two independent defects on gfx950 MX return wrong numbers: the row pitch
hipBLASLt reports for the scale tensor does not match the layout the
kernel was compiled against, and the test that picks a kernel by
inspecting its name accepts kernels that do not fit the problem.
Measured over 108 gfx950 MX problem and type combinations, 36 produced
numerically wrong results, some containing `inf`.

## Technical Details

This pull request is stacked on #14086.

The first fix concerns the scale row pitch.
`ContractionProblemGemm::setMXScaleA/B` rounds the scale tensor's
K-block dimension up with `RoundUpToMultiple(CeilDivide(K, mxBlock), 8)`
on gfx950. `generateCustomCall` passed that padded value as the kernel
arguments `StrideScaleA0` and `StrideScaleB0`, but the rocRoller kernels
are built against the unpadded `ceil(K/32)`. The two values are equal
only when `K % 256 == 0`. Otherwise every scale row after the first
resolves to the wrong bytes, and the kernel reads past the end of the
caller's scale buffer. `generateCustomCall` now takes both strides from
the buffer the caller passed. `customKernelMXScaleAIsPacked()` and
`customKernelMXScaleBIsPacked()` name that caller, one operand at a
time, because hipBLASLt takes the A and B scale formats independently.
When an operand's flag is set, its row stride is the unpadded
`ceil(K/mxBlock)`. When it is not, the descriptor stride is already the
one the kernel must use.

The padding is deliberately not removed globally. The gfx950 MX kernels
that TensileLite generates overwrite this pitch in their own prologue
from the problem's `SizesSum` field, so the kernel argument is dead for
them and the padded descriptor must stay for the rest of the library.
The change is confined to `generateCustomCall`, which runs only for
externally captured custom kernels. The batch stride `StrideScale{A,B}1`
follows the same caller buffer: a packed caller gets the product of the
unpadded scale sizes, and an unpacked caller keeps the descriptor
stride. No shipped rocRoller kernel reads that batch stride, and those
kernels run a single batch. This also repairs the FP6 custom kernels
added by #12964 and #12965, which reach the same code path.

hipBLASLt declares each operand packed unless its format is
`Block_32_UE8M0_32_8_EXT`: that caller pre-swizzled its scales into the
padded gfx950 layout, which the descriptor already describes. The
TensileLite benchmark client leaves both flags false, because it
allocates from the padded descriptor.

The second fix concerns `matchesRocRollerSelectedKernel`, the predicate
that decides whether a kernel's name describes the problem at hand. It
has three defects, all reachable on the `HIPBLASLT_ENABLE_ROCROLLER=OFF`
build:

- The tile test was the bare substring `WGT_<m>x<n>x<k>_UR_`, which
occurs inside both `_WGT_..._UR_` and `_SK_WGT_..._UR_`. A plain tile
therefore matched a StreamK kernel — StreamK is a work-partitioning
scheme that splits the summation axis across workgroups — and a StreamK
tile matched a plain kernel. The test is now anchored as `_WGT_...` with
an explicit `_SK` discriminator.
- The prefix match stopped at `_Float_` while the tile match began at
`WGT_`, so the scale-layout tokens between the two were never inspected.
A pre-swizzled kernel, named with `PSTA_`, `PTA_`, `PSTB_`, or `PTB_`,
could match a problem whose scales are not pre-swizzled. Those tokens
are now rejected.
- A StreamK kernel name never carries `_WGM_`, because
`parameter_selection.cpp` forces `workgroupMappingDim = -1` for StreamK.
The workgroup-mapping comparison now runs only when `workgroupMapping &&
!streamK`, and StreamK tiles are no longer rejected outright.

`getRocRollerSelectedSolutions` also gains the workspace rejection that
the rocRoller-enabled path already applies at `gemm.cpp:703-706`.
Without it an `OFF` build hands back a StreamK kernel that an `ON` build
would have skipped, because `_convertToHeuristicResultArray` reports
`requiredWorkspaceSize` but never filters on it.

### Name matching is not enough on its own

A kernel's name carries its tile shape and its operand types, and
nothing else. Every other condition the kernel was captured under —
which scale layout it reads, the size multiples and size windows it
requires, how many batches it handles, how large a tensor it can address
— lives in the kernel's selection predicates. An ordinary library lookup
evaluates those; this hand-rolled search skipped them. A problem that
block-scales only one of its two operands therefore matched a kernel
built to read two scale tensors, and that kernel read a scale buffer the
caller had never allocated.

`getRocRollerSelectedSolutions` now requires a candidate's
`hardwarePredicate` and `problemPredicate` to accept the problem before
it takes a name match, and keeps searching when they do not. It tests
hardware and problem only, as the grouped-gemm path in the same file
does: `taskPredicate` needs a `Task`, which needs the workspace size
that is tested immediately afterwards.

This narrows what the `OFF` path selects. Where the kernel it used to
match declares a size window that excludes the problem, it now picks a
different one. That is the intended behaviour, but it has a cost,
measured below: the only candidates on this path are other rocRoller
kernels, so when the best-fitting tile is correctly rejected there may
be nothing comparable left in the pool.

The predicate moves to `rocroller_kernel_match.hpp`, whose only
dependency is `<string>`, so it can be tested without a problem
descriptor or a GPU.

No longer rejecting StreamK outright changes which kernel an `OFF` build
selects. That is intended — it is what lets an `OFF` build reach the
StreamK kernels at all — but this pull request tests it only at the
name-matching level. The selection-identity sweep that compares an `OFF`
build against an `ON` build lands with the logic that makes these
kernels selectable, later in this stack.

## Test Plan

- `CustomKernelTest.ScaleStrideIsCompactNotPadded`,
`CustomKernelTest.ScaleStrideIsCompactForEitherBoundDimension`,
`CustomKernelTest.ScaleBatchStrideFollowsTheCallerBuffer`,
`CustomKernelTest.ScaleStrideFollowsDescriptorWhenCallerDoesNotPack`,
`CustomKernelTest.ScaleStridesIncludeTheInitialStrideForDataParallelArgs`,
and `CustomKernelTest.ScaleStrideRoundsUpPartialBlocks`: assert that
`generateCustomCall` emits the caller's scale stride. A packed caller
with a `K` that is not a multiple of 256 gets `ceil(K/mxBlock)`, for
both bound dimensions and for the batch stride. An unpacked caller gets
the descriptor stride.
- `HostUnitRocRollerKernelMatch.*`: five host-only tests covering the
StreamK and plain tile discrimination, the pre-swizzle token rejection,
and the workgroup-mapping comparison. Mutation-check them by running
them against the pre-patch predicate; a test that passes against the old
code does not discriminate.
- `CustomKernelTest.ScaleStrideFollowsEachOperandsBuffer`: a packed A
with a padded B, and the reverse, each get their own buffer's row and
batch strides.
- `HostUnitMXScaleSetup.smoke_PreSwizzledDeclarationIsPerOperand`: a
pre-swizzled operand is declared unpacked, and declaring one operand
does not change the other.
- Numerical parity sweep on gfx950 over 108 MX problem and type
combinations against a 1e-6 tolerance, comparing each result with and
without this change.
- A problem that block-scales one operand only — `scaleA 3`, `scaleB 0`,
bf8 inputs, 1024x1024x1024 — on an `HIPBLASLT_ENABLE_ROCROLLER=OFF`
build. It must report no solution rather than launching a kernel.
- A selection sweep on the same build over 8 shapes that do block-scale
both operands, recording which kernel each build picks and whether it
verifies, to show the predicates narrow selection without rejecting
problems the kernels do serve. Numerical checks must be requested in the
test record itself, because a `--verify` flag on the command line does
not reach a record supplied by `--yaml`.

## Test Result

Completed evidence:

- Both `CustomKernelTest` cases are new and pass.
- All five `HostUnitRocRollerKernelMatch` tests are new and pass.
Against the pre-patch predicate, 4 of the 5 fail, so they discriminate
the change.
- Parity sweep: 36 of the 108 combinations were numerically wrong before
the change, with a normalized error as large as 6508 and `inf` in some
cases. After the change 0 are wrong and none regressed; the 63
combinations that were already clean are bit-identical.

Predicate evaluation, measured on MI355X (gfx950, PCI 0x75a3) against an
`HIPBLASLT_ENABLE_ROCROLLER=OFF` build, with the numerical check set in
the test record:

- One-sided MX, bf8 x bf8 -> f32 at 1024x1024x1024 with `scaleA 3` and
`scaleB 0`: before the change the run ends in `an illegal memory access
was encountered (700)`; after it, the problem reports no solution, on 2
of 2 runs.
- Selection sweep, f8 x f8 -> f32 with both operands block-scaled, over
8 shapes: every shape still receives a solution and every shape
verifies, on both builds, so no problem the kernels serve is rejected.
Five of the eight change kernel. For instance
`RR_GEMM_..._WGT_32x32x64_UR_2` declares M and N between 64 and 128 and
K exactly 128, and was being selected at 512x512x512.
- The narrowing costs performance where the rejected tile was the only
large one available. At 4096x4096x1024 the selection moves from
`RR_GEMM_..._WGT_256x128x128_UR_2`, whose declared window ends at M =
2560, to `RR_GEMM_..._WGT_16x16x128_UR_2`, and the kernel time rises by
a factor of about 3.6 over three repeats. That fallback, routing a
problem the rocRoller path declines to ordinary Tensile selection, is
#14497, later in this stack. It is not in this pull request.

Pending: automated GitHub checks have not reported on this branch. The
parity sweep was run locally on gfx950 hardware and does not run in a
shared CI lane today.

## Submission Checklist

- [x] Look over the contributing guidelines at
https://github.com/ROCm/TheRock/blob/main/GOVERNANCE.md#pull-requests.

## Risk level

Medium. Two pieces of device-visible behavior change. The scale stride
passed to custom MX kernels on gfx950 changes value whenever `K % 256 !=
0`, which is the defect being fixed; kernels generated by TensileLite
are unaffected because they overwrite that argument. Separately, an
`HIPBLASLT_ENABLE_ROCROLLER=OFF` build can now select StreamK kernels it
previously rejected, so kernel choice on that path changes; the
numerical consequence of that selection change is measured later in this
stack rather than here.

Evaluating the predicates narrows that path further, and the measured
blast radius is kernel choice rather than correctness: across the 8
shapes swept, no problem lost a solution and none failed verification,
while 5 changed kernel. The cost is performance, not accuracy, and it
falls on shapes that no checked-in rocRoller kernel was captured for —
previously served by a kernel used outside its declared window. The
largest measured case is about 3.6x slower. That cliff is removed by the
fallback in #14497, later in this stack, not by this pull request.
@assistant-librarian

Copy link
Copy Markdown
Contributor

TheRock Submodule Bump Activity

Newest first

cycheng pushed a commit that referenced this pull request Nov 6, 2026
…me matching (#14043)

JIRA ID : AIHPBLAS-5261

## Motivation

Two independent defects on gfx950 MX return wrong numbers: the row pitch
hipBLASLt reports for the scale tensor does not match the layout the
kernel was compiled against, and the test that picks a kernel by
inspecting its name accepts kernels that do not fit the problem.
Measured over 108 gfx950 MX problem and type combinations, 36 produced
numerically wrong results, some containing `inf`.

## Technical Details

This pull request is stacked on #14086.

The first fix concerns the scale row pitch.
`ContractionProblemGemm::setMXScaleA/B` rounds the scale tensor's
K-block dimension up with `RoundUpToMultiple(CeilDivide(K, mxBlock), 8)`
on gfx950. `generateCustomCall` passed that padded value as the kernel
arguments `StrideScaleA0` and `StrideScaleB0`, but the rocRoller kernels
are built against the unpadded `ceil(K/32)`. The two values are equal
only when `K % 256 == 0`. Otherwise every scale row after the first
resolves to the wrong bytes, and the kernel reads past the end of the
caller's scale buffer. `generateCustomCall` now takes both strides from
the buffer the caller passed. `customKernelMXScaleAIsPacked()` and
`customKernelMXScaleBIsPacked()` name that caller, one operand at a
time, because hipBLASLt takes the A and B scale formats independently.
When an operand's flag is set, its row stride is the unpadded
`ceil(K/mxBlock)`. When it is not, the descriptor stride is already the
one the kernel must use.

The padding is deliberately not removed globally. The gfx950 MX kernels
that TensileLite generates overwrite this pitch in their own prologue
from the problem's `SizesSum` field, so the kernel argument is dead for
them and the padded descriptor must stay for the rest of the library.
The change is confined to `generateCustomCall`, which runs only for
externally captured custom kernels. The batch stride `StrideScale{A,B}1`
follows the same caller buffer: a packed caller gets the product of the
unpadded scale sizes, and an unpacked caller keeps the descriptor
stride. No shipped rocRoller kernel reads that batch stride, and those
kernels run a single batch. This also repairs the FP6 custom kernels
added by #12964 and #12965, which reach the same code path.

hipBLASLt declares each operand packed unless its format is
`Block_32_UE8M0_32_8_EXT`: that caller pre-swizzled its scales into the
padded gfx950 layout, which the descriptor already describes. The
TensileLite benchmark client leaves both flags false, because it
allocates from the padded descriptor.

The second fix concerns `matchesRocRollerSelectedKernel`, the predicate
that decides whether a kernel's name describes the problem at hand. It
has three defects, all reachable on the `HIPBLASLT_ENABLE_ROCROLLER=OFF`
build:

- The tile test was the bare substring `WGT_<m>x<n>x<k>_UR_`, which
occurs inside both `_WGT_..._UR_` and `_SK_WGT_..._UR_`. A plain tile
therefore matched a StreamK kernel — StreamK is a work-partitioning
scheme that splits the summation axis across workgroups — and a StreamK
tile matched a plain kernel. The test is now anchored as `_WGT_...` with
an explicit `_SK` discriminator.
- The prefix match stopped at `_Float_` while the tile match began at
`WGT_`, so the scale-layout tokens between the two were never inspected.
A pre-swizzled kernel, named with `PSTA_`, `PTA_`, `PSTB_`, or `PTB_`,
could match a problem whose scales are not pre-swizzled. Those tokens
are now rejected.
- A StreamK kernel name never carries `_WGM_`, because
`parameter_selection.cpp` forces `workgroupMappingDim = -1` for StreamK.
The workgroup-mapping comparison now runs only when `workgroupMapping &&
!streamK`, and StreamK tiles are no longer rejected outright.

`getRocRollerSelectedSolutions` also gains the workspace rejection that
the rocRoller-enabled path already applies at `gemm.cpp:703-706`.
Without it an `OFF` build hands back a StreamK kernel that an `ON` build
would have skipped, because `_convertToHeuristicResultArray` reports
`requiredWorkspaceSize` but never filters on it.

### Name matching is not enough on its own

A kernel's name carries its tile shape and its operand types, and
nothing else. Every other condition the kernel was captured under —
which scale layout it reads, the size multiples and size windows it
requires, how many batches it handles, how large a tensor it can address
— lives in the kernel's selection predicates. An ordinary library lookup
evaluates those; this hand-rolled search skipped them. A problem that
block-scales only one of its two operands therefore matched a kernel
built to read two scale tensors, and that kernel read a scale buffer the
caller had never allocated.

`getRocRollerSelectedSolutions` now requires a candidate's
`hardwarePredicate` and `problemPredicate` to accept the problem before
it takes a name match, and keeps searching when they do not. It tests
hardware and problem only, as the grouped-gemm path in the same file
does: `taskPredicate` needs a `Task`, which needs the workspace size
that is tested immediately afterwards.

This narrows what the `OFF` path selects. Where the kernel it used to
match declares a size window that excludes the problem, it now picks a
different one. That is the intended behaviour, but it has a cost,
measured below: the only candidates on this path are other rocRoller
kernels, so when the best-fitting tile is correctly rejected there may
be nothing comparable left in the pool.

The predicate moves to `rocroller_kernel_match.hpp`, whose only
dependency is `<string>`, so it can be tested without a problem
descriptor or a GPU.

No longer rejecting StreamK outright changes which kernel an `OFF` build
selects. That is intended — it is what lets an `OFF` build reach the
StreamK kernels at all — but this pull request tests it only at the
name-matching level. The selection-identity sweep that compares an `OFF`
build against an `ON` build lands with the logic that makes these
kernels selectable, later in this stack.

## Test Plan

- `CustomKernelTest.ScaleStrideIsCompactNotPadded`,
`CustomKernelTest.ScaleStrideIsCompactForEitherBoundDimension`,
`CustomKernelTest.ScaleBatchStrideFollowsTheCallerBuffer`,
`CustomKernelTest.ScaleStrideFollowsDescriptorWhenCallerDoesNotPack`,
`CustomKernelTest.ScaleStridesIncludeTheInitialStrideForDataParallelArgs`,
and `CustomKernelTest.ScaleStrideRoundsUpPartialBlocks`: assert that
`generateCustomCall` emits the caller's scale stride. A packed caller
with a `K` that is not a multiple of 256 gets `ceil(K/mxBlock)`, for
both bound dimensions and for the batch stride. An unpacked caller gets
the descriptor stride.
- `HostUnitRocRollerKernelMatch.*`: five host-only tests covering the
StreamK and plain tile discrimination, the pre-swizzle token rejection,
and the workgroup-mapping comparison. Mutation-check them by running
them against the pre-patch predicate; a test that passes against the old
code does not discriminate.
- `CustomKernelTest.ScaleStrideFollowsEachOperandsBuffer`: a packed A
with a padded B, and the reverse, each get their own buffer's row and
batch strides.
- `HostUnitMXScaleSetup.smoke_PreSwizzledDeclarationIsPerOperand`: a
pre-swizzled operand is declared unpacked, and declaring one operand
does not change the other.
- Numerical parity sweep on gfx950 over 108 MX problem and type
combinations against a 1e-6 tolerance, comparing each result with and
without this change.
- A problem that block-scales one operand only — `scaleA 3`, `scaleB 0`,
bf8 inputs, 1024x1024x1024 — on an `HIPBLASLT_ENABLE_ROCROLLER=OFF`
build. It must report no solution rather than launching a kernel.
- A selection sweep on the same build over 8 shapes that do block-scale
both operands, recording which kernel each build picks and whether it
verifies, to show the predicates narrow selection without rejecting
problems the kernels do serve. Numerical checks must be requested in the
test record itself, because a `--verify` flag on the command line does
not reach a record supplied by `--yaml`.

## Test Result

Completed evidence:

- Both `CustomKernelTest` cases are new and pass.
- All five `HostUnitRocRollerKernelMatch` tests are new and pass.
Against the pre-patch predicate, 4 of the 5 fail, so they discriminate
the change.
- Parity sweep: 36 of the 108 combinations were numerically wrong before
the change, with a normalized error as large as 6508 and `inf` in some
cases. After the change 0 are wrong and none regressed; the 63
combinations that were already clean are bit-identical.

Predicate evaluation, measured on MI355X (gfx950, PCI 0x75a3) against an
`HIPBLASLT_ENABLE_ROCROLLER=OFF` build, with the numerical check set in
the test record:

- One-sided MX, bf8 x bf8 -> f32 at 1024x1024x1024 with `scaleA 3` and
`scaleB 0`: before the change the run ends in `an illegal memory access
was encountered (700)`; after it, the problem reports no solution, on 2
of 2 runs.
- Selection sweep, f8 x f8 -> f32 with both operands block-scaled, over
8 shapes: every shape still receives a solution and every shape
verifies, on both builds, so no problem the kernels serve is rejected.
Five of the eight change kernel. For instance
`RR_GEMM_..._WGT_32x32x64_UR_2` declares M and N between 64 and 128 and
K exactly 128, and was being selected at 512x512x512.
- The narrowing costs performance where the rejected tile was the only
large one available. At 4096x4096x1024 the selection moves from
`RR_GEMM_..._WGT_256x128x128_UR_2`, whose declared window ends at M =
2560, to `RR_GEMM_..._WGT_16x16x128_UR_2`, and the kernel time rises by
a factor of about 3.6 over three repeats. That fallback, routing a
problem the rocRoller path declines to ordinary Tensile selection, is
#14497, later in this stack. It is not in this pull request.

Pending: automated GitHub checks have not reported on this branch. The
parity sweep was run locally on gfx950 hardware and does not run in a
shared CI lane today.

## Submission Checklist

- [x] Look over the contributing guidelines at
https://github.com/ROCm/TheRock/blob/main/GOVERNANCE.md#pull-requests.

## Risk level

Medium. Two pieces of device-visible behavior change. The scale stride
passed to custom MX kernels on gfx950 changes value whenever `K % 256 !=
0`, which is the defect being fixed; kernels generated by TensileLite
are unaffected because they overwrite that argument. Separately, an
`HIPBLASLT_ENABLE_ROCROLLER=OFF` build can now select StreamK kernels it
previously rejected, so kernel choice on that path changes; the
numerical consequence of that selection change is measured later in this
stack rather than here.

Evaluating the predicates narrows that path further, and the measured
blast radius is kernel choice rather than correctness: across the 8
shapes swept, no problem lost a solution and none failed verification,
while 5 changed kernel. The cost is performance, not accuracy, and it
falls on shapes that no checked-in rocRoller kernel was captured for —
previously served by a kernel used outside its declared window. The
largest measured case is about 3.6x slower. That cliff is removed by the
fallback in #14497, later in this stack, not by this pull request.
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