# StinkyTofu Configuration via GlobalParameters Control StinkyTofu behavior through Tensile's `GlobalParameters` system -- either via `--global-parameters` on the CLI or in the YAML configuration file. ## Quick Reference | Parameter | Values | Default | Purpose | |---|---|---|---| | `StinkyTofuOptLevel` | `0`, `1`, `2`, `3` | `0` | Pipeline optimization level | | `StinkyTofuDebugLevel` | `0`, `1`, `2` | `0` | Diagnostic output verbosity | | `StinkyTofuPrintBeforePass` | comma-separated pass names | `""` | Print IR before specific passes | | `StinkyTofuPrintAfterPass` | comma-separated pass names | `""` | Print IR after specific passes | | `StinkyTofuDebugPass` | comma-separated pass names | `""` | PASS_DEBUG logging | | `StinkyTofuVerifyEach` | `0`, `1` | `0` | Verify StinkyTofu ASM IR after every pass | | `StinkyTofuEnableRemarks` | `0`, `1` | `0` | Emit optimization remarks to stderr | --- ## `StinkyTofuOptLevel` Maps directly to the pipeline's `OptLevel` enum (`O0`--`O3`). Set to `None` in YAML to disable the StinkyTofu feature entirely. --- ## `StinkyTofuDebugLevel` Debug output is **per-PM** -- the outer PassManager and each ScopeAdaptor's inner PassManager are configured independently. | Level | Output | Destination | |---|---|---| | `0` (default) | Silent | -- | | `1` | Pass names in execution order | stdout | | `2` | Initial IR before passes + IR after each pass | per-PM files (see below) | ### DebugLevel 2 file naming Each PM writes to its own file, named by scope: | Scope | File prefix | |---|---| | Outer PM | `kernel-OuterPM` | | Single-region adapter | `` (e.g. `loopWithPrefetch`) | | Multi-region adapter | `+` (e.g. `loopWithPrefetch+noLoadLoopBody`) | | Whole-kernel adapter | `wholeKernel` | Example files for a gfx1250 kernel: ``` kernel-OuterPM-before_passes.txt kernel-OuterPM-after_passes.txt loopWithPrefetch-before_passes.txt loopWithPrefetch-after_passes.txt noLoadLoopBody-before_passes.txt noLoadLoopBody-after_passes.txt loopWithPrefetch+noLoadLoopBody-before_passes.txt loopWithPrefetch+noLoadLoopBody-after_passes.txt ``` --- ## `StinkyTofuPrintBeforePass` / `StinkyTofuPrintAfterPass` Comma-separated list of pass names (case-sensitive) to selectively dump IR before or after. Output goes to per-PM files using the same naming convention as DebugLevel 2. These work independently of `StinkyTofuDebugLevel`. When both are set, they compose without duplication. Unmatched pass names are silently ignored. Pass names target the actual pass (e.g. `CFGBuilderPass`, `StinkyDAGSchedulerPass`), not the `ScopeAdaptor` wrapper. The pass runs inside an inner PM, so the IR dump shows the extracted region, not the full kernel. --- ## `StinkyTofuDebugPass` Comma-separated list of pass names (case-sensitive). Enables **PASS_DEBUG logging** -- prints pass-internal debug information (e.g. DAG graphs, scheduling decisions) to stderr for the listed passes. Unmatched pass names are silently ignored. **Global scope**: `DebugPass` is a global setting that applies to all PMs regardless of nesting. No per-PM configuration needed. --- ## `StinkyTofuEnableRemarks` Enables LLVM-style optimization remarks on stderr. Unlike `PASS_DEBUG` (which targets compiler developers), remarks are designed for **kernel developers** who want to understand the quality of generated code without reading raw IR. Currently the only remark-emitting pass is `LoopRegionRemarkPass`, which reports per-loop: | Metric | What it means | |--------|---------------| | **Region count** | Number of contiguous instruction stretches separated by non-movable side effects. Fewer regions = more scheduling freedom = better performance. | | **Boundary causes** | What splits each region: `[wait]` (s_waitcnt), `[store]` (global memory store), `[barrier]`, `[branch]`, or `[untokenized_mem]` (ds_read/ds_write/tensor_load without MemTokenData -- these could potentially be made movable by adding token support). | | **s_nop count** | `s_nop` instructions inserted by InsertDelayAluPass, indicating scheduling couldn't hide latency. Reports count and total wasted cycles. | | **Branch count** | Branches in the loop body. Too many branches hurt the hardware instruction prefetcher. | Example output: ``` analysis: LoopRegionRemark: loop 'loopWithPrefetch' summary: 142 insts, 4 regions, 2 s_nop (5 wasted cycles), 3 branches analysis: LoopRegionRemark: BB 'loopWithPrefetch_body': 4 regions, 3 boundaries: analysis: LoopRegionRemark: [wait] s_waitcnt_vscnt (inst #12) analysis: LoopRegionRemark: [barrier] s_barrier (inst #25) analysis: LoopRegionRemark: [wait] s_waitcnt_lgkmcnt (inst #38) analysis: LoopRegionRemark: BB 'loopWithPrefetch_body': 2 s_nop instructions (5 wasted cycles) ``` **What to do with the output:** - **High region count**: Look at the `[untokenized_mem]` boundaries -- these are memory operations that lack MemTokenData tokens. Adding token support for these operations would allow the DAG scheduler to move them freely, merging regions. - **s_nop waste**: Indicates the scheduler couldn't hide instruction latency. Consider reordering independent work to fill the gaps. - **Many branches**: Consider loop restructuring to reduce branch pressure on the instruction prefetcher. --- ## Usage ### Via CLI String values require both outer single quotes and inner double quotes (`'Key="value"'`) so that Python's `eval()` parses them correctly. This applies even for a single pass name. ```bash Tensile.sh config.yaml output/ --global-parameters StinkyTofuOptLevel=3 StinkyTofuDebugLevel=2 Tensile.sh config.yaml output/ --global-parameters StinkyTofuOptLevel=3 'StinkyTofuPrintAfterPass="CFG Builder, StinkyDAGSchedulerPass"' Tensile.sh config.yaml output/ --global-parameters StinkyTofuOptLevel=3 'StinkyTofuDebugPass="StinkyDAGSchedulerPass"' Tensile.sh config.yaml output/ --global-parameters StinkyTofuOptLevel=3 StinkyTofuEnableRemarks=1 ``` ### Via YAML ```yaml GlobalParameters: StinkyTofuOptLevel: 3 StinkyTofuDebugLevel: 2 StinkyTofuPrintAfterPass: "CFG Builder, StinkyDAGSchedulerPass" StinkyTofuDebugPass: "StinkyDAGSchedulerPass" StinkyTofuEnableRemarks: 1 ``` --- ## Scope These parameters apply to the **Tensile/KernelWriter integration path**. For `stinkytofu-opt`, use the equivalent CLI flags (e.g. `--remarks`). See [stinkytofu-opt README](../../tools/stinkytofu-opt/README.md).