Skip to content

[Docs] Follow the TileOPs manifest migration - #53

Merged
lcy-seso merged 16 commits into
tile-ai:mainfrom
lcy-seso:fix/bench/manifest-recursive
Sep 27, 2026
Merged

lcy-seso merged 16 commits into
tile-ai:mainfrom
lcy-seso:fix/bench/manifest-recursive

Conversation

@lcy-seso

@lcy-seso lcy-seso commented Sep 27, 2026 •

Copy link
Copy Markdown
Contributor

Problems

  • TileOPs moves its manifest YAML into src/tileops/manifest/spec/ ([Refactor][Manifest] Move the manifest YAML into spec/ under one file-naming rule TileOPs#2227); render_bench.sh and workload_shape.load_manifest read one level only, so the Benchmarks pages would lose their shapes.
  • TileOPs converted every manifest entry to a parametric signature (forall, dtype_cases, some); the renderer read only dtypes and <tensor>_shape, so 1087 workloads of the snapshot at 44727e21e showed no shapes.
  • check_api_pages.py failed: TileOPs renamed five ops and exported three the API pages did not list.
  • Writing a Spec, the new-op guide, torch.compile and backends taught the retired format and Op class: source, static_dims, {input}_shape, same_as, torch_compile_fullgraph, L0-L4 levels, default_kernel_map, hand-written _infer_output_shapes, tileops::normalization_*, and outdated backend error messages.

Changes

  • render_bench.sh lists the manifest with git ls-tree -r, and load_manifest reads **/*.yaml, so both layouts load; types.yaml is read as ADTs, not ops.
  • Parametric entries are instantiated by the checkout's tileops.manifest and matched on its case id; legacy snapshots render byte for byte as before (goldens unchanged). Against the #2227 manifest, 1280 of 1280 case ids resolve.
  • FP8LightningIndexerFwdOp moves from the Quantization to the Attention benchmark page, where the API reference lists it.
  • docs/api/ follows the renamed ops (NSA, DeltaNetAutogradFwdOp, FusedTopKFwdOp) and lists FusedMoeSharedExpertFwdOp, DeltaNetInferenceFwdOp, GLAInferenceFwdOp.
  • Links point at src/tileops/manifest/spec/; the shape_rules.py link is gone with the module.
  • Writing a Spec (en/zh) is rewritten on TileOPs docs/design/manifest.md: entry fields, reading a spec, five writing steps, four recurring forms from real entries, and the schema/signature/bench validator levels.
  • The new-op guide (en/zh) follows the current spec and Op class: kernel_types, generated checks, one role per memoization bucket, kernel classes choosing among themselves, manifest_calls.
  • torch.compile (en/zh): compile_boundary = True, _call_boundary, one operator per effect branch, tileops::norm_rms_norm_fwd, target resolved inside the operator.
  • Backends (en/zh): the parametric RMSNorm spec with optional weight, params passed as the instance holds them, the whole-op target path, and re-measured error messages.
  • The spec/ links resolve once [Refactor][Manifest] Move the manifest YAML into spec/ under one file-naming rule TileOPs#2227 merges; everything else works against TileOPs main and after the move.
  • Test node delta: +2 (test_a_manifest_in_a_subdirectory_renders_the_same_pages, test_a_parametric_row_resolves_through_the_tileops_checkout; the second skips without a TileOPs checkout).

…t package

TileOPs is moving its manifest YAML from src/tileops/manifest/ into src/tileops/manifest/spec/. The renderer globbed one level and git ls-tree listed one level, so after the move it would find no files and publish pages without workload shapes, logging only a warning.

Both readers now descend into subdirectories, which reads the flat layout of older benchmark commits and the nested layout of newer ones alike.
Copilot AI lite review requested due to automatic review settings September 27, 2026 02:39

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

TileOPs renamed five ops and exported three new ones, so check_api_pages.py failed the build on the old names. The pages now name NSACmpVarlenFwdOp, NSATopkVarlenFwdOp, NSAVarlenFwdOp, DeltaNetAutogradFwdOp and FusedTopKFwdOp, and list FusedMoeSharedExpertFwdOp, DeltaNetInferenceFwdOp and GLAInferenceFwdOp on their family pages.
@lcy-seso
lcy-seso force-pushed the fix/bench/manifest-recursive branch from 40a7124 to 5221a0e Compare September 27, 2026 02:52
TileOPs moved its manifest YAML into src/tileops/manifest/spec/ and renamed nothing a link here names except normalization.yaml, which has long been norm.yaml. The links now point at spec/, and the step that pointed at shape_rules.py drops the link, because TileOPs deleted that module.
…ec page

The page still taught the manifest format TileOPs has retired: `source`, `static_dims`, `{input}_shape` workload keys, `same_as` dtypes, rules that read `x.shape` and `x is None`, `torch_compile_fullgraph`, and a five-level L0-L4 validator. Every entry is now a parametric signature over `forall` indices, rows carry `dtype_cases` and `some`, and the validator runs the schema, signature and bench levels.

Both languages now follow TileOPs docs/design/manifest.md with real entries (RMSNormFwdOp, GemmFwdOp, GroupNormFwdOp, SSDDecodeFwdOp, GroupedQueryAttentionVarlenFwdOp), and link that spec for the complete rules instead of restating them.
…target path

The kernel-writing section quoted RMSNormFwdOp's retired spec, with a required `weight` and `same_as` dtypes; the entry now has `forall` indices and an optional `weight`, so a builder receives `None` in that slot. A parameter is passed as the op instance holds it, so an `eps` left at its null default arrives as `None`, not a computed number.

A target now serves the whole op after the generated checks, and `kernel_for` runs only on the in-tree path, so the call walk-through no longer routes the target through it. The error messages are re-measured on the current TileOPs: an unsupported device raises OpNotAvailableError from the op, and the call-site error no longer exists.
TileOPs converted its manifest to parametric signatures: a row gives type indices and dtype_cases instead of <tensor>_shape keys and a dtypes list, and the case id is built from the label, the dtype cases and the dtype parameters. The renderer read only the legacy form, so on the nightly snapshot at 44727e21e 1087 of its workloads lost their shapes. Parametric entries are now instantiated by the checkout's own tileops.manifest, which owns type families, let, generators and presence, and the case id is matched against the one it builds. Legacy entries keep their path, so historical snapshots render as before, and a row the checkout cannot instantiate keeps its id alone. types.yaml holds ADTs, not op entries, and is read as such.
The op lives in a top-level module, so the keyword table places it, and the fp8 keyword sent it to Quantization while the API reference lists it under Attention. A keyword ahead of fp8 now follows the API reference.
…on the new-op guide

The guide wrote GemmFwdOp's retired spec (`source`, `same_as`, a `shape_rules` output formula) and an op class that no longer exists: `default_kernel_map` from `source.kernel_map`, a hand-written `_infer_output_shapes`, a role chosen per kernel, and L0-L4 validation. The spec now names no file or kernel; the class declares `kernel_types`, the checks and shape inference are generated, one role is one memoization bucket while the kernel classes choose among themselves, and benchmarks take their calls from `manifest_calls`.
…erator namespace

The family `normalization` is now `norm`, so RMSNormFwdOp's operator is `tileops::norm_rms_norm_fwd`, measured on the current TileOPs. A class claims the boundary with `compile_boundary = True`: `forward` calls the generated `_call_boundary`, one operator is generated per effect branch with `_writes_<input>` and `_out` suffixes, the fake allocates from the checked signature with `torch.empty`, and the target is resolved once, inside the operator. The page still showed an OperatorSpec tuple, a hand-written `_infer_output_shapes`, `caller_stated` outputs and a second resolution in `kernel_for`.
…ontract as the spec does

The key's direction suffix is required only once the other direction has an entry, and `params` is the op's `__init__` list less the code-owned execution-policy parameters, written against the reference rather than the current code. A row with several dtype cases is several calls.
@lcy-seso lcy-seso changed the title [Bench] Read the TileOPs manifest YAML at any depth under the manifest package [Docs] Follow the TileOPs manifest migration Sep 27, 2026
The row's dtype was the one most of its present inputs take, so GroupedGemmFwdOp's float16 rows read int32 (three index tensors against two operands) and SSDDecodeFwdOp's read float32. The case id names the dtype the row runs at, so the first dtype-case value in forall order is the row's dtype, and the tensors in another dtype carry their own.
lcy-seso added a commit to tile-ai/TileOPs that referenced this pull request Sep 27, 2026
…-naming rule (#2227)

## Problems

- `src/tileops/manifest/` interleaves 22 YAML files with 10 Python
modules.
- A family file's name did not always follow from its entries' `family`
(`position_encoding.yaml`, `scan.yaml`, `bmm.yaml`, and the `fft` entry
in `sequence_modeling.yaml`), and nothing checked it.
- The five spec-only ops' constructors fail the implemented-entry parity
check, so a status flip would fail on the signature before reaching the
kernel gaps.

## Changes

- Move every YAML file into `src/tileops/manifest/spec/`; import paths
and public names are unchanged.
- Rename `position_encoding.yaml` → `rope.yaml`, `scan.yaml` →
`reduction_scan.yaml`, `bmm.yaml` → `gemm_bmm.yaml`, and move
`FFTC2CFwdOp` into `spec/fft.yaml`.
- `load_manifest()` rejects a family file that is empty, mixes families,
or is not named `<family>.yaml` / `<family>_<shard>.yaml`.
- A pre-commit hook rejects YAML under `src/tileops/manifest/` outside
`spec/` and anything nested in `spec/`.
- CLAUDE.md, `manifest-spec.md`, `docs/design/manifest.md` and
`gpu-smoke.yml` name `spec/`.
- Conform the constructors of the five spec-only ops to
`signature.params` order plus keyword-only `target`, `kernel_map`,
`tune`; `kernel_map` becomes keyword-only in four and Paged's
`out_dtype` moves ahead of the RoPE parameters.
- Needs tile-ai/TileOPs.github.io#53 merged first; the site's links move
to `spec/` after this merges.
- Test node delta: +1 (`tests/test_ops_manifest.py` 7 → 8).
…s them

A target receives every input the call does not write contiguous, and a written input as passed; tensors declared `device: cpu` may sit beside the call device; a composite with no builder of its own runs its composition, so after install an op is in one of three states and a composite can be replaced wholesale. Under torch.compile, only an output the op allocates is always contiguous. The GroupNormFwdOp excerpt carries its second shape rule.
…chmark runs a call

A forall index may also be a Seq[Int] value list that only a generator takes. A benchmark does not subclass ManifestBenchmark: each test builds one around the op and the call's workload and compares the implementations.
…ndices

A row writes dtype_cases only when the entry has relevant DType indices; a dtype parameter is written as a parameter, and a row without dtype cases is one call.
… the test reference

Key order is __init__ order for params, forward order for inputs and return order for outputs. A composition lists sub-op and kernel-role stages. Op tests compare against the workload's ref_program, not the manifest's optional ref_api.
The test of parametric workload resolution skipped in CI because the Renderer job had no TileOPs checkout. The job now sparse-checks src/tileops of tile-ai/TileOPs, which is all tileops.manifest needs beside PyYAML, and pytest reports skips so a silent skip shows in the log. CLAUDE.md no longer hard-codes the test count, which had gone stale; it points at the command that lists the suite.
@lcy-seso
lcy-seso merged commit c07bcac into tile-ai:main Sep 27, 2026
3 checks passed
@lcy-seso
lcy-seso deleted the fix/bench/manifest-recursive branch September 27, 2026 04:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants