Go to file
Cao Ying d39accf3d7
[Fix][CI] Isolate dynamo state in torch.compile tests (#1743)
Closes #1741

## Summary

- Add a shared `isolated_dynamo` fixture in `tests/conftest.py` that
runs `torch._dynamo.reset()` before and after every `torch.compile`
test.
- Request the fixture from all compile tests (`test_compile.py`,
`test_elementwise_compile.py`, `test_norm_ops.py`, `test_pool.py`),
replacing the module-local reset fixture in
`test_elementwise_compile.py`.
- Fixes `FailOnRecompileLimitHit` on all three `test_mha_kernel_compile`
cases in the push-tier gpu-smoke run (cross-test dynamo cache pollution,
not intrinsic guard churn).

## Test plan

- [x] Modified files pass unit tests (297/297 nodes across the 4 touched
test files at 8de7df1e; pre-commit green)
- [x] All three `test_mha_kernel_compile` parametrizations pass under
the push-tier selection `-m "smoke or full" -k compile` with push-tier
ordering on H200 (11/11; 3 failed pre-fix). CI push-tier confirmation
lands on the post-merge run — PR-event gpu-smoke runs `-m smoke` only.
- [x] This PR documents the flip commit/mechanism and the layer choice
(see Regression)
- [ ] Subsequent push-to-main GPU Smoke run is green (verifiable only
after merge)

## Regression

- **Flip commit**: c9229cab (#1731) added
`test_max_pool1d/3d_compile_fullgraph` (2 params each, smoke tier),
raising pre-MHA push-tier compiles from 4 (norm 2 + pool2d 2) to exactly
8.
- **Mechanism**: dynamo's recompile cache is keyed per code object.
`torch.compile` of any plain callable (every TileOps `Op` instance via
`Op.__call__`) shares torch's single wrapper frame `inner`
(`torch/_dynamo/external_utils.py:66`), so each compiled op instance in
one pytest process consumes one of the 8 `cache_size_limit` slots of
that shared frame. The first `test_mha_kernel_compile` case was the 9th
entry → `FailOnRecompileLimitHit` under `fullgraph=True`; all three MHA
parametrizations failed.
- **Reproduction**: `pytest tests/ops/test_norm_ops.py
tests/ops/test_pool.py tests/test_compile.py -m "smoke or full" -k
compile` — 3 failed pre-fix, 11 passed post-fix on H200.
`tests/test_compile.py` alone passed pre-fix, confirming cross-test
cache pollution rather than intrinsic guard churn.
- **Why test-isolation layer (not op wrapper, not a limit raise)**: the
exhausted code object is torch-owned and shared across ALL compiled
plain callables, so no `tileops/ops/` wrapper change can prevent
distinct op instances consuming per-code-object cache slots; each
individual compile is legitimate (one entry per instance, no intra-test
recompilation). Fix: shared `isolated_dynamo` fixture in
`tests/conftest.py` (`torch._dynamo.reset()` before/after) requested by
every `torch.compile` test. Raising `cache_size_limit` was rejected — it
would mask the next capacity flip instead of removing cross-test
coupling.

## Test node delta

```
File                                     Base    HEAD    Delta
--------------------------------------------------------------
tests/conftest.py                           0       0        0
tests/ops/test_elementwise_compile.py       0      84      +84
tests/ops/test_norm_ops.py                  5       5        0
tests/ops/test_pool.py                    205     205        0
tests/test_compile.py                       3       3        0
--------------------------------------------------------------
TOTAL                                     213     297      +84
```

**Justification:** no real growth. The +84 on
`tests/ops/test_elementwise_compile.py` is a base-side pytest collection
failure in the delta tool (warning emitted); the file has the same 84
nodes at base and HEAD — the diff only rewires an autouse fixture (2
insertions, 5 deletions, no test functions added).

---------

Co-authored-by: Ibuki 🍃 — a wind born from GPTs <Ibuki-wind@users.noreply.github.com>
2026-07-25 15:49:19 +08:00
.claude [Chore] strip scaffolding comments and validator-narration docstrings 2026-05-17 10:12:56 +08:00
.foundry [Design] Trust-model rules become review lens; retire strict-mode auto-reject (#1424) 2026-05-11 18:16:25 +08:00
.github [CI][Runner] Fix benchmark baseline dependencies (#1710) 2026-07-15 19:24:02 +08:00
assets [Doc] Add development doc and update readme (#75) 2026-01-05 09:14:25 +08:00
benchmarks [Refactor][Ops] Infer static metadata from forward inputs (#1734) 2026-07-25 12:05:17 +08:00
docs [Feat][Ops] Infer shape metadata from op inputs (#1651) 2026-07-06 17:51:47 +08:00
scripts [Fix][Manifest] Keep UnaryOp dispatch visible to validator (#1708) 2026-07-15 14:18:01 +08:00
tests [Fix][CI] Isolate dynamo state in torch.compile tests (#1743) 2026-07-25 15:49:19 +08:00
tileops [Refactor][Ops] Infer static metadata from forward inputs (#1734) 2026-07-25 12:05:17 +08:00
workloads [CI][Nightly] Restore benchmark and op test coverage (#1712) 2026-07-19 08:10:10 +08:00
.gitignore [Perf][Mamba] Tune SSD chunk state default tile config (#1512) 2026-05-21 19:44:28 +08:00
.pre-commit-config.yaml [CI][Tooling] Unify issue and PR auto-labeling into a single workflow (#280) 2026-03-02 19:26:01 +08:00
CLAUDE.md [Doc] move tileops-skills.md out of docs/design/ (#1108) 2026-04-29 11:01:38 +08:00
LICENSE [Chore] Update README, pre-commit hooks and reformat. (#82) 2026-01-05 18:20:15 +08:00
Makefile [Fix][CI] Install external baseline libraries in nightly benchmarks (#673) 2026-03-26 15:06:45 +08:00
README.md [Refactor][CI] retarget README badges to spec / bench coverage (#1470) 2026-05-15 17:41:52 +08:00
THIRD_PARTY_NOTICES.md [Perf][Linear-Attn] Add optimized Gated DeltaNet prefill op (#1596) 2026-07-07 21:10:18 +08:00
constraints.txt [CI] retire run-local venv across CI; install via image-baked stack (#1606) 2026-06-24 13:22:59 +08:00
pyproject.toml [CI] retire run-local venv across CI; install via image-baked stack (#1606) 2026-06-24 13:22:59 +08:00

README.md

TileOPs

Spec-driven GPU operator library for LLMs — designed for AI agents to build, evaluate, and optimize

Built on TileLang

Spec coverage Bench coverage

Installation | Quick Start | Docs

Status: TileOPs is under active development. APIs may change.

Overview

TileOPs is a GPU operator library for LLM training and inference, built on TileLang. Beyond providing a growing collection of production-quality operators, TileOPs explores a spec-driven development model where AI agents can read declarative operator specifications, generate kernel implementations, and evaluate them against hardware-theoretical performance bounds — with minimal human scaffolding.

Architecture

Every operator is split into two layers with a strict boundary:

  • Op (L2) — stateless Python entry point. Handles validation, dtype casting, and memory layout. Compatible with CUDA-Graph and torch.compile.
  • Kernel (L1) — TileLang GPU implementation with hardware-specific optimizations (Ampere, Hopper).

This separation keeps user-facing behavior independent of GPU strategy, allowing agents and developers to modify either layer without side effects on the other.

Key Properties

  • Spec-driven — each operator is declared in a machine-readable manifest (tileops/manifest/) that specifies signatures, workloads, and roofline formulas, serving as the entry point for both agent code generation and automated validation
  • Roofline-evaluated — kernel performance is measured against Speed-of-Light hardware bounds, not relative baselines
  • Auto-tuning — built-in search over tile sizes, pipelines, and scheduling parameters
  • Lightweight — depends only on TileLang, PyTorch, and einops

Installation

TileOPs can be installed from PyPI or built from source. A CUDA-capable GPU is required.

Prerequisites

  • Python >= 3.10
  • PyTorch >= 2.1
  • CUDA Toolkit
  • NVIDIA GPU: Hopper (SM_90)
  • TileLang == 0.1.9

From PyPI

pip install tileops

From source

git clone https://github.com/tile-ai/TileOPs
cd TileOPs
make install    # dev dependencies + pre-commit hooks

[!NOTE] If CUDA and TileLang are already installed system-wide and you encounter build issues: PIP_NO_BUILD_ISOLATION=1 pip install -e '.[dev]' -v && pre-commit install

Verify:

python -m pytest tests/ -q    # requires a CUDA GPU

Quick Start

import torch
from tileops.ops import GemmOp

M, N, K = 1024, 1024, 512
dtype = torch.float16

gemm = GemmOp(M, N, K, dtype=dtype)

A = torch.randn(M, K, device="cuda", dtype=dtype)
B = torch.randn(K, N, device="cuda", dtype=dtype)

C = gemm(A, B)

Documentation

Design docs and development guides are in docs/. The full API reference and performance tables are published at TileOPs.github.io.

Contributing

See docs/ for design docs. Branch and commit conventions are in .claude/conventions/types.sh.

License

TileOPs is released under the MIT License.