[Docs] Follow the TileOPs manifest migration - #53
Merged
Merged
Conversation
…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.
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
force-pushed
the
fix/bench/manifest-recursive
branch
from
September 27, 2026 02:52
40a7124 to
5221a0e
Compare
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.
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problems
src/tileops/manifest/spec/([Refactor][Manifest] Move the manifest YAML into spec/ under one file-naming rule TileOPs#2227);render_bench.shandworkload_shape.load_manifestread one level only, so the Benchmarks pages would lose their shapes.forall,dtype_cases,some); the renderer read onlydtypesand<tensor>_shape, so 1087 workloads of the snapshot at 44727e21e showed no shapes.check_api_pages.pyfailed: TileOPs renamed five ops and exported three the API pages did not list.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.shlists the manifest withgit ls-tree -r, andload_manifestreads**/*.yaml, so both layouts load;types.yamlis read as ADTs, not ops.tileops.manifestand 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.FP8LightningIndexerFwdOpmoves from the Quantization to the Attention benchmark page, where the API reference lists it.docs/api/follows the renamed ops (NSA,DeltaNetAutogradFwdOp,FusedTopKFwdOp) and listsFusedMoeSharedExpertFwdOp,DeltaNetInferenceFwdOp,GLAInferenceFwdOp.src/tileops/manifest/spec/; theshape_rules.pylink is gone with the module.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.kernel_types, generated checks, one role per memoization bucket, kernel classes choosing among themselves,manifest_calls.compile_boundary = True,_call_boundary, one operator per effect branch,tileops::norm_rms_norm_fwd, target resolved inside the operator.weight, params passed as the instance holds them, the whole-op target path, and re-measured error messages.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_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).