Skip to content

feat(hipblaslt): Gemm-From-Anywhere custom kernel framework V1#9304

Open
jinchen62 wants to merge 60 commits into
developfrom
GemmFromAnywhere
Open

feat(hipblaslt): Gemm-From-Anywhere custom kernel framework V1#9304
jinchen62 wants to merge 60 commits into
developfrom
GemmFromAnywhere

Conversation

@jinchen62

@jinchen62 jinchen62 commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Motivation

hipBLASLt/TensileLite currently only dispatches kernels generated by Tensile's own assembly writer. Several teams (AITER, Composable Kernel, rocRoller, Wave, Triton, and eventually hipKittens) independently write high-performance GEMM kernels for the same hardware, duplicating tuning effort and fragmenting the AMD GEMM kernel ecosystem instead of pooling it behind one selection/dispatch path. Gemm-From-Anywhere (GFA) lets hipBLASLt load and run kernels from any of these sources through the existing Tensile solution-selection and device-library loading path, so the fastest available kernel for a given problem shape can come from anywhere, not just Tensile.

This is "Version 1": the foundational metadata format, host-code dispatch path, and one working demo kernel per source generator (see Confluence: Hipblaslt-kernel-from-anywhere). Follow-on milestones (hipKittens, full production kernel sets, JIT generation) are tracked separately and are out of scope here.

Technical Details

  • Self-describing kernels: each custom kernel .s file embeds a custom.config YAML block in its .amdgpu_metadata section, carrying provenance (Source.Origin/Repository/Version), a Features capability map, and — for external (non-Tensile) kernels — the full Tensile-side interface (args, macrotile, threads, grid, ProblemType, MatrixInstruction). See Tensile/CustomKernels/README.md.
  • Tensile.AddCustomConfig (new): extracts a kernel's interface from a Tensile benchmark test YAML and mechanically injects the custom.config block into the .s file.
  • Tensile.ValidateMetadata (new): CI-gate script (--strict) that walks CustomKernels/ and validates every kernel's embedded metadata; the same check is also available at build time via GlobalParameters.ValidateMetadata / --validate-metadata.
  • Host runtime: ContractionSolution/KernelArguments extended so the launch argument buffer is built generically from a kernel's declared args: list instead of requiring a hand-written C++ solution class per kernel.
  • Problem-shape predicates: SolutionStructs/Solution.py, Naming.py, and Contractions.py extended with AssertFree0/1ElementMultiple / AssertSummationElementMultiple (now up to 256) so a custom kernel can declare exactly which problem shapes it supports.
  • Organization: CustomKernels/ split into per-origin subdirectories (tensile/, aiter/, ck/, rocroller/, wave/, triton/); loader behavior is unchanged, the split is organizational only.
  • Working, checked-in, end-to-end demo kernels + test YAMLs (Tensile/Tests/custom/*.yaml) for: AITER bf16 GEMM, AITER MXFP4 GEMM (pre-shuffled scales), Composable Kernel bf16 GEMM, rocRoller fp16 GEMM, Wave bf16 GEMM, Triton MXFP4 GEMM, and a Tensile-native Stream-K custom kernel.
  • roc::mxDataGenerator wired into tensilelite's CMake for MX-type reference-data generation used by the MXFP4 demos.
  • While restoring the TensileLite Python unit-test suite to a running state (see Test Result), found and fixed two small, real bugs already present in this branch's own code: a custom-kernel detection gap in HandleCustomKernel.hasCustomKernel() for legacy-style logic-file entries, and an unhandled missing-file crash in the new Toolchain.Component.Assembler._retargetAssemblySource.
  • Unified single-kernel dispatch: ContractionSolution::generateSingleCall (develop's dedicated Tensile-kernel argument-packing path) was renamed and rewritten as generateCustomCall, which now builds the launch args for every single-kernel solution — Tensile-generated and external alike — by iterating the kernel's declared customKernel.args list instead of the old bespoke per-feature C++ blocks. GSU/Stream-K workspace-stride handling and the MBSK dstD/Synchronizer/GSUSync argument set are preserved (recomputed inline rather than threaded in as a parameter — see the "legacy generateSingleCall/singleCallArgs encoding" comments in ContractionSolution.cpp). generateSingleCallGroupedGemm (the separate grouped-GEMM path) is untouched.

Test Plan

  • New unit coverage: Tensile/Tests/unit/test_CustomKernelMetadata.py (AddCustomConfig extraction/injection, ValidateMetadata, predicate round-tripping) and extended test_custom_kernel_occupancy.py (occupancy over the new real gfx942/gfx950 custom kernels).
  • 7 new Tensile test YAMLs under Tensile/Tests/custom/ build and dispatch each demo kernel end-to-end through the real CustomKernels: fork-parameter path with ValidateMetadata: True enabled.
  • python -m Tensile.ValidateMetadata --strict over the full CustomKernels/ tree as the metadata CI gate.
  • Full pytest -m unit (the entire TensileLite Python characterization + unit suite) as the regression net for everything under Tensile/.
  • Direct side-by-side comparison against a develop baseline checkout on the same gfx942/gfx950 hardware, running the same suites on both: the full hipblaslt-test C++ client gtest suite, the tensilelite-tests C++ host-library gtest suite, and the common/gemm/*.yaml integration tests — to separate any pre-existing issue from anything this PR introduces.

Test Result

Ran locally against gfx942/gfx950 as part of preparing this PR, including a full side-by-side comparison against a develop baseline checkout on the same hardware:

  • python -m Tensile.ValidateMetadata --strict126 kernels, 0 errors, 0 warnings.
  • Full pytest -m unit5368 passed, 0 failed, 222 skipped, confirmed byte-identical across two clean re-runs (cache cleared each time).
  • hipblaslt-test (full C++ client gtest suite): 79102 run, 79096 passed, 6 skipped, 0 failed — identical on develop and GemmFromAnywhere, including the exact same 6 skipped tests.
  • YAML integration tests, common/gemm/*.yaml (58 files): 52 PASS / 6 fail on both branches, same 6 files failing with "0 valid solutions" (f32_mac, f64_gfx90a, f64_mac, i8_gsu, gemm_bias_strided_batched[_broadcast]) — confirmed pre-existing and unrelated to this PR.
  • YAML tests, custom/custom_{aiter,ck,rr,tensile_sk,triton,wave}.yaml (new, GFA-only, no equivalent exists on develop): all 7 PASS.
  • tensilelite-tests (C++ host-library gtest suite): 349 passed, 1 failed, 3 skipped — identical on both branches, including the same pre-existing failure (RangeLibraryTest.SpecificSizes/0, a missing nonTemporalA key in Kernels_gfx950.yaml) and the same 3 skips.

Risk level

Medium-High. Reasons:

  • Diff is 183 files / +300,929 / −329 vs develop, blowing through the Libraries PR Bot's size thresholds (50 files / 2000 changes / 700-per-file) — expect a non-blocking size warning. ~296K of the insertions are checked-in kernel .s files, not hand-written logic; the reviewable source surface is closer to 50 files.
  • Touches high-coupling shared files (KernelWriter.py, KernelWriterAssembly.py, ContractionSolution.cpp) — per this repo's hipblaslt-pr-quality skill these need 2 hipBLASLt code-owner approvals and a rebase+re-test if develop has moved on them since this diverged (checked at PR-update time: develop had not moved since this branch's last merge).
  • The new dispatch path is additive/opt-in (only engaged when a solution actually picks a CustomKernel:-listed kernel), so existing Tensile-generated-kernel selection should be unaffected.
  • The Python unit/characterization suite is now confirmed green end-to-end (see Test Result) — this is new information as of this PR; it had not run to completion on this branch before, so reviewers should not assume other CI-adjacent suites silently passed without directly confirming they too ran to completion.
  • ContractionSolution::generateSingleCall was renamed/rewritten as generateCustomCall and now drives kernel-argument packing for all single-kernel solutions generically from each kernel's declared customKernel.args, not just custom ones — this is the single highest-scrutiny item in the PR, since it's the core dispatch path for every non-grouped-GEMM kernel launch. Traced the one specific risk this raised (the dropped gsuSettings parameter) to a faithful inline recomputation with the old MBSK dstD/Synchronizer/GSUSync arguments reappearing as explicit cases in the new generic loop, corroborated by the hipblaslt-test/common/gemm parity above — but this has not been re-verified with a full line-by-line audit against every CustomArgSemantic case, so reviewers with ContractionSolution.cpp context should treat this rename as the primary focus area.

Submission Checklist

AlexBrownAMD and others added 30 commits April 1, 2026 07:27
Add code object V6.
Fix some build/packaging issues with new custom kernel format.
Add DebugPattern argument which puts easy to spot data in the argument buffer for debugging.
Update build scripts to allow subdirectories in CustomKernels folder to
help organize files.
Update the way CustomKernel info gets stored in a solution to improve
default build, and avoid having to come up with equivalent tuning
arguments to describe external kernels.
- Add padding argument semantic
  e.g. { type: uint32, semantic: Padding}
- Add padding param to the arg
  e.g. { type: address, semantic: AddressD, padding: 8 }
  
AIGECORE-1985
Fix `KeyError: 'MFMA_BF16_1K'` when building install.sh
@therock-pr-bot

therock-pr-bot Bot commented Jul 11, 2026

Copy link
Copy Markdown

❌ PR Check — Action Required

Check Status Details
🌿 Branch Name ✅ Pass
📝 PR Title/Description ❌ Fail Error: PR description must reference a JIRA ID, ISSUE ID, or a GitHub closing keyword.
Expected: include a JIRA ID / ISSUE ID line (separator : or -, or omitted; value may be a JIRA key, a number with/without #, or a link), OR a closing keyword + issue reference. Accepted examples:
JIRA ID : TESTAUTO-6039
JIRA ID - #330
JIRA ID #330
ISSUE ID : TESTUTO-3334
ISSUE ID #3334
ISSUE ID - TESTAUTO-3433
ISSUE ID : https://github.com/<org_name>/<repo_name>/issues/1234
Closes #10
Fixes octo-org/octo-repo#100
Resolves: #123
#123
https://github.com/<org_name>/<repo_name>/issues/123
Current: no valid JIRA/ISSUE/closing-keyword reference found
Forbidden Files ✅ Pass
🧪 Unit Test ✅ Pass
🔎 pre-commit ✅ Pass
🚫 Draft PR 🔜 To Be Enabled
🚩 Feature Flag 🔜 To Be Enabled
📊 Code Coverage 🔜 To Be Enabled

⚠️ 1 policy check(s) failed. Please address the issues above before this PR can be Reviewed.

🚫 Please fix the failed policies

  • ❌ PR Title/Description

The Not ready to Review label was added to this PR. Once all policies pass, the label is removed automatically.

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

@therock-pr-bot

Copy link
Copy Markdown

🚫 Please fix the failed policies before requesting reviews.

The following policy checks failed:

  • ❌ PR Title/Description

The Not ready to Review label has been added to this PR.
Once all policies pass, the label will be removed automatically.

@codecov-commenter

codecov-commenter commented Jul 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 37.63158% with 474 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...s/hipblaslt/tensilelite/Tensile/AddCustomConfig.py 50.21% 103 Missing and 18 partials ⚠️
...ects/hipblaslt/tensilelite/Tensile/KernelWriter.py 0.88% 112 Missing ⚠️
...cts/hipblaslt/tensilelite/Tensile/CustomKernels.py 50.28% 66 Missing and 24 partials ⚠️
...lt/tensilelite/Tensile/SolutionStructs/Solution.py 18.33% 47 Missing and 2 partials ⚠️
.../hipblaslt/tensilelite/Tensile/ValidateMetadata.py 40.00% 20 Missing and 1 partial ⚠️
...rojects/hipblaslt/tensilelite/Tensile/LibraryIO.py 0.00% 18 Missing ⚠️
...hipblaslt/tensilelite/Tensile/BenchmarkProblems.py 6.67% 14 Missing ⚠️
...pblaslt/tensilelite/Tensile/Toolchain/Component.py 20.00% 12 Missing ⚠️
...ipblaslt/tensilelite/Tensile/Toolchain/Assembly.py 58.33% 5 Missing and 5 partials ⚠️
...ilelite/Tensile/TensileLogic/HandleCustomKernel.py 10.00% 9 Missing ⚠️
... and 6 more

❌ Your project status has failed because the head coverage (76.84%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #9304      +/-   ##
===========================================
- Coverage    65.36%   65.32%   -0.04%     
===========================================
  Files         2685     2687       +2     
  Lines       422269   422979     +710     
  Branches     62742    62922     +180     
===========================================
+ Hits        276012   276303     +291     
- Misses      125466   125830     +364     
- Partials     20791    20846      +55     
Flag Coverage Δ *Carryforward flag
TensileLite 35.14% <37.63%> (+0.07%) ⬆️
hipBLAS 90.81% <ø> (ø) Carriedforward from 53acec6
hipBLASLt 34.69% <ø> (ø)
hipCUB 82.68% <ø> (ø) Carriedforward from 53acec6
hipDNN 86.13% <ø> (ø) Carriedforward from 53acec6
hipFFT 50.88% <ø> (ø) Carriedforward from 53acec6
hipRAND 76.12% <ø> (ø) Carriedforward from 53acec6
hipSOLVER 69.18% <ø> (ø) Carriedforward from 53acec6
hipSPARSE 86.10% <ø> (ø) Carriedforward from 53acec6
rocBLAS 47.91% <ø> (ø) Carriedforward from 53acec6
rocFFT 55.50% <ø> (ø) Carriedforward from 53acec6
rocRAND 57.02% <ø> (ø) Carriedforward from 53acec6
rocSOLVER 76.84% <ø> (ø) Carriedforward from 53acec6
rocSPARSE 72.37% <ø> (ø) Carriedforward from 53acec6
rocThrust 91.36% <ø> (ø) Carriedforward from 53acec6

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

Files with missing lines Coverage Δ
...ects/hipblaslt/tensilelite/Tensile/ClientWriter.py 46.88% <100.00%> (+0.10%) ⬆️
.../hipblaslt/tensilelite/Tensile/Common/Constants.py 100.00% <ø> (ø)
...slt/tensilelite/Tensile/Common/GlobalParameters.py 87.40% <100.00%> (+0.05%) ⬆️
...aslt/tensilelite/Tensile/Common/ValidParameters.py 89.00% <ø> (ø)
...ite/Tensile/TensileCreateLibrary/ParseArguments.py 11.94% <ø> (ø)
...blaslt/tensilelite/Tensile/KernelWriterAssembly.py 9.97% <50.00%> (ø)
.../hipblaslt/tensilelite/Tensile/Common/Utilities.py 99.24% <80.00%> (-0.76%) ⬇️
...ects/hipblaslt/tensilelite/Tensile/Contractions.py 77.34% <83.33%> (+1.42%) ⬆️
projects/hipblaslt/tensilelite/Tensile/Tensile.py 50.66% <25.00%> (-0.27%) ⬇️
...aslt/tensilelite/Tensile/SolutionStructs/Naming.py 78.03% <42.86%> (-0.88%) ⬇️
... and 11 more
🚀 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.

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.

4 participants