|
| 1 | +# AGENTS.md |
| 2 | + |
| 3 | +## Purpose |
| 4 | + |
| 5 | +This repository is ApproxMLIR, an accuracy-aware compilation framework built on MLIR. |
| 6 | + |
| 7 | +ApproxMLIR is not just a plugin or deployment artifact. Its main role is to provide a reusable substrate for expressing, lowering, transforming, and tuning approximations across different software stacks and abstraction levels. |
| 8 | + |
| 9 | +Agents should treat the repository as supporting several equally legitimate kinds of work: |
| 10 | + |
| 11 | +- core compiler research and development |
| 12 | +- runtime and autotuning infrastructure |
| 13 | +- frontend and backend integrations |
| 14 | +- workload-specific projects built on top of ApproxMLIR |
| 15 | + |
| 16 | +Examples of the last category include systems such as Triton-based kernel approximation or projects like ApproxLM that use ApproxMLIR as the approximation substrate for large-model workloads. |
| 17 | + |
| 18 | +## Core Framing |
| 19 | + |
| 20 | +ApproxMLIR exists to support unified approximation management across heterogeneous systems. |
| 21 | + |
| 22 | +The important design ideas are: |
| 23 | + |
| 24 | +- approximation should be represented explicitly, not buried in backend-specific ad hoc logic |
| 25 | +- approximation metadata and control should be non-invasive with respect to existing dialects |
| 26 | +- the same approximation interface should be reusable across ML and non-ML compilation flows |
| 27 | +- backend-specific lowering should not redefine the meaning of the shared approximation abstractions |
| 28 | + |
| 29 | +When in doubt, preserve these properties. |
| 30 | + |
| 31 | +## What ApproxMLIR Provides |
| 32 | + |
| 33 | +ApproxMLIR consists of: |
| 34 | + |
| 35 | +- the `approx` dialect, which represents approximation scopes and decisions |
| 36 | +- passes that lower approximation semantics and apply transformations |
| 37 | +- `approx-opt`, a reusable optimizer for ApproxMLIR pipelines |
| 38 | +- `approx-runtime`, which supports runtime control and autotuning flows |
| 39 | +- frontends and integrations for different host ecosystems |
| 40 | + |
| 41 | +Core dialect concepts include: |
| 42 | + |
| 43 | +- `approx.knob`: marks an approximation region |
| 44 | +- `approx.decide`: computes runtime approximation state |
| 45 | +- `approx.try`: expresses try-check-recover safety behavior |
| 46 | +- `approx.transform`: selects a transformation strategy and knob value |
| 47 | +- `approx.yield`: region terminator |
| 48 | +- `approx.util.annotation.*`: frontend annotations consumed by early passes |
| 49 | + |
| 50 | +Approximation strategies currently include: |
| 51 | + |
| 52 | +- `func_substitute` |
| 53 | +- `loop_perforate` |
| 54 | +- `task_skipping` |
| 55 | + |
| 56 | +## Canonical Pipeline |
| 57 | + |
| 58 | +The standard ApproxMLIR pass story is: |
| 59 | + |
| 60 | +1. `emit-approx` |
| 61 | +2. `emit-management` |
| 62 | +3. `config-approx` |
| 63 | +4. `transform-approx` |
| 64 | +5. `finalize-approx` |
| 65 | + |
| 66 | +Some flows also use `pre-emit-transform` before `transform-approx`. |
| 67 | + |
| 68 | +The high-level expectation is: |
| 69 | + |
| 70 | +- frontends emit annotations or approximation structure |
| 71 | +- passes materialize approximation semantics |
| 72 | +- transformations rewrite the underlying program |
| 73 | +- approx ops are eliminated by the end of the pipeline |
| 74 | +- downstream IR remains legal for the host compiler stack |
| 75 | + |
| 76 | +## Main Work Modes |
| 77 | + |
| 78 | +Before acting, identify which layer the task belongs to. Do not let one layer's constraints dominate the others by accident. |
| 79 | + |
| 80 | +### 1. Core compiler work |
| 81 | + |
| 82 | +This includes: |
| 83 | + |
| 84 | +- dialect design |
| 85 | +- pass implementation |
| 86 | +- legality and lowering |
| 87 | +- transformation correctness |
| 88 | +- IR invariants |
| 89 | +- regression tests |
| 90 | + |
| 91 | +Optimize for semantic clarity and reusable abstractions. Prefer backend-neutral designs unless the task is explicitly integration-specific. |
| 92 | + |
| 93 | +### 2. Runtime and tuning work |
| 94 | + |
| 95 | +This includes: |
| 96 | + |
| 97 | +- Python APIs |
| 98 | +- configuration objects |
| 99 | +- export and compilation glue |
| 100 | +- runtime semantics |
| 101 | +- OpenTuner integration |
| 102 | +- workload-specific pipeline selection |
| 103 | + |
| 104 | +Optimize for stable interfaces and clean separation between shared runtime logic and backend-specific execution paths. |
| 105 | + |
| 106 | +### 3. Integration work |
| 107 | + |
| 108 | +This includes integrating ApproxMLIR into systems such as: |
| 109 | + |
| 110 | +- IREE / StableHLO / JAX |
| 111 | +- Triton |
| 112 | +- C/C++ flows through Polygeist or related toolchains |
| 113 | + |
| 114 | +Optimize for preserving ApproxMLIR semantics while adapting to the host compiler's IR and pass APIs. |
| 115 | + |
| 116 | +Do not assume the host compiler's quirks should leak back into the core ApproxMLIR model unless that change is deliberate and broadly beneficial. |
| 117 | + |
| 118 | +### 4. Research extension work |
| 119 | + |
| 120 | +This includes projects that build on ApproxMLIR rather than merely deploying it. |
| 121 | + |
| 122 | +Examples: |
| 123 | + |
| 124 | +- identifying approximation opportunities in kernels or whole workloads |
| 125 | +- designing new approximation families |
| 126 | +- generating or inferring annotations automatically |
| 127 | +- constructing approximation search spaces |
| 128 | +- evaluating quality-performance tradeoffs |
| 129 | +- building systems like ApproxLM on top of ApproxMLIR |
| 130 | + |
| 131 | +For this kind of work, treat ApproxMLIR as the reusable approximation substrate. Triton, JAX, C++, or other ecosystems are frontend and evaluation paths, not the definition of the project itself. |
| 132 | + |
| 133 | +## Guidance For ApproxLM-Style Work |
| 134 | + |
| 135 | +If a task is about approximating kernels for large models, identifying opportunities automatically, or generating new approximate variants, prefer the following framing: |
| 136 | + |
| 137 | +- ask first whether the logic belongs in shared ApproxMLIR analysis or transformation infrastructure |
| 138 | +- only make it Triton-specific when the problem is truly tied to Triton IR or Triton runtime behavior |
| 139 | +- keep search-space construction and approximation semantics as general as possible |
| 140 | +- treat workload evaluation as separate from the core representation of approximation |
| 141 | + |
| 142 | +Good places for ApproxLM-style contributions may include: |
| 143 | + |
| 144 | +- generic analysis passes |
| 145 | +- annotation generation utilities |
| 146 | +- new transform abstractions |
| 147 | +- runtime support for evaluating candidate approximations |
| 148 | +- thin frontend hooks for Triton or other kernel generators |
| 149 | + |
| 150 | +Avoid prematurely hard-coding research ideas into one backend integration if they could live at a shared layer. |
| 151 | + |
| 152 | +## How To Avoid Misleading Future Work |
| 153 | + |
| 154 | +Keep these boundaries in mind: |
| 155 | + |
| 156 | +- ApproxMLIR is not "the Triton plugin project" |
| 157 | +- Triton is one important integration target, not the sole target |
| 158 | +- JAX/IREE, C/C++, and future frontends should remain conceptually first-class |
| 159 | +- deployment goals are local priorities, not repository-wide definitions |
| 160 | +- backend-specific compatibility code should stay scoped to backend-specific layers where possible |
| 161 | + |
| 162 | +If a task is ambiguous, classify it explicitly as one of: |
| 163 | + |
| 164 | +- core compiler work |
| 165 | +- runtime/tuning work |
| 166 | +- integration work |
| 167 | +- research extension work |
| 168 | + |
| 169 | +Then optimize for that layer. |
| 170 | + |
| 171 | +## Current Local Priority |
| 172 | + |
| 173 | +On this machine, there is an active Triton deployment effort. The immediate operational target is: |
| 174 | + |
| 175 | +- `runtime/examples/example_triton_wo_tuning.py` runs successfully on the Jetson machine |
| 176 | + |
| 177 | +This is a local deployment milestone. It should guide debugging for Jetson setup work, but it should not override the broader ApproxMLIR framing above for unrelated tasks. |
| 178 | + |
| 179 | +## Triton Integration Summary |
| 180 | + |
| 181 | +Triton's rough pipeline is: |
| 182 | + |
| 183 | +- Python AST -> TTIR -> TTGIR -> LLVM IR -> PTX/AMDGCN |
| 184 | + |
| 185 | +ApproxMLIR integrates at the TTIR stage through an out-of-tree pass plugin. |
| 186 | + |
| 187 | +Relevant repo locations: |
| 188 | + |
| 189 | +- Triton plugin: `external-tools/approx-triton-plugin` |
| 190 | +- Triton example target: `runtime/examples/example_triton_wo_tuning.py` |
| 191 | +- Triton runtime hook code: `runtime/approx_runtime/triton_hook.py` |
| 192 | +- Triton compiler bridge: `runtime/approx_runtime/triton_compiler.py` |
| 193 | +- Pipeline selection logic: `runtime/approx_runtime/compiler.py` |
| 194 | + |
| 195 | +The plugin is loaded with: |
| 196 | + |
| 197 | +- `TRITON_PASS_PLUGIN_PATH=/path/to/libApproxTritonPlugin.so` |
| 198 | + |
| 199 | +The Triton path does not use `approx-opt`; it drives passes through Triton's pass manager. |
| 200 | + |
| 201 | +## Triton Pass Pipeline |
| 202 | + |
| 203 | +The current Triton plugin registers: |
| 204 | + |
| 205 | +1. `emit-approx` |
| 206 | +2. `emit-management` |
| 207 | +3. `config-approx` |
| 208 | +4. `pre-emit-transform` |
| 209 | +5. `transform-approx` |
| 210 | +6. `finalize-approx` |
| 211 | + |
| 212 | +`legalize-to-stablehlo` is not part of the Triton path. |
| 213 | + |
| 214 | +For `func_substitute`, `pre-emit-transform` may be needed because Triton uses Triton-specific function/call ops and compatibility handling may be required before the generic transformation pass runs. |
| 215 | + |
| 216 | +## Recommended Debug Order For Triton Deployment |
| 217 | + |
| 218 | +If `runtime/examples/example_triton_wo_tuning.py` fails, check in this order: |
| 219 | + |
| 220 | +1. Python imports: |
| 221 | + - `approx_runtime` |
| 222 | + - `triton` |
| 223 | + - `torch` |
| 224 | +2. GPU availability: |
| 225 | + - `torch.cuda.is_available()` |
| 226 | +3. Plugin build artifact exists: |
| 227 | + - `libApproxTritonPlugin.so` |
| 228 | +4. Plugin path exported: |
| 229 | + - `TRITON_PASS_PLUGIN_PATH` |
| 230 | +5. Triton can load the plugin and enumerate passes |
| 231 | +6. TTIR hook is being installed |
| 232 | +7. Approx annotations are injected into TTIR |
| 233 | +8. The approx helper TTIR is available for `func_substitute` |
| 234 | +9. The transformed TTIR still lowers through Triton successfully |
| 235 | + |
| 236 | +Prefer confirming the failure stage with the example script before making broad changes. |
| 237 | + |
| 238 | +## Files Worth Reading First |
| 239 | + |
| 240 | +For general ApproxMLIR understanding: |
| 241 | + |
| 242 | +- `README.md` |
| 243 | +- `include/` |
| 244 | +- `lib/` |
| 245 | +- `runtime/README.md` |
| 246 | + |
| 247 | +For Triton-specific work: |
| 248 | + |
| 249 | +- `runtime/examples/example_triton_wo_tuning.py` |
| 250 | +- `runtime/approx_runtime/triton_hook.py` |
| 251 | +- `runtime/approx_runtime/triton_compiler.py` |
| 252 | +- `runtime/approx_runtime/compiler.py` |
| 253 | +- `external-tools/approx-triton-plugin/README.md` |
| 254 | +- `external-tools/approx-triton-plugin/pass/ApproxTritonPlugin.cpp` |
0 commit comments