The spec is the source; kernels are derived from it and judged against it.
Quick Start · Why it's different · How it works · Installation · Docs
import torch
from tileops.ops import GemmFwdOp
gemm = GemmFwdOp() # shapes and dtype are inferred at call time
a = torch.randn(1024, 512, device="cuda", dtype=torch.float16)
b = torch.randn(1024, 512, device="cuda", dtype=torch.float16)
d = gemm(a, b) # equals a @ b.TOperators are auto-tuned on first use, CUDA-Graph compatible, and declare their
torch.compile(fullgraph=True) support per op.
An implementation can be regenerated from its spec; a spec cannot be recovered from an implementation. The project is organised around the spec rather than around the kernels:
- The spec is self-contained. Generation reads it and nothing else, so every constraint on the implementation is declared rather than assumed.
- Acceptance is decidable. Correctness settles against a declared reference, performance against a modelled bound — neither is a judgement call.
- The operator/kernel split is enforced. The boundary is checked rather than agreed, because an unenforced convention does not survive automated edits.
- Conformance is validated at every stage. Spec, generated code, tests and benchmarks each answer to a validator, so an operator is certified as it is produced rather than reviewed once at the end.
Each operator is declared in src/tileops/manifest/ before it is implemented.
The entry drives code generation, testing, and benchmarking:
GemmFwdOp:
ref_api: "torch.matmul"
signature: {inputs: {a: {dtype: "float16 | bfloat16"}, b: {dtype: "same_as(a)"}}, ...}
workloads: [{m: 1024, n: 1024, k: 1024, dtypes: [float16, bfloat16]}]
roofline: {func: tileops.perf.formulas.gemm_fwd_roofline}
source: {kernel: ..., op: ..., test: ..., bench: ..., kernel_map: ...}| Field | Role |
|---|---|
ref_api |
Reference implementation the tests compare outputs against. |
signature |
Tensor contract, shape rules, and dtype combinations; enforced at the op layer. |
workloads |
Shapes and dtypes the tests and benchmarks cover. |
roofline |
Performance model. Efficiency is achieved throughput over the modelled bound. |
source |
Paths to the kernel, op, test, and benchmark, and the slot-to-kernel map. |
A validator checks every entry against its implementation in CI, so the declaration and the code stay in step.
The implementation is split in two layers. L2, the Python entry point, owns the caller-facing contract: validation, dtype casting, and memory layout. L1, the TileLang kernel, owns the GPU implementation. trust-model.md defines the boundary between them.
TileOPs installs from source; a PyPI release lands with the first stable version. A CUDA-capable GPU is required.
Prerequisites
- Python >= 3.10 (CI validates 3.12)
- PyTorch >= 2.1, < 2.14 (CI validates 2.13)
- CUDA Toolkit 13.2
- NVIDIA Hopper (SM_90)
- TileLang >= 0.1.9, < 0.2.0 (CI validates 0.1.11 at a pinned main snapshot — see development.md)
git clone https://github.com/tile-ai/TileOPs
cd TileOPs
pip install -e '.[dev]' -c constraints.txt # constraints.txt pins what CI validates
pre-commit install
python -m pytest -q tests -m smoke # verify; requires a CUDA GPUA prebuilt Docker image carries the whole stack and is the environment CI runs in — see development.md, along with test tiers, benchmarks, and build troubleshooting.
| development.md | Build, test, benchmark, dev image |
| architecture.md | Module map and the agent production loop |
| manifest.md | The spec format every operator starts from |
| ops-design.md | Adding an operator, step by step |
| roofline.md | How performance is scored against Speed-of-Light |
| trust-model.md | What each layer may assume about the others |
API reference and performance tables: TileOPs.github.io.
Operators are added through the loop above — start from ops-design.md, which walks the path from a manifest entry to a merged kernel.
TileOPs is released under the MIT License.