You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -143,7 +143,7 @@ Verify `_scale = softmax_scale * q_scale * k_scale` matches the reference. Commo
143
143
144
144
### 6.1 `range()` vs `range_constexpr()` inside @flyc.kernel
145
145
146
-
FlyDSL's AST rewriter converts ALL`range()`to `scf.for` (runtime loops). Use `range_constexpr()` for compile-time unrolled loops:
146
+
FlyDSL's AST rewriter converts runtime`range()`loops into MLIR loops. Use `range_constexpr()` for compile-time unrolled loops:
147
147
```python
148
148
# WRONG: i becomes an ArithValue, can't index Python lists
149
149
for i inrange(4): result[i] =...
@@ -160,23 +160,23 @@ FlyDSL tracing evaluates Python `if` at trace time. Runtime GPU values can't be
160
160
if kv_tok < context_len: # runtime comparison
161
161
fx.printf(...)
162
162
163
-
# CORRECT: use arith.select for runtime conditionals
164
-
val =arith.select(kv_tok < context_len, good_val, bad_val)
163
+
# CORRECT: use ArithValue.select for runtime value selection
164
+
val = (kv_tok < context_len).select(good_val, bad_val)
165
165
```
166
166
167
167
Python `if` is fine for COMPILE-TIME decisions (e.g., `if trans_v:` where trans_v is a Python bool).
168
168
169
-
### 6.3 scf.for state packing
169
+
### 6.3 Loop-carried state packing
170
170
171
-
All loop-carried values must be raw SSA values (not Python wrappers):
171
+
Prefer FlyDSL internal types (`fx.Int32`, `fx.Float32`, `Vector`, `ArithValue`) for loop-carried state. Unwrap only when a low-level helper explicitly requires raw `ir.Value`:
172
172
```python
173
173
def_unwrap(v):
174
174
return v.ir_value() ifhasattr(v, 'ir_value') else v
175
175
176
176
init_state = [_unwrap(v) for v in [val1, val2, vec_val]]
177
177
```
178
178
179
-
Supported state types: `f32` (scalar), `f32x4` (vector), `i32`, `i64`, `index`.
179
+
Supported state types: `f32` (scalar), vector values, `i32`, `i64`, `index`.
180
180
181
181
### 6.4 buffer_load type mismatch
182
182
@@ -186,21 +186,21 @@ k_addr_bytes = ... # address in FP8 elements (= bytes for FP8)
- Runtime loops with carried state: `range(start, stop, step, init=[...])` using `fx.Index(...)` bounds
23
+
- Compile-time loops: `range_constexpr(...)`
24
+
25
+
Avoid new direct `scf.*`, `vector.*`, `memref.*`, `arith.index`, `arith.index_cast`, and `arith.trunc_f` in kernel bodies unless a lower-level boundary requires the exact op.
|`arith.select(cond, a, b)`|`cond.select(a, b)` when `cond` is an `ArithValue`|
43
+
44
+
## Important Exceptions
45
+
46
+
Keep the exact lower-level op when it encodes semantics that internal types do not expose:
47
+
48
+
-`llvm.InlineAsmOp` for hand-scheduled ISA snippets
49
+
-`llvm.LoadOp` / `llvm.StoreOp` when `volatile`, `nontemporal`, address space, or alignment must be explicit
50
+
-`arith.*FOp(..., fastmath=...)` when performance depends on fastmath flags
51
+
-`arith.DivUIOp` / `arith.RemUIOp` for unsigned integer division/remainder
52
+
-`rocdl.*` intrinsics and MFMA/WMMA/TDM ops
53
+
- Backend dialect/C++ lowering docs and implementation code
54
+
55
+
Do not hide these exceptions behind new helper wrappers just to remove the visible op. If exact semantics are required, keep the direct op at the boundary and document why.
56
+
57
+
## Control Flow
58
+
59
+
- Compile-time / constant conditions must be written as `if const_expr(condition): ...`. Do not rely on a plain Python `if` unless the condition is already a Python `bool`.
60
+
- Use ordinary Python `if` on runtime values only when the AST rewriter keeps branch-local values and side effects correct.
61
+
- For runtime branches inside nested helper functions, wrap the dispatch in a local `@flyc.jit` helper. This keeps branch side effects and loop-carried state in the right rewritten region.
62
+
- For complex runtime branches with side effects, loop-carried state, or branch-local definitions, split branch bodies into local helper functions and dispatch through a local `@flyc.jit` helper. Verify correctness and ASM/perf.
63
+
- Do not hand-write `scf.IfOp` in new kernel code unless the `@flyc.jit` helper pattern cannot express the required branch.
64
+
- Use `range(..., init=[...])` for runtime loops with carried state; unwrap init values only if the API specifically requires raw `ir.Value`.
65
+
66
+
Pattern:
67
+
68
+
```python
69
+
def_then_path():
70
+
...
71
+
72
+
def_else_path():
73
+
...
74
+
75
+
@flyc.jit
76
+
def_dispatch():
77
+
if runtime_cond:
78
+
_then_path()
79
+
else:
80
+
_else_path()
81
+
82
+
_dispatch()
83
+
```
84
+
85
+
## Verification Loop
86
+
87
+
For performance-sensitive kernels:
88
+
89
+
1. Record baseline shape coverage, timing, ASM hash, VGPR/SGPR counts, and spill counts.
90
+
2. Apply one cleanup group at a time.
91
+
3. Run correctness on small and large representative shapes.
92
+
4. Compare performance; for strict cleanups, compare ASM hash.
93
+
5. If performance drops or results change, revert that cleanup group and keep the lower-level op.
94
+
95
+
Recommended checks:
96
+
97
+
```bash
98
+
PYTHONPATH=python:. FLYDSL_RUNTIME_ENABLE_CACHE=0 <kernel test command>
0 commit comments