FlyDSL Python DSL#
The flydsl package provides the Python front-end for authoring GPU kernels
with explicit layout algebra.
Core module#
Expression API (flydsl.expr)#
The flydsl.expr module (imported as fx) provides the high-level Python
API for constructing Fly IR, including layout construction, tiled copies, tensor
operations, and kernel definitions.
import flydsl.expr as fx
Layout construction#
fx.make_layout(shape, stride) – create a layout from shape and stride tuples
fx.make_shape(*dims) – create a shape tuple
fx.make_stride(*strides) – create a stride tuple
fx.make_coord(*coords) – create a coordinate tuple
fx.make_ordered_layout(shape, order) – layout with explicit mode ordering
fx.make_identity_layout(shape) – identity layout (strides = prefix products)
Layout inspection#
fx.size(layout) – total number of elements
fx.cosize(layout) – codomain size
fx.rank(layout) – number of modes
fx.depth(layout) – nesting depth
fx.get_shape(layout) – extract shape tuple
fx.get_stride(layout) – extract stride tuple
fx.get_scalar(int_tuple) – extract the scalar from a single-leaf int tuple; use
fx.get_(int_tuple, mode).unpack()for per-mode access
Layout algebra#
fx.composition(a, b) – compose two layouts
fx.complement(layout, codomain_size) – complementary layout
fx.right_inverse(layout) – right inverse
fx.coalesce(layout) – coalesce contiguous modes
fx.recast_layout(layout, old_type, new_type) – recast layout for type change
Layout products and divides#
fx.logical_divide(tensor, tiler) – partition tensor by tiler layout
fx.zipped_divide, fx.tiled_divide, fx.flat_divide – divide variants
fx.logical_product(a, b) – layout product
fx.zipped_product, fx.tiled_product, fx.flat_product – product variants
fx.raked_product(thr_layout, val_layout) – interleaved (raked) product
fx.blocked_product(a, b) – blocked product
Coordinate mapping#
fx.crd2idx(coord, layout) – coordinate to linear index
fx.idx2crd(idx, layout) – linear index to coordinate
fx.slice(tensor, slices) – slice a tensor by coordinates or
Nonefx.get_(int_tuple, mode) – select a mode while preserving its structured result; use
.unpack()when a scalar result is required. The olderfx.getspelling is deprecated
Memory operations#
fx.make_rmem_tensor(shape_or_layout, dtype) – allocate register-file memory
fx.memref_load(memref, indices) – scalar load from memref
fx.memref_store(value, memref, indices) – scalar store to memref
fx.memref_load_vec(memref) – load entire register as a vector
fx.memref_store_vec(vec, memref) – store vector to register memref
fx.make_fragment_layout_like(tensor) – compute the corresponding fragment layout
fx.make_fragment_like(tensor) – allocate register fragment with same layout
Copy and GEMM#
fx.make_copy_atom(instr, dtype) – create a CopyAtom from instruction descriptor
fx.make_mma_atom(instr) – create an MmaAtom from an MMA op type (the op type carries the dtype, for example
fx.rocdl.MFMA(16, 16, 4, fx.Float32))fx.make_tile(*layouts) – build a tile from layouts (variadic)
fx.make_tiled_copy(copy_atom, layout_tv, tile_mn) – build a TiledCopy
fx.make_tiled_mma(mma_atom, …) – build a TiledMma
fx.copy(copy_atom, src, dst, pred=None) – execute a copy (with optional predicate mask)
fx.gemm(mma_atom, d, a, b, c) – execute matrix multiply-accumulate (accumulator passed as both
dandc)fx.copy_atom_call(atom, src, dst) – invoke a single copy atom
fx.mma_atom_call(atom, d, a, b, c) – invoke a single MMA atom
Derived tiled operations (flydsl.expr.derived)#
High-level classes for tiled copy and MMA partitioning:
CopyAtom (
flydsl.expr.typing) – single hardware copy instruction descriptorMmaAtom (
flydsl.expr.typing) – single MMA instruction descriptor (MFMA)CopyAtomType, MmaAtomType – atom type wrappers exported by
flydsl.expr.primitiveTiledCopy – multi-thread tiled copy; use
get_slice(tid)→ThrCopyTiledMma – multi-thread tiled MMA; use
get_slice(tid)→ThrMmaThrCopy – per-thread copy view:
partition_S(src),partition_D(dst),retile(t)ThrMma – per-thread MMA view:
partition_A(a),partition_B(b),partition_C(c)make_layout_tv(thr, val) – build thread-value layout
make_tiled_copy_A/B/C(copy_atom, tiled_mma) – create TiledCopy matched to MMA operands
fx.gather(copy_atom, base_iter, offset_tensor, dst_tensor, *, pred=None) – indexed load
dst = base[offset]via a copy atom (offset tensor is(TV, Rest...))fx.scatter(copy_atom, src_tensor, base_iter, offset_tensor, *, pred=None) – indexed store
base[offset] = src(seeexamples/05-gather_scatter.py)
Type annotations#
fx.Tensor – GPU tensor argument
fx.Constexpr[int] – compile-time constant
fx.Int32 – dynamic int32 argument
fx.Float32, fx.Float16, fx.BFloat16 – scalar types
fx.Float8E4M3FN, fx.Float8E4M3FNUZ, fx.Float8E5M2 – FP8 scalar types
fx.Stream – GPU stream argument
fx.T – type namespace (
T.f32,T.f16,T.bf16,T.i8,T.index, etc.)fx.Basis(value, modes) / fx.E(*modes) – basis-stride leaves for by-mode layout construction (
E(0)→1E0)fx.SyncScope – target-neutral LLVM sync scopes (
SyncScope.System,SyncScope.SingleThread); AMDGPU scopes live inflydsl.expr.rocdl.enum.SyncScope
GPU intrinsics (flydsl.expr.gpu)#
fx.thread_idx – thread index (
Tuple3Dwith.x,.y,.z)fx.block_idx – block index
fx.block_dim – block dimensions
fx.grid_dim – grid dimensions
fx.gpu.barrier() – workgroup barrier synchronization
fx.gpu.smem_space() – shared memory (LDS) address space attribute
Arithmetic and numeric types#
Prefer typed DSL values and operator-overloaded arithmetic:
import flydsl.expr as fx
from flydsl.expr.typing import Vector as Vec
c = fx.Int64(42)
v = fx.Int32(idx)
f = fx.Float32(1.0)
r = cond.select(a, b)
y = (x + 1) * scale
Preferred APIs:
fx.Int32(value), fx.Int64(value), fx.Float32(value) – typed constants and casts (use fx.Int64 for index/offset values and loop bounds; fx.Index is deprecated)
ArithValue / Numeric operators –
+,-,*,/,%,<<,>>cond.select(true_val, false_val) – ternary select when
condis anArithValuearith.cmpi(predicate, lhs, rhs) – integer comparison
arith.cmpf(predicate, lhs, rhs) – float comparison
fx.maxnumf(a, b) – float maximum returning the non-NaN operand (libm
fmax); preserves the DSL type ofafx.minnumf(a, b) – float minimum returning the non-NaN operand (libm
fmin); preserves the DSL type ofaChained comparisons (
lo <= x < hi) are supported inside traced kernels and lower to combinedcmp+and.
You can apply fastmath flags ambiently to a block or per-op:
with fx.fastmath(fx.FastMathFlags.fast):
y = a * b + c # float operators/math funcs inherit the flags
z = fx.exp(a, fastmath="contract") # explicit arg overrides the ambient scope
fx.fastmath(flags) – context manager applying
fastmathto float ops built in the block; nests and restores on exitfx.FastMathFlags – flag enum (
fast,contract,reassoc, …; combine with|)Direct ``arith.addf(…, fastmath=…)`` / ``arith.AddFOp(…, fastmath=…)`` – per-op flags where an ambient scope is not desired
Vector values (flydsl.expr.typing.Vector)#
Vec.from_elements(elements, dtype) – construct vector from scalars
Vec.filled(shape, value, dtype) – splat vector
Vec(value)[i] – extract element
Vec(value).bitcast(dtype) – bitcast vector element type
Vec(value).to(dtype) – convert vector element type
Vec(value).store(memref, indices) – store vector to memref
ROCDL operations (flydsl.expr.rocdl)#
AMD-specific operations for ROCm:
The exported universal and architecture namespaces are governed by API Stability. Importable target helpers or generated upstream ROCDL builders that are absent from the export chain remain unstable even when they are useful for source-tree kernel development.
fx.rocdl.make_buffer_tensor(tensor) – create buffer resource from tensor (CDNA buffer copy)
fx.rocdl.BufferCopy32b / BufferCopy128b – buffer copy instruction atoms
fx.rocdl.MFMA(m, n, k, elem_ty_ab, elem_ty_acc=None) – MFMA instruction atom constructor (CDNA3/CDNA4; 4th arg is the A/B element type; accumulator defaults to f32)
fx.rocdl.WMMA(m, n, k, elem_ty_ab, elem_ty_acc=None, **kwargs) – WMMA MMA atom constructor (arch-dispatched: gfx11 / gfx120x / gfx1250).
elem_ty_boptionally selects a different B operand type. gfx1250 supports f32(K4), f16/bf16(K32), fp8/bf8(K64/128), i8(K64), i4(K32); integer paths takesign_a/sign_b/clamp. gfx120x (RDNA4) supports 16x16x16 f16/bf16 and every fp8(E4M3FN)/bf8(E5M2) A/B combination to f32, on the v8 operand ABIfx.rocdl.WMMAScale(m, n, k, elem_ty_a, elem_ty_b=None, elem_ty_acc=None, *, opsel_a=0, opsel_b=0, mod_c=0, reuse_a=False, reuse_b=False, block_size=32) – unstable, target-specific gfx1250 MX-scaled WMMA (E8M0 block scale, f8/f6/f4;
16x16x128or32x16x128fp4-only). Per-operand scales are atom state (scale_a/scale_b)fx.rocdl.make_tdm_atom(tensor, tensor_extents, strides=None, *, num_warps, …) – unstable, target-specific gfx1250 TDM (Tensor Data Mover) async Global↔LDS whole-tile copy atom (rank 1-5); the global base comes from the
copy_atom_calloperand pointer, while the per-dim extent (OOB), stride,imm_offset, and MCASTworkgroup_maskare atom state.fx.rocdl.TDM(rank, num_warps, ...)builds the atom type only. Advance the K-loop tile withfx.copy(atom, gt, dst, imm_offset=...)fx.rocdl.sched_mfma(cnt) – insert MFMA scheduling barrier
fx.rocdl.sched_vmem(cnt) – insert VMEM scheduling barrier
fx.rocdl.sched_dsrd(cnt) – insert DS read scheduling barrier
fx.rocdl.sched_dswr(cnt) – insert DS write scheduling barrier
mfma_f32_16x16x16f16, mfma_f32_16x16x16bf16_1k, etc. – generated direct MFMA intrinsics; these low-level builders are unstable
Compiler API (flydsl.compiler)#
import flydsl.compiler as flyc
@flyc.kernel – decorator for GPU kernel functions
@flyc.jit – decorator for host-side JIT launch functions
flyc.from_dlpack(tensor) – convert DLPack-compatible tensors (PyTorch, etc.) to FlyDSL
JitArgumentRegistry – registry for custom argument type adapters
flydsl.compiler.kernel_function.CompilationContext – unstable implementation context available during kernel compilation; it is not a top-level
flydsl.compilersymbol
See also
Compiler and pipeline for the full compilation pipeline and pass details.