Files
TheRock/rocm-libraries/shared/stinkytofu/docs/developer/wmma-vgpr-reorder-pass.md
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

152 lines
4.5 KiB
Markdown

# WMMA VGPR Reorder Pass
## Overview
`StinkyWmmaVgprReorderPass` is a read-only analysis pass that detects VGPR savings
in N-buffered GEMM kernels by identifying when wmma instructions can be reordered
to allow cross-pool register aliasing.
The pass never mutates any instruction or register operand. All output is in
`WmmaReorderAnalysisResult` for downstream passes to act on.
---
## Problem
In an N-buffered GEMM loop body the wmma instructions are split into N pools, each
using its own set of registers for the pool-varying operand (either A or B depending
on the kernel). When that operand is the *outer* loop dimension its registers stay
live across all iterations of the inner dimension, preventing cross-pool aliasing and
wasting VGPRs.
Making the pool-varying operand the *inner* dimension (grouping its instructions
contiguously within each pool) tightens its liveness interval so that pool N's
registers die before pool 0's next use. The two pools can then be aliased to the
same physical registers.
---
## Three-Layer ABI
The pass is structured as three independent layers. Each can be swapped without
touching the others.
### Layer 1 — `IRegLivenessAnalysis`
Computes live intervals for the A and B register groups referenced by the wmma
sequence.
```cpp
class IRegLivenessAnalysis {
public:
virtual std::map<RegGroup, RegInterval> computeLiveness(
const BasicBlock& bb,
const std::vector<WmmaNode>& wmmaSeq) const = 0;
};
```
**Built-in implementation**: `WmmaIntervalLiveness`
Fast wmma-only backend. The interval for a register group is
`[first wmma index that reads it, last wmma index that reads it]`.
Sufficient for standard N-buffered GEMM patterns.
A full-instruction liveness backend can be substituted here without changing
anything else.
---
### Layer 2 — `IWmmaReorderAlgorithm`
Given the pre-grouped pools and precomputed live intervals, decides the optimal
reordering and which register groups can be aliased.
```cpp
class IWmmaReorderAlgorithm {
public:
struct Result {
std::vector<WmmaNode> desiredOrder;
std::vector<AliasCandidate> aliases;
};
virtual Result solve(
const std::vector<std::vector<WmmaNode>>& pools,
const std::map<RegGroup, RegInterval>& liveness) const = 0;
};
```
`pools` arrives already grouped and relabeled by `detectABIndices` so that
`WmmaNode::aGroup` is always the pool-varying operand and `WmmaNode::bGroup`
is always pool-shared.
**Built-in implementation**: `PoolVaryingReorderAlgorithm`
Checks whether the pool-varying operand (A) has inflated liveness
(`interval width > number of distinct B groups`). If so, reorders each pool
via `reorderContiguously` to make A groups contiguous, then pairs up
corresponding A groups across pools as alias candidates.
---
### Layer 3 — `WmmaReorderAnalysisResult`
The stable output contract consumed by all downstream passes.
```cpp
struct WmmaReorderAnalysisResult {
bool applicable;
std::vector<StinkyInstruction*> desiredWmmaOrder; // permutation of wmma pointers
std::vector<RegReplacement> replacements; // per-operand rewrite map
unsigned totalVgprSaved;
};
```
Retrieve after the pass runs:
```cpp
const WmmaReorderAnalysisResult* result = getWmmaReorderResult(bb);
```
---
## Pool Tagging
TensileLite stamps each wmma instruction with a `WmmaPoolData` modifier at
generation time so the pass can group instructions by pool without heuristics.
```cpp
struct WmmaPoolData : public TypedModifier<WmmaPoolData> {
uint32_t poolIndex = 0;
};
```
If any wmma instruction is missing this modifier the pass bails out for the
entire basic block. Partial tagging indicates a misconfigured pipeline and the
pass must not proceed on incomplete information.
---
## A/B Detection
`detectABIndices` determines which src operand index is pool-varying (A) vs
pool-shared (B) by checking register group intersection across pools. If src0's
groups appear in multiple pools it is pool-shared and src1 is A; otherwise src0
is A.
This means the pass handles both the standard case (hardware A is pool-varying)
and the symmetric case (hardware B is pool-varying) without any special-casing.
---
## Injecting Custom Implementations
Both the liveness backend and the algorithm are injected at construction:
```cpp
auto pass = createStinkyWmmaVgprReorderPass(
std::make_unique<MyLivenessBackend>(),
std::make_unique<MyReorderAlgorithm>());
```
Passing `nullptr` for either uses the built-in default.