Parser utilities#

A few helpers act at parse time (when TVMScript is turned into TIRx), letting you inline Python-computed values, factor out reusable fragments, and bundle parser-side state.

T.meta_var — inline a Python value#

T.meta_var(x) tells the parser to treat x — a value computed in Python — as a compile-time meta value and inline it directly into the IR, rather than parse it as a script variable. It avoids a throwaway local and lets Python values parameterize the generated IR. A plain range(n) is still a serial TIRx loop; use T.unroll(n) when the lowering pipeline should unroll it.

n = T.meta_var(4)              # the constant 4 is inlined as the extent
for j in T.unroll(n):          # marked for the UnrollLoop lowering pass
    acc[0] = acc[0] + A[tx, j]

@T.inline — inline functions#

@T.inline defines a function whose body is inlined at each call site during parsing — no call appears in the generated code. It follows Python’s lexical (LEGB) scoping with late binding, so a parameter shadows an enclosing variable:

@T.inline
def add_into(acc, x):
    acc[0] = acc[0] + x

add_into(acc, A[tx, j])       # inlined -> acc[0] = acc[0] + A[tx, j]

@T.meta_class — parser-side state objects#

@T.meta_class marks a plain Python class whose instances are parser meta values: their fields can hold buffers and scalars, so you can bundle related allocations and state into one object and use it in the kernel body.

@T.meta_class
class State:
    def __init__(self, smem):
        self.acc = T.alloc_local([1], "float32")
        self.buf = T.decl_buffer([64], "float16", smem, scope="shared.dyn")

s = State(smem.data)
s.acc[0] = T.float32(0.0)     # use its fields like ordinary buffers
# ... s.buf[i] ...

This is handy for grouping a kernel’s pipeline state (barriers, accumulators, scratch views) instead of threading many separate locals through the body.

T.constexpr#

T.constexpr marks a compile-time kernel parameter, baked in by @T.jit’s .specialize(...). See Introduction to TIRx for the details.