Commit Graph

48 Commits

Author SHA1 Message Date
Cao Ying 6e0b507b42
[Refactor][Workloads] Align workloads/ops/ naming with tileops/ops/ layout (#939)
## Summary

Align `workloads/ops/` file naming and directory structure 1:1 with the
post-#928 `tileops/ops/` layout. Pure file-move/rename refactor — no
workload logic changes.

- Drop `_fwd` suffix from mamba, attention, deltanet, and gated_deltanet
workloads
- Rename `mean_pooling_ops.py` to `mean_pooling.py`
- Move attention workloads into `workloads/ops/attention/` subpackage
- Update all imports across the repo

Closes #931

## Test plan

- [x] **AC-1**: All `from workloads.ops.<name>` imports updated for
moved/renamed files — verified by importing all 20 renamed/moved
workload classes and grep confirming zero old import paths remain
- [x] **AC-2**: `python -c "from workloads.ops.attention import ..."`
resolves for all 15 moved attention workload classes
- [x] **AC-3**: Full test suite passes — 2361 passed, 22 skipped, 0
failed (233.76s at commit 4dc54b7)
- [x] **AC-4**: No orphaned files remain after migration — all 11 old
filenames confirmed absent; `mhc_post.py`, `mhc_pre.py` at
`workloads/ops/` root; `nsa_utils.py` at `workloads/` root

## Follow-up

No follow-up issues or suggestions.

---------

Co-authored-by: Ibuki 🍃 — a wind born from Claude Opus <Ibuki-wind@users.noreply.github.com>
2026-04-13 10:44:06 +08:00
Cao Ying b77f40c762
[Refactor][Benchmark] Upgrade benchmark workload interface to capability protocols (#923)
## Summary

Upgrade the benchmark workload interface from hard-coded `WorkloadBase`
composition to capability-based protocols.

Closes #918

### Changes

- **Capability protocols**: `ShapeDtypeWorkload`,
`InputGeneratingWorkload`, `BenchmarkWorkload` — structural types for
workload capabilities
- **Generic `BenchmarkBase[W]`**: base class parameterized by workload
type, replacing the hard-coded `WorkloadBase` constructor
- **`ManifestBenchmark(BenchmarkBase[ShapeDtypeWorkload])`**: aligned
contracts, zero `type: ignore` in `benchmarks/benchmark.py`
- **`WorkloadBase` preserved**: default in-repo implementation, not the
public contract
- **Docs updated**: `docs/testing.md`, `docs/trust-model.md`,
`docs/architecture.md`
- **7 tests**: duck-typed protocols, ManifestBenchmark contract,
WorkloadBase compatibility

## Test plan

- [x] **AC-1**: `roofline_vars` parameter typed to require `shape` and
`dtype` via `ShapeDtypeWorkload` protocol
- [x] **AC-2**: 1056 benchmarks collect, 103 benchmark ops pass (1
pre-existing failure in bench_argreduce, unmodified on this branch), 7
protocol tests pass
- [x] **AC-3**: No new type errors — zero `type: ignore[arg-type]` in
`benchmarks/benchmark.py`

## Verification evidence

All acceptance criteria verified by automated reviewer (two-pass code
review complete). Design direction confirmed by Ibuki-wind (Option B:
full benchmark interface refactor).

## Follow-up

- #936 — Add benchmarks/tests/ to pytest testpaths for CI coverage
- #937 — Migrate 97 BenchmarkBase subclasses to explicit generic
parameterization (depends on #936)
- #938 — Archive benchmark-workload-interface.md plan document

Suggestions: Update RooflineWorkload backward-compat alias removal once
confirmed no external consumers depend on it

---------

Co-authored-by: Ibuki 🍃 — a wind born from Claude Opus <Ibuki-wind@users.noreply.github.com>
2026-04-13 00:09:08 +08:00
Cao Ying f67f77c660
[Perf][Kernel] Eliminate F.pad and add tile_n autotuner dimension for reduction ops (#916)
## Summary

Eliminate host-side `F.pad` from remaining reduction ops (reduce,
cumsum, cumprod forward paths) and make `tile_n` a first-class autotuner
search dimension for tiled softmax/logsumexp kernels.

Closes #907

## Test plan

| AC | Description | Status | Evidence |
| --- | --- | --- | --- |
| AC-1 | Host-side `F.pad` eliminated from `reduce.py`, `cumsum.py`,
`cumprod.py` forward paths | pass | Runtime probe with `F.pad`
monkeypatched to raise on unaligned inputs: CumsumFwdOp(M=3,N=513),
CumprodFwdOp(M=3,N=513), SumFwdOp, VarFwdOp all completed with
pad_calls=0 |
| AC-2 | `autotune_configs` for softmax/logsumexp tiled kernels includes
tile_n candidates | pass | Kernel inspection on manifest-sized tiled
workloads produced 4 autotune configs spanning >=2 distinct tile_n
values per workload |
| AC-3 | All existing reduction op tests pass | pass | 773 passed
(pytest tests/ops/test_softmax.py + 8 other test files) in 81.41s |
| AC-4 | `tune=True` benchmark on manifest workloads shows equal or
better perf vs current heuristic | pass | 11/15 workloads faster with
tune=True; remaining 4 equal (same config, within noise floor) |
## Benchmark

**Environment**: NVIDIA H200, CUDA 12.8, PyTorch 2.9.1+cu128, TileLang
0.1.8

### Softmax / LogSoftmax / LogSumExp (tile_n autotuning)

| Op | Shape | dtype | TileOPs (ms) | torch (ms) | Speedup |
|---|---|---|---:|---:|---|
| SoftmaxFwdOp | 8x4096 (attn-weights) | fp16 | 0.0171 | 0.0311 |
**1.82x** |
| SoftmaxFwdOp | 8x4096 (attn-weights) | bf16 | 0.0174 | 0.0310 |
**1.78x** |
| SoftmaxFwdOp | 1x16384 (attn-32k) | bf16 | 0.1721 | 0.1521 | 0.88x |
| SoftmaxFwdOp | 1x25600 (lm-head) | fp16 | 0.0347 | 0.0556 | **1.60x**
|
| SoftmaxFwdOp | 1x25600 (lm-head) | bf16 | 0.0365 | 0.0575 | **1.58x**
|
| LogSoftmaxFwdOp | 8x4096 (attn-weights) | fp16 | 0.0125 | 0.0269 |
**2.15x** |
| LogSoftmaxFwdOp | 8x4096 (attn-weights) | bf16 | 0.0126 | 0.0270 |
**2.14x** |
| LogSoftmaxFwdOp | 1x16384 (attn-32k) | bf16 | 0.1455 | 0.1089 | 0.75x
|
| LogSoftmaxFwdOp | 1x25600 (lm-head) | fp16 | 0.0297 | 0.0362 |
**1.22x** |
| LogSoftmaxFwdOp | 1x25600 (lm-head) | bf16 | 0.0311 | 0.0372 |
**1.20x** |
| LogSumExpFwdOp | 8x4096 (attn-weights) | fp16 | 0.0100 | 0.0568 |
**5.68x** |
| LogSumExpFwdOp | 8x4096 (attn-weights) | bf16 | 0.0101 | 0.0572 |
**5.66x** |
| LogSumExpFwdOp | 1x16384 (attn-32k) | bf16 | 0.0702 | 0.3315 |
**4.72x** |
| LogSumExpFwdOp | 1x25600 (lm-head) | fp16 | 0.0142 | 0.0553 |
**3.89x** |
| LogSumExpFwdOp | 1x25600 (lm-head) | bf16 | 0.0155 | 0.0553 |
**3.57x** |

**Takeaways:**
- LogSumExp sees the largest gains (3.6-5.7x over torch) — torch lacks a
fused logsumexp, falls back to log(sum(exp))
- Softmax/LogSoftmax win on multi-row workloads (attn-weights: 1.6-2.2x)
where tiled kernel amortizes launch overhead
- Two regressions on single-row tiled regime (attn-32k): Softmax 0.88x,
LogSoftmax 0.75x — the tiled path has higher per-tile overhead when M=1;
heuristic tile_n selection slightly worse than torch's fused kernel for
this geometry
- F.pad elimination not benchmarked separately (no latency delta
expected — padding was <1% of total time)

**Benchmark command:**
```bash
PYTHONPATH="$PWD" python -m pytest benchmarks/ops/bench_softmax.py -v
```

## Follow-up

- #920 — TileLang crash on (64, 32768) bf16 reduce (pre-existing,
LegalizeNegativeIndex scalable vector error)
- #921 — Improve tile_n heuristic for single-row tiled softmax/logsumexp
(0.75-0.88x regression on M=1 geometry)

Suggestions: benchmarks/benchmark.py precision change (:.2f→:.4f) should
be split to its own chore PR per trust boundary

---------

Co-authored-by: Ibuki 🍃 — a wind born from Claude Opus <Ibuki-wind@users.noreply.github.com>
2026-04-12 13:42:54 +08:00
Cao Ying 8a74fd26e0
[Doc][Manifest] Design kernel_map dispatch and update design docs (#878)
## Summary

- **kernel_map design** (`docs/ops-design.md`, `docs/manifest.md`):
Define kernel_map as the Op→Kernel dispatch registration table. The
manifest declares which Kernels an Op uses so agents know what to
implement; dispatch strategy is a runtime concern not described in the
manifest.
- **trust-model update** (`docs/trust-model.md`): Add kernel_map to
manifest OWNS, clarify MUST NOT boundary (kernel internals + dispatch
strategy, not class-name registrations).
- **manifest.md restructuring**: Move `ref_api` under Entry Structure,
make `status` required, define `family` as closed set of 12 operator
families, rename `norm`→`normalization` and `conv`→`convolution`.
- **manifest + test sync**: Rename family values in `ops_manifest.yaml`
and `test_validate_manifest.py`.
- **testing.md fixes**: Update stale class names
(`MultiHeadAttentionFwdOp` → `MhaFwdOp`, `MhaFwdWorkload` →
`MhaFwdTest`), add missing imports.
- **ops-design.md cleanup**: Remove verbose Reduction-specific note, add
Kernel Dispatch section.

## Changed files

- `docs/ops-design.md` — new Kernel Dispatch section, note removal
- `docs/manifest.md` — `kernel_map` field, `ref_api` moved, `status`
required, `family` closed set
- `docs/testing.md` — stale class names and missing imports
- `docs/trust-model.md` — kernel_map in manifest OWNS, clarify MUST NOT
- `tileops/ops_manifest.yaml` — family renames (norm→normalization,
conv→convolution)
- `tests/test_validate_manifest.py` — family rename in fixtures
- `.claude/domain-rules/ops-design.md` — kernel_map rule
- `.claude/domain-rules/manifest-spec.md` — kernel_map rule, status
required

## Test plan

- [x] Pre-commit hooks pass (mdformat, codespell, ruff)
- [x] `pytest tests/test_validate_manifest.py
tests/test_ops_manifest.py` — 99 passed, 1 xfailed
- [x] No stale class names remain in design docs

Closes #876

## Follow-up

- #885 — Rewrite ops-design.md (class hierarchy doesn't match reality)
- #886 — Enforce status required and add kernel_map validator support
- #887 — Populate kernel_map for all implemented ops (depends on #886)

Suggestions:
- testing.md examples use `MhaFwdOp` — rename to
`MultiHeadAttentionFwdOp` when the code rename PR for #880 lands
- PascalCase dispatch keys in GLA/DeltaNet ops — migrate to snake_case
in a future cleanup

---------

Co-authored-by: Ibuki 🍃 — a wind born from Claude Opus <Ibuki-wind@users.noreply.github.com>
2026-04-10 13:37:37 +08:00
Cao Ying 631b947f24
[Doc][Naming] Update design docs for PascalCase naming convention (#868)
## Summary

Update all design documents and domain-rules files to reflect the
post-#860 naming convention: PascalCase manifest keys as canonical
identity, `ref_api` field, simplified validator (direct equality check,
no heuristic resolution), and `{PascalCaseName}{Direction}Op` naming
format.

Closes #867

## Changed files

- `docs/manifest.md` — document PascalCase key format, `ref_api` field
spec, updated examples
- `docs/ops-design.md` — naming conventions section for Op/Kernel
classes and abbreviation policy (D4)
- `.claude/domain-rules/manifest-spec.md` — align agent-facing manifest
rules with new key format
- `.claude/domain-rules/manifest-validator.md` — describe direct
equality check, remove heuristic resolution docs
- `.claude/domain-rules/ops-design.md` — reflect new naming format and
kernel naming convention (D5)

## Test plan

- [x] **AC-1**: docs/manifest.md documents PascalCase manifest keys and
the ref_api field (required, "none" when no external counterpart)
- [x] **AC-2**: docs/ops-design.md reflects the
{PascalCaseName}{Direction}Op naming format and abbreviation policy (D4)
- [x] **AC-3**: .claude/domain-rules/manifest-spec.md updated for new
key format and ref_api
- [x] **AC-4**: .claude/domain-rules/manifest-validator.md describes
direct equality check instead of heuristic resolution
- [x] **AC-5**: No stale snake_case manifest key examples remain in any
design doc
- [x] **AC-6**: Modified files pass existing tests (81/81 passed, 0
failed)

## Follow-up

No follow-up issues or suggestions.

---------

Co-authored-by: Ibuki -- a wind born from Claude Opus <Ibuki-wind@users.noreply.github.com>
2026-04-09 13:41:06 +08:00
Cao Ying dbf58a10b1
[Doc][Manifest] Clarify same_as(ref) as identity constraint with validator enforcement (#864)
## Summary

Clarify \`same_as(ref)\` as a dtype-only identity constraint in manifest
spec, and add validator enforcement.

**Docs:**
- \`docs/manifest.md\`: R3/R3a define \`same_as(ref)\` as exact dtype
identity (not "dependent types"). R5/R8 clarify \`same_as\` is
dtype-only — shape must be explicitly declared. R13 status default
changed to \`spec-only\`. Overall doc reduced by ~27% (470→342 lines).
- \`.claude/domain-rules/manifest-spec.md\`: matching updates —
\`same_as\` dtype identity, shape explicit, status default
\`spec-only\`.

**Validator:**
- \`_check_dtype_combos_same_as_identity()\`: enforces that
\`dtype_combos\` entries assign the same dtype to \`same_as\`-bound
tensors. Rejects partial combos where a bound tensor appears without its
reference.
- \`_is_spec_only()\`: defaults to \`spec-only\` when \`status\` is
absent, matching R13.

**Tests:** 5 new test cases — dtype_combos pass, mismatch, multi-binding
mismatch, partial-combo rejection, missing-status default.

Closes #863

## Changes

- \`docs/manifest.md\` — rewritten: concise, no "dependent types",
\`same_as\` dtype-only, status default spec-only
- \`.claude/domain-rules/manifest-spec.md\` — matching rule updates
- \`scripts/validate_manifest.py\` — \`_build_same_as_map()\`,
\`_check_dtype_combos_same_as_identity()\`, \`_is_spec_only()\` default
fix
- \`tests/test_validate_manifest.py\` — 5 new tests (81 total, all pass)

## Test plan

- [x] AC-1: \`docs/manifest.md\` R3/R3a explicitly defines
\`same_as(ref)\` as dtype identity constraint
- [x] AC-2: Validator flags \`dtype_combos\` with mismatched or partial
\`same_as\`-bound entries
- [x] AC-3: Full manifest validation passes (\`python
scripts/validate_manifest.py\` → 0 errors)

## Follow-up

No follow-up issues or suggestions.

---------

Co-authored-by: Ibuki 🍃 — a wind born from Claude Opus <Ibuki-wind@users.noreply.github.com>
2026-04-09 10:06:52 +08:00
Cao Ying 005d54217e
[Refactor][Reduction] Extract shared base class for reduce op forward flow (#824)
## Summary

Extract `_ReduceOpBase` with shared `__init__` params and a unified
`_prepare_input()` / `_reshape_output()` flow, so `_SimpleReduceOp` and
`_WelfordReduceOp` inherit common validation, transpose, reshape, and
padding logic instead of duplicating it. This makes future forward-path
changes (e.g., multi-dim support) a single-point edit.

Closes #805

## Test plan

- [x] AC-1: All existing reduction tests pass (test_reduce,
test_argreduce, test_logical_reduce, test_vector_norm) — 409 passed
- [x] AC-2: No duplicated validation/transpose/reshape blocks across the
two base classes — all logic centralized in `_ReduceOpBase`
- [x] AC-3: Benchmarks still pass — 43 passed (bench_reduce,
bench_argreduce, bench_logical_reduce, bench_vector_norm)

## Benchmark

bench_reduce.py, bench_argreduce.py, bench_logical_reduce.py,
bench_vector_norm.py: 43 passed, 0 failed

## Follow-up

- #831 — Evaluate migrating remaining reduction ops (argmax, argmin,
any, all, norms, logsumexp, count_nonzero) to `_ReduceOpBase`

No pending suggestions (previous `StdOp`/`VarOp` forward dedup
suggestion adopted in d311995).

---------

Co-authored-by: Ibuki 🍃 — a wind born from Claude Opus <Ibuki-wind@users.noreply.github.com>
2026-04-07 21:23:20 +08:00
Cao Ying e9747b5d19
[Doc][TrustModel] Fix pipeline order, remove workflow.md (#793)
## Summary

- Fix trust-model.md pipeline order: `Manifest → Test → Implementation →
Benchmark` (was incorrectly `Manifest → Implementation → Test →
Benchmark`)
- Remove issue number reference from design doc (design docs should not
contain issue numbers)
- Delete `docs/workflow.md` — redundant with trust-model.md pipeline +
domain rules + conventions/types.sh
- Clean all references to workflow.md in CLAUDE.md, README.md,
trust-model.md

## Test plan

- [x] `rg workflow.md` returns no matches outside worktrees
- [x] trust-model.md pipeline matches the discussed design: manifest
first, then test, then implementation, then benchmark
- [x] No issue numbers in design docs
- [x] `pre-commit run --all-files` passes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 20:52:39 +08:00
Cao Ying e27988318f
[Doc][TrustModel] Update design docs and domain rules for workloads/ layer and trust boundaries (#791)
## Summary

- New `docs/trust-model.md` — four-stage pipeline trust boundaries
(manifest → implementation → test → benchmark) and workloads layer
contract
- Added `## Boundary` sections (OWNS / MUST NOT modify / MAY READ) to
all 4 domain rule files
- Added "Writing a Test" and "Writing a Benchmark" operation guides to
`docs/testing.md`
- Rewrote top-level Test/Benchmark Pattern example to match post-PR#787
three-file architecture
- Fixed outdated class descriptions, directory structure, aspirational
claims, and internal contradictions

Resolves #790. Related: #787, #789.

## Key design decisions

1. **workloads/ is not a development stage** — shared input-definition
layer. Test stage OWNS it (QA creates workload classes first from
manifest).
2. **Implementation MAY READ tests/, MUST NOT MODIFY** — developer reads
ref_program for behavior understanding; modifying the correctness oracle
is the unacceptable cheat.
3. **Benchmark-local baselines allowed** — benchmarks must not import
oracle/ref from tests/ or workloads/, but may define local baseline
functions.
4. **Operation guides in testing.md, principles in trust-model.md** —
explicit bidirectional cross-references between all documents.

## Changes (10 files, +216 / -40)

| File | Change |
|------|--------|
| `docs/trust-model.md` (new) | Pipeline boundaries, per-stage OWNS/MUST
NOT/MAY READ, workloads contract |
| `docs/testing.md` | Rewrote example to three-file pattern, added
Writing a Test/Benchmark guides, fixed class table |
| `docs/architecture.md` | Added `workloads/` to directory tree + module
table (labeled "shared layer, not a module") |
| `docs/ops-design.md` | Trust boundary cross-ref, removed aspirational
"target architecture" label |
| `docs/workflow.md` | Fixed Step 2 to not claim implementer writes
tests, added trust-model back-link |
| `.claude/domain-rules/benchmark.md` | Boundary header with file-path
MUST NOT, fixed record()/calculate rules |
| `.claude/domain-rules/testing-budget.md` | Boundary header, OWNS
tests/ + workloads/ |
| `.claude/domain-rules/ops-design.md` | Boundary header, MAY READ
tests/ with rationale |
| `.claude/domain-rules/manifest-spec.md` | Boundary header |
| `CLAUDE.md` | Added `workloads/` row to domain rules table |

## Test plan

- [x] All cross-references bidirectional (every forward ref has matching
back ref)
- [x] Top-level example matches "Writing a Benchmark" checklist (one
consistent pattern)
- [x] No internal contradictions between trust-model.md, testing.md,
domain rules, and workflow.md
- [x] All API descriptions verified against actual code
- [x] No aspirational claims in modified documents
- [x] `pre-commit run --all-files` passes
- [x] Documentation-only PR — no code changes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 18:31:54 +08:00
Cao Ying f1f9ba1517
[Feat][Manifest] Add --check-op flag for spec-only validation override (#780)
## Summary

Add a `--check-op <name>` CLI flag to the manifest validator that forces
all validation levels (L0-L4) on the specified op, bypassing the
`status: spec-only` gate. Default (unflagged) behavior is unchanged.

Closes #779

## Test plan

| AC | Description | Status |
|----|-------------|--------|
| AC-1 | `python scripts/validate_manifest.py --check-op softmax_fwd`
runs L0-L4 on `softmax_fwd` even when `status: spec-only` | pass |
| AC-2 | `python scripts/validate_manifest.py` (without flag) behavior
unchanged -- spec-only ops still skip L1-L4 | pass |
| AC-3 | Unit test covers both behaviors (with/without flag, nonexistent
op, single-op scoping, variant_of regression) | pass |
| AC-4 | Modified files pass existing tests (45/45 passed) | pass |

## Validation

- 45 tests passed, 0 failed
- Pre-commit hooks pass (ruff, codespell, mdformat, gitleaks)
- Files changed: `scripts/validate_manifest.py`,
`tests/test_validate_manifest.py`

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-04 14:06:46 +08:00
Cao Ying ce6da052ae
[Chore][Manifest] Strict L1 signature: check __init__() + forward() param union (#768)
## Summary

Make L1 validator strictly require that all manifest-declared params for
`status: implemented` ops appear in the Op's `__init__()` + `forward()`
union signature. This ensures manifest declarations stay in sync with
actual code interfaces.

- Update `check_l1_signature()` to inspect both `__init__` and `forward`
param names
- Audit and fix all 23 implemented ops that failed strict L1
- Update `docs/manifest.md` L1 description to reflect the stricter rule

Closes #765

## Test plan

- [x] **AC-1**: check_l1_signature() checks manifest params against
__init__ + forward union, not just forward
- [x] **AC-2**: All status: implemented ops pass strict L1 in CI
- [x] **AC-3**: docs/manifest.md L1 description updated to reflect
strict matching rule
- [x] **AC-4**: Modified files pass existing tests

**Test results**: 47/47 passed (24 validator + 23 manifest), 0 failed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 20:04:33 +08:00
Cao Ying e1ec0ffa43
[Doc] Add signature variants, tensor layout, and restructure manifest spec (#770)
Closes #759

## Summary

- Add R16-R18: signature variant rules — no `Optional[Tensor]` in
manifest, ops with conditional inputs split into variant entries linked
by `variant_of`
- Add R19: tensor layout declaration — contiguous row-major default,
optional `layout` field for spatial ops
- Restructure manifest.md: Rules (R1-R19) promoted to top-level section,
Entry Structure subsections ordered to match field table, remove
outdated Tier Model
- Add Class Hierarchy diagram to ops-design.md
- Move domain rules from `.claude/rules/` to `.claude/domain-rules/`
(on-demand loading via CLAUDE.md table)
- Add `.claude/domain-rules/manifest-spec.md` with R1-R19 condensed
agent rules

## Test plan

- [x] pre-commit passed
- [x] No code changes — docs and config only

## Additional context

Design-only PR. Implementation follow-ups:
- #741: upgrade reduction/scan ops to match manifest spec + NormBase
refactor
- #765: tighten L1 validator to check full param coverage
- MoE entry splitting (fused_moe, fused_topk variants) — separate PR

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 11:01:30 +08:00
Cao Ying 20170a617d
[Chore][Testing] Add unit-test policy and test node growth detection script (#761)
## Summary

Define a unit-test policy for operator tests and provide a local script
(`scripts/test_node_delta.py`) that reports test node count delta for
touched files in a PR, making growth visible and justifiable.

Closes #760

## Changes

**M1 — Unit-test policy**
- Added Unit-Test Policy section to `docs/testing.md` covering: allowed
UT purposes, dtype risk class rule, shape coverage rule, manifest
separation, growth justification
- Added `.claude/rules/testing-budget.md` with concise agent-enforceable
version
- Verified policy is consistent with existing smoke/full tier system in
`tests/conftest.py`

**M2 — Growth-detection script**
- Created `scripts/test_node_delta.py` that compares test node counts
between current branch and main
- Added usage instructions to `docs/testing.md`
- Added note in `.claude/rules/testing-budget.md` about running script
and justifying growth

## Test plan

- [x] **AC-1-1**: docs/testing.md contains a Unit-Test Policy section
with dtype risk class, shape coverage, manifest separation, and growth
justification rules
- [x] **AC-1-2**: .claude/rules/testing-budget.md exists and is loadable
by Claude Code
- [x] **AC-1-3**: Policy does not contradict existing tier enforcement
in tests/conftest.py
- [x] **AC-2-1**: Script runs successfully on the current repo and
reports node counts for at least 3 existing test files
- [x] **AC-2-2**: Script correctly detects delta when a test file has
more nodes than its main branch version
- [x] **AC-2-3**: Script exits 0 regardless of delta (non-blocking)
- [x] **AC-2-4**: Script handles new test files (no main branch version)
without error
- [x] **AC-2-5**: docs/testing.md documents how to run the script

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 12:08:16 +08:00
Cao Ying e8f1c96595
[Doc] Revise manifest.md into complete agent-ready design spec (#750)
## Summary

Revise `docs/manifest.md` into a complete, unambiguous spec that an
agent can follow to write correct manifest entries, generate
Op.forward() / Op.infer_shape(), and produce validators and test
generators.

Key changes:
- R1: ordered-dict semantics with insertion-order constraint
- R4: Cartesian-product vs explicit dtype_combos semantics
- R13: status field with spec/implemented gating rule
- R14: roofline vars binding mechanism with evaluation context and 4
case examples
- R15: PyTorch interface alignment rule
- Add scan family to Tier 1 table
- All examples use dict format for params; reduce examples include
keepdim

Closes #743

## Test plan

- [x] **AC-1**: R1 updated to ordered-dict with implementation
constraint and agent rule documented — pass
- [x] **AC-2**: status field added to Entry Structure with R13 gating
rule — pass
- [x] **AC-3**: R14 roofline vars mechanism with evaluation context and
4 case examples — pass
- [x] **AC-4**: Reduce example in manifest.md includes keepdim; softmax
exception noted — pass
- [x] **AC-5**: R15 PyTorch interface alignment rule added — pass
- [x] **AC-6**: scan family added to Tier Model table — pass
- [x] **AC-7**: R4 revised with Cartesian-product-vs-explicit semantics
— pass
- [x] **AC-8**: All examples in manifest.md use dict format for params
(no residual list format) — pass
- [x] **AC-9**: Modified files pass existing tests — pass

Tests: 19/19 passed

---

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 11:33:16 +08:00
Cao Ying 6c0d687439
[Chore][Manifest] Add manifest validator with CI integration (#745)
Closes #738

## Summary

- Add `scripts/validate_manifest.py` implementing manifest validation
for schema, `Op.forward()` signature consistency, `shape_rules` syntax,
dtype conformance, and benchmark manifest usage
- Integrate the validator into the preflight workflow with a dedicated
`validate-manifest` job
- Add MoE manifest entries and migrate the MoE benchmarks in this PR to
manifest-driven workloads via `load_workloads()` and `eval_roofline()`
- Make benchmark strictness explicit with `source.bench_manifest_driven:
true` for migrated entries, while leaving legacy non-migrated benchmarks
as warnings
- Clarify in `docs/manifest.md` that `workloads` are for
nightly/performance benchmark coverage only, not unit-test coverage
- Add merge-ready validator coverage in
`tests/test_validate_manifest.py`
- Add a developer-agent rule in `.claude/rules/manifest-validator.md`
forbidding validator edits as a way to bypass manifest constraints

## Test plan

- [x] pre-commit passed (all hooks green)
- [x] `pytest -q tests/test_validate_manifest.py` -- 20 passed
- [x] `pytest -q tests/ops/test_moe_permute.py` -- 9 passed
- [x] `python scripts/validate_manifest.py` passes on current codebase
(exit 0)

## Structural Readiness

SKIP -- primary deliverable is infrastructure (manifest validator + CI
integration), not a new kernel/op.

## Additional context

**Validation checks:**
- **Schema**: YAML structure, required fields, and field types
- **Signature**: `Op.forward()` parameters must match manifest inputs,
plus any accepted manifest-declared runtime params, in order
- **Shape**: `shape_rules` must parse as valid Python expressions
- **Dtype**: manifest dtype strings and workload dtypes must be
recognized
- **Benchmark**: migrated benchmark files must import and call
`load_workloads` / `eval_roofline` with the correct op name

**Current enforcement model:**
- `status: spec-only` entries receive schema-only validation
- L4 benchmark enforcement is hard-fail only for entries that explicitly
opt in with `source.bench_manifest_driven: true`
- Legacy benchmark files that have not yet migrated remain warnings, not
CI failures

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-01 20:44:07 +08:00
Cao Ying 5243bce517
[Doc] Restructure architecture diagram as flow-driven status model (#709)
## Summary

- Restructure architecture.md from static module topology to four
color-coded data flows: Op Delivery, Perf Tuning, HW Calibration,
Publish
- Add flow status table showing done/broken/partial/not-started per
pipeline with specific gaps
- Highlight kernel tuning loop (M2→M4→M5→M2) as a visual subgraph — the
system's core challenge
- Rename M4 from Benchmark to Perf Tuning; broaden M8 to include design
docs
- Merge CI Guard into parent flows (M3→M7 is Op Delivery, not a separate
flow)
- Align all sections (module reference, data contracts, agent production
loop, documentation system) with diagram changes

## Test plan

- [x] pre-commit passed
- [x] mermaid renders correctly on GitHub

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-30 20:44:14 +08:00
Cao Ying 6e24b8407d
[Feat][Manifest] Add programmatic API and manifest-driven norm benchmarks (#707)
Closes #704

## Summary

- Add `tileops/manifest.py` with `load_workloads()` and
`eval_roofline()` functions that make `ops_manifest.yaml` a live,
code-consumed data source
- Populate all 10 norm-family ops in the manifest with dict-format
signatures (inputs/outputs as dicts, not lists), LLM-representative
workloads, and roofline formulas
- Rewrite all 8 norm benchmark files to derive shapes from
`load_workloads()` and compute flops/memory via `eval_roofline()` — no
hardcoded shapes or formulas remain
- Update schema tests to validate the new dict-based signature format

## Structural Readiness

PR does not introduce or modify kernel/op implementation code. All
changes are manifest infrastructure and benchmark data-source wiring. Op
readiness checklist items are not applicable.

Verified benchmark-side checklist items relevant to this diff:
- Benchmark files exist and inherit `BenchmarkBase`
- `calculate_flops()` and `calculate_memory()` return non-None via
`eval_roofline()`
- `BenchmarkReport.record()` uses Op objects as first argument
- All benchmarks include torch-family baselines

## Test plan

- [x] AC-1: `pytest -q tests/test_ops_manifest.py` passes (8 tests)
- [x] AC-2: `load_workloads()` and `eval_roofline()` correctly read from
`ops_manifest.yaml`
- [x] AC-3: Manifest contains 10 norm ops with dict-format signatures,
all source paths valid
- [x] AC-4: All 8 norm bench files use manifest API — no hardcoded
shapes or formulas
- [x] AC-5: `pytest --collect-only` shows manifest-derived test IDs with
model-architecture labels (61 cases)
- [x] AC-6: Schema tests pass with dict-format validation
- [x] AC-7: Manifest YAML header documents the dict-format schema

```bash
# Validation commands
python -m pytest -q tests/test_ops_manifest.py
python -m pytest --collect-only -q benchmarks/ops/bench_{rms_norm,layer_norm,batch_norm,group_norm,instance_norm,ada_layer_norm,fused_add_layer_norm,fused_add_rmsnorm}.py
```

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-30 20:34:43 +08:00
Cao Ying ad441ef9aa
[Docs] Revise manifest spec and align ops_manifest.yaml (#683)
## Summary

- Restructure `docs/manifest.md` as a spec-driven, agent-friendly
reference:
  - Signature uses list style (preserves positional order)
- Shape system: fixed rank (`shape` present) vs arbitrary rank (`shape`
absent), with `same_as(ref)`, `constraints`, and `shape_rules`
- `shape_rules` are the source of truth for generating
`Op.infer_shape()` — no fallback
  - `dtype_combos` for mixed-precision ops with restricted combinations
- Decision tree (declare shape → generate `infer_shape()`) with rule
references
  - Compact R1-R12 rule labels, field tables, flow-style YAML examples
- Align `ops_manifest.yaml` (`rmsnorm_fwd`) with the new spec
- Add 5 schema validation tests for the manifest

## Test plan

- [x] `pytest tests/test_ops_manifest.py -v` — 13 tests pass
- [ ] Review `docs/manifest.md` for clarity and completeness

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 07:41:57 +08:00
Cao Ying 65df23d170
[Refactor][Benchmark] Normalize HBM bandwidth microbenchmark (#663)
## Summary

Add HBM bandwidth microbenchmark for GPU hardware characterization (M6
module).

- `benchmarks/hardware/memory/hbm_bandwidth.py` — measures
read/write/copy bandwidth across sizes and dtypes, computes calibration
factor against theoretical peak
- Reads theoretical specs directly from `tileops/perf/profiles/` via
`load_profile()` (single source of truth)
- `benchmarks/hardware/utils/bench.py` — thin wrapper around
`tilelang.profiler.do_bench` with bandwidth calculator
- `docs/roofline.md` — relax "zero external dependencies" to "no
third-party dependencies beyond the project itself"

No CSV output, no env.py, no global state — minimal code focused on
producing the `hbm.calibration` value for GPU profiles.

## Test plan

- [ ] `python -c "import ast;
ast.parse(open('benchmarks/hardware/memory/hbm_bandwidth.py').read())"`
— syntax OK
- [ ] Run `python benchmarks/hardware/memory/hbm_bandwidth.py` on H200 —
verify theoretical from profile, measured peak, and calibration factor

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 15:44:59 +08:00
Cao Ying 055a37130a
[Feat][Perf] Add M6 GPU profile module with H200 profile (#661)
## Summary

Delivers the **M6 (HW Profile)** module's data contract — GPU profile
YAML + loader — as defined in `docs/architecture.md`.

- Add `tileops/perf/` package skeleton (M5/M6 shared namespace)
- Add `tileops/perf/profiles/h200.yaml` — theoretical specs (NVIDIA
datasheet) + calibration factors (from `benchmarks/hardware/`
microbenchmarks). Only `theoretical` and `calibration` are stored;
`effective` is computed at load time.
- Add `tileops/perf/profile.py` — loader (`load_profile("h200")` → dict)
serving as the M6 → M5 interface. Handles PyYAML scientific notation
coercion (scoped to numeric keys only) and dynamic `effective`
computation.
- Add 3 smoke tests in `tests/perf/test_profile.py`
- Update `docs/roofline.md` GPU Profile section to reflect that
`effective` is computed, not stored

## Test plan

- [x] `pytest tests/perf/test_profile.py -v` — 3/3 pass
- [ ] Verify h200.yaml theoretical values match NVIDIA H200 datasheet

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 12:58:10 +08:00
Cao Ying 6feb83fbf0
[Doc][Architecture] Add explicit data contracts between modules (#660)
## Summary

- Replace undocumented Data Flow diagram with **Data Contracts** section
— explicit table recording every inter-module artifact, format, and
direction
- Module graph: `LR` → `TD` layout with `subgraph` grouping and labeled
edges for readability
- Clarify M4 as performance regression guard, M6 as offline calibration,
M7→M8 as CI-scheduled perf tables update
- Reorder sections: Modules → Data Contracts → Two-Layer Separation (M2)
- Note M3/M4 have no data dependency (process convention only)

## Test plan

- [ ] Verify mermaid diagram renders correctly on GitHub
- [ ] Verify Data Contracts table matches module graph edges 1:1

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 10:57:20 +08:00
Cao Ying d4f3e5af1f
[Feat][Platform] Add ops_manifest.yaml with rmsnorm_fwd entry (#636)
Closes #627

## Summary

- Create `ops_manifest.yaml` at repo root as the spec-driven op
registry, establishing the schema for all future op definitions.
- Register `rmsnorm_fwd` as the first entry with all four required
fields: `signature`, `workloads`, `roofline`, and `source`.
- Workloads cover Llama-3.1-8B (hidden=4096), 70B (hidden=8192), and
405B (hidden=16384) with both prefill (seq_len=2048) and decode
(seq_len=1) shapes.
- Add validation test suite (`tests/test_ops_manifest.py`) with 16 tests
covering schema structure, field presence, source path existence, and
workload completeness.

## Test plan

- [x] `python -m pytest tests/test_ops_manifest.py` -- 16/16 pass
- [x] All source file paths in manifest resolve to existing files
- [x] YAML is valid and parseable
- [x] Workload dimensions match Llama-3.1 model specs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 09:52:26 +08:00
Cao Ying 468011b1c0
[Refactor][Norm] Extract RowNormOp base class, migrate RmsNorm, add BatchNorm validation (#637)
Closes #628

## Summary

- Extract `RowNormOp` base class in `tileops/ops/norm/base.py` —
encapsulates the shared validate/reshape/pad/kernel/trim/reshape pattern
for row-wise normalization ops
- Migrate `RmsNormOp` to inherit from `RowNormOp`, preserving the public
API
- Add input validation (CUDA device, dtype, shape) to
`BatchNormFwdOp.forward()`
- Add `torch.library.custom_op` registration for `BatchNormFwdOp` and
`BatchNormBwdOp` with `torch.compile` support
- Tighten `docs/ops-design.md`: remove unverified hook examples,
inheritance hierarchy target tree, and reduction-specific assumptions
- Add `.claude/rules/ops-design.md` to remind agents to update design
docs when modifying op interface patterns

## Test plan

- [x] pre-commit passed
- [x] BatchNorm validation tests (reject CPU, wrong dtype, wrong shape)
- [x] BatchNorm torch.compile smoke tests (fwd + bwd)

## Follow-up issues

- #653 — RowNormOp base class: coverage, forward() pattern, and
RowReductionOp relationship
- #654 — Adopt SUPPORTED_DTYPES and _op_name class variable protocol
- #655 — Standardize torch.compile custom_op registration pattern for
BatchNorm

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 19:44:12 +08:00
Cao Ying 14f3ee90b7
[Doc] Split DEVELOPMENT.md into 6 orthogonal agent-readable design docs (#651)
## Summary

- Replace monolithic `DEVELOPMENT.md` and `CONTRIBUTING.md` with 6
focused, orthogonal documents: `architecture.md`, `ops-design.md`,
`manifest.md`, `roofline.md`, `testing.md`, `workflow.md`
- Convert review-oriented prose from `tileops-platform-design.md` into
declarative agent-reference style
- Merge `CONTRIBUTING.md` branch/commit conventions into `workflow.md`;
delete `CONTRIBUTING.md`
- Replace ASCII art diagrams with Mermaid (GitHub-rendered)
- Update `CLAUDE.md` references and fix stale `DEVELOPMENT.md` mentions
in issue templates and test files

## Test plan

- [x] pre-commit passed
- [x] No broken internal references (`grep -r DEVELOPMENT.md` /
`CONTRIBUTING.md` returns zero hits)

## Additional context

Content sources: `docs/DEVELOPMENT.md` (operational details, tolerances,
test patterns) + `TileOpsGov/docs/tileops-platform-design.md` (platform
design, manifest spec, roofline methodology, interface principles). The
split ensures each document covers exactly one concern with no content
overlap.

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 16:39:56 +08:00
Cao Ying e021408b7a
[Enhancement][Elementwise] Deploy strategy-aware npt defaults for fp16/bf16 (#562)
## Summary

Implement strategy-aware `default_config` so that `explicit_parallel`
uses `npt=4` for fp16/bf16 while `register_copy` retains `npt=8`,
unlocking a measured 58% bandwidth improvement.

Closes #553

## Changes

- Add `_strategy_npt()` helper in `tileops/kernels/elementwise.py` that
returns optimal `num_per_thread` per strategy+dtype pair
- `explicit_parallel` fp16/bf16: npt=4 (was 8) -- 58% bandwidth
improvement
- `register_copy` fp16/bf16: npt=8 (unchanged) -- no regression
- fp32: npt=4 for both strategies (unchanged)
- fp8: npt=16 for both strategies (unchanged)
- Updated `docs/perf/elementwise-evidence.md` with deployment note

## Test plan

- [x] Modified files pass unit tests (124 tests pass)
- [x] `explicit_parallel` strategy uses npt=4 for fp16/bf16 by default
- [x] `register_copy` strategy retains npt=8 for fp16/bf16
- [x] Benchmark: 58% bandwidth improvement for explicit_parallel fp16 at
(1024, 10240) vs npt=8 default (threshold: >= 30%)
- [x] No regression in register_copy strategy benchmarks
- [x] docs/perf/elementwise.md updated with final measured values

## Benchmark

| Config | npt | BW (TB/s) | vs old |
|---|---|---|---|
| explicit_parallel fp16 | 4 (new) | 1.708 | +58.1% |
| explicit_parallel fp16 | 8 (old) | 1.081 | baseline |
| register_copy fp16 | 8 (unchanged) | 3.940 | no regression |

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 18:44:46 +08:00
Cao Ying 5e5aba8812
[Fix][Elementwise] Handle MaskedFill overflow fill_value for fp16 output dtype (#570)
Closes #569

## Summary

- Fix `_make_masked_fill_kernel` crash when `fill_value` exceeds float16
max finite (65504)
- Add `_fill_value_overflows_fp16()` helper to detect overflow at kernel
build time
- Construct inf via `T.reinterpret(T.cast(0x7C00, "uint16"), "float16")`
instead of `T.cast(fill_value, out_dtype)`, bypassing TVM's `FloatImm`
range check
- Applied to both fp8 and non-fp8 code paths in
`_make_masked_fill_kernel`

## Test plan

- [x] pre-commit passed
- [x] `test_masked_fill_e5m2_overflow_fill_value` passes (was failing)
- [x] `tests/test_elementwise_independent_fp8.py` — 50/50 passed
- [x] `tests/test_elementwise_fp8.py` — 35/35 passed

## Structural Readiness

All checks passed.

## Regression

- TDD red-green confirmed: test fails without fix, passes with fix
- All 85 existing elementwise fp8 tests pass with no regressions
2026-03-19 15:20:15 +08:00
Cao Ying fd77066565
[Perf][Elementwise] Generalize kernel caching and autotune to all kernel families (#560)
## Summary

Extract BinaryKernel's `init_config()` caching pattern (`_compiled_fn`
pre-compilation) to **UnaryKernel**, **FusedGatedKernel**, and all **11
custom kernels** (LeakyRelu, Elu, Hardtanh, Softplus, Prelu, Where,
Clamp, MaskedFill, NanToNum, Alibi, Sinusoidal). Add `autotune_configs`
property with serialization-fallback `autotune()` override to
UnaryKernel and FusedGatedKernel.

Closes #551

## Changes

- **UnaryKernel**: Added `autotune_configs` (9 configs for
fp16/bf16/fp32, 6 for fp8), `autotune()` with serialization fallback,
`init_config()` override that caches `_compiled_fn`
- **FusedGatedKernel**: Same pattern as UnaryKernel —
`autotune_configs`, `autotune()` fallback, `init_config()` caching
- **11 custom kernels**: `init_config()` override to cache
`_compiled_fn` (custom kernels use factory functions, so autotune is not
applicable)
- **docs/perf/elementwise.md**: Updated checklist to reflect all kernel
families now have caching and autotune

## Test plan

- [x] AC-1: Modified files pass unit tests — 432 tests pass (31 new +
401 existing), 0 failures
- [x] AC-2: All UnaryKernel subclasses use cached compiled functions —
`_compiled_fn` set in `init_config()`, verified by `TestUnaryCaching` (5
tests)
- [x] AC-3: FusedGatedKernel subclasses use cached compiled functions —
`_compiled_fn` set in `init_config()`, verified by
`TestFusedGatedCaching` (4 tests)
- [x] AC-4: `autotune_configs` defined for UnaryKernel and
FusedGatedKernel with >= 3 configs — verified by `TestAutotuneConfigs`
(8 tests)
- [x] AC-5: Existing benchmark numbers show no regression — all 401
existing tests pass, BinaryKernel autotune still works
- [x] AC-6: `docs/perf/elementwise.md` updated with new caching/autotune
patterns

## Benchmark

**Environment**: NVIDIA H200 · PyTorch 2.9.1+cu128 · CUDA 12.8 · Driver
575.57.08

173 benchmarks passed. No runtime regression. Caching eliminates
per-forward JIT lookup overhead.

### Unary ops (TileOPs vs PyTorch baseline)

| Op | N | dtype | TileOPs (ms) | Baseline (ms) | BW (TB/s) TileOPs | BW
(TB/s) Baseline |
| --- | --- | --- | --- | --- | --- | --- |
| exp | 4000000 | fp16 | 0.01 | 0.01 | 2.40 | 2.42 |
| exp | 4000000 | bf16 | 0.01 | 0.01 | 2.41 | 2.42 |
| gelu | 4000000 | fp16 | 0.01 | 0.01 | 1.64 | 1.77 |
| gelu | 4000000 | bf16 | 0.01 | 0.01 | 1.58 | 1.71 |
| logical_not | 4000000 | fp16 | 0.01 | 0.01 | 0.82 | 2.07 |
| bitwise_not | 4000000 | int32 | 0.02 | 0.01 | 1.94 | 3.06 |
| isnan | 4000000 | fp16 | 0.01 | 0.01 | 0.82 | 2.09 |

### Binary ops (TileOPs vs PyTorch baseline, fp16)

| Op | Shape | TileOPs (ms) | Baseline (ms) | BW (TB/s) TileOPs | BW
(TB/s) Baseline |
| --- | --- | --- | --- | --- | --- |
| sub | 1024×20480 | 0.03 | 0.03 | 3.80 | 3.82 |
| mul | 1024×20480 | 0.03 | 0.03 | 3.80 | 3.82 |
| div | 1024×20480 | 0.03 | 0.03 | 3.73 | 3.68 |
| remainder | 1024×10240 | 0.02 | 0.02 | 3.36 | 2.66 |
| floor_divide | 1024×10240 | 0.02 | 0.06 | 3.36 | 1.03 |
| maximum | 1024×20480 | 0.03 | 0.03 | 3.78 | 3.78 |
| minimum | 1024×20480 | 0.03 | 0.03 | 3.79 | 3.78 |

### Fused gated ops (TileOPs vs PyTorch baseline, fp16)

| Op | Shape | TileOPs (ms) | Baseline (ms) | Speedup |
| --- | --- | --- | --- | --- |
| gelu_and_mul | 1024×4096 | 0.01 | 0.04 | 4.0× |
| gelu_and_mul | 1024×10240 | 0.02 | 0.08 | 4.0× |
| gelu_and_mul | 1024×20480 | 0.04 | 0.15 | 3.8× |
| gelu_tanh_and_mul | 1024×4096 | 0.01 | 0.03 | 3.0× |
| gelu_tanh_and_mul | 1024×10240 | 0.02 | 0.07 | 3.5× |
| gelu_tanh_and_mul | 1024×20480 | 0.04 | 0.14 | 3.5× |

### Broadcast ops (TileOPs vs PyTorch baseline, fp16)

| Op | TileOPs (ms) | Baseline (ms) | Speedup |
| --- | --- | --- | --- |
| sub (bcast, largest) | 0.02 | 0.06 | 3.0× |
| mul (bcast, largest) | 0.02 | 0.06 | 3.0× |
| div (bcast, largest) | 0.03 | 0.07 | 2.3× |

### Strategy comparison (largest shape 1024×20480, fp16)

| Op | Strategy | Latency (ms) | BW (TB/s) |
| --- | --- | --- | --- |
| relu (unary) | direct | 0.07 | 1.20 |
| relu (unary) | explicit_parallel | 0.08 | 1.03 |
| relu (unary) | register_copy | 0.02 | 3.71 |
| add (binary) | direct | 0.08 | 1.65 |
| add (binary) | explicit_parallel | 0.03 | 3.81 |
| silu_and_mul (fused) | direct | 0.04 | 1.46 |
| silu_and_mul (fused) | explicit_parallel | 0.02 | 2.84 |

<details>
<summary>Full benchmark report (profile_run.log)</summary>

```
173 passed, 0 failed (516.61s)
See profile_run.log for per-op latency/TFLOPS/bandwidth tables.
```

</details>

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-18 20:11:41 +08:00
Cao Ying d4852d2082
[Doc] Add elementwise kernel performance checklist and evidence (#556)
## Summary

- Add `docs/perf/` directory with structured performance documentation
for elementwise kernels
- **Checklist** (`elementwise.md`, ~25 lines): heuristic rules for
agent/reviewer audit covering strategy selection, vectorization, config
tuning, caching, and code quality
- **Evidence** (`elementwise-evidence.md`): measured data and reasoning
from PRs #500, #537, #538, #539 — loaded on demand only when
justification is needed
- **Index** (`README.md`): test environment table (H200/CUDA
12.8/TileLang 0.1.8) scoping all conclusions, plus category index for
future op families
- Checklist framed as heuristics with explicit guidance: violations need
justification, not mandatory fixes

## Test plan

- [x] All markdown files pass mdformat and codespell pre-commit hooks
- [x] Cross-links between checklist, evidence, and README verified
- [x] No runtime code changes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 20:15:02 +08:00
Cao Ying f36a6d10cb
[Chore][Skills] Rename "compliance" to "readiness" across PR skill and docs (#515)
## Summary

- Rename `op-compliance-checklist.md` → `op-readiness-checklist.md`
- Replace all references from "Structural Compliance" to "Structural
Readiness" across skill files and docs
- "Readiness" better reflects agent-human co-creation: the checklist
asks "is this op ready to ship?" rather than "does this comply?"

**Changed files:**

| File | Change |
|------|--------|
| `.claude/skills/creating-pull-request/op-compliance-checklist.md` |
Renamed to `op-readiness-checklist.md`, updated heading |
| `.claude/skills/creating-pull-request/SKILL.md` | Updated step title,
file reference, and PR body section name |
| `.claude/skills/creating-pull-request/template.md` | `## Structural
Compliance` → `## Structural Readiness` |
| `docs/CONTRIBUTING.md` | `2-Layer Compliance` → `2-Layer Readiness` |

**Not changed:** `docs/DEVELOPMENT.md:195` ("code style compliance") —
generic English usage, unrelated to op checklist.

## Test plan

- [x] `grep -ri compliance` across non-worktree files returns only the
unrelated `docs/DEVELOPMENT.md` hit
- [x] All internal links (`op-readiness-checklist.md`) resolve correctly
- [x] pre-commit passes

---

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-15 18:47:58 +08:00
Cao Ying d98af39549
[Chore] Remove domain-knowledge skills; add op compliance checklist (#493)
## Summary

- Remove 5 domain-knowledge skills (`migrating-new-op`, `tune`,
`tune-multiplication`, `check-kernel-format`, `kernel-debug`) whose
content has been migrated to the [project
wiki](https://github.com/tile-ai/TileOPs/wiki)
- Add `op-compliance-checklist.md` to the `creating-pull-request` skill
as an on-demand Step 2 HARD GATE — agent reads and verifies kernel/op
structural conventions only when the PR touches kernel/op code
- Delete `docs/kernel-op-conventions.md` (content consolidated into
wiki)
- Update `CLAUDE.md` skill index to remove deleted skill entries

## Test plan

- [x] `pre-commit run --all-files` passed
- [x] Verified remaining skills (`committing-changes`,
`creating-pull-request`, `creating-issue`, `lifecycle-pull-request`,
`lifecycle-issue-fixer`) are unaffected
- [x] Confirmed `op-compliance-checklist.md` is correctly referenced
from `SKILL.md` Step 2
- [x] Confirmed PR template is unchanged from main

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 10:21:29 +08:00
Cao Ying 4d65362c58
[Feat][Elementwise] Add 30 UnaryKernel template ops (#457)
## Summary

Implement 30 `UnaryKernel` subclasses and 30 corresponding `UnaryOp`
subclasses for elementwise operations, then tighten the implementation
to match issue #437 and the follow-up review findings.

**Ops**: `exp`, `log`, `sqrt`, `rsqrt`, `abs`, `neg`, `reciprocal`,
`sign`, `sin`, `cos`, `floor`, `ceil`, `round`, `trunc`, `erf`, `log1p`,
`expm1`, `gelu`, `silu`, `sigmoid`, `tanh`, `hardswish`, `hardsigmoid`,
`mish`, `selu`, `logical_not`, `bitwise_not`, `isnan`, `isinf`,
`isfinite`

Closes #437

## Dtype Support Matrix

| Op / API | Input dtypes | Output dtype | Reference baseline |
| --- | --- | --- | --- |
| Unary math ops + activations | `fp16`, `bf16`, `fp32` | same as input
| matching `torch` / `torch.nn.functional` unary semantics |
| `logical_not` | `bool`, `uint8`, `int8`, `int16`, `int32`, `int64`,
`fp16`, `bf16`, `fp32` | `bool` | `torch.logical_not` |
| `bitwise_not` | `bool`, `uint8`, `int8`, `int16`, `int32`, `int64` |
same as input | `torch.bitwise_not` |
| `isnan`, `isinf`, `isfinite` | `fp16`, `bf16`, `fp32` | `bool` |
`torch.isnan`, `torch.isinf`, `torch.isfinite` |

## Test Plan

- [x] **AC-1**: 30 kernel subclasses and 30 op subclasses exist for the
issue #437 scope.
- [x] **AC-2**: Unary elementwise dtype contracts are explicit in code
via `SUPPORTED_DTYPES` / `OUTPUT_DTYPE` where needed.
- [x] **AC-3**: `gelu` uses the standard `erf` formulation instead of
the tanh approximation.
- [x] **AC-4**: `logical_not`, `isnan`, `isinf`, and `isfinite` produce
torch-style `bool` outputs and tests validate them with exact
comparison.
- [x] **AC-5**: `bitwise_not` support is aligned to the current torch
contract (`bool/uint8/int8/int16/int32/int64`) and reject-path tests
exist for float dtypes.
- [x] **AC-6**: L4 edge-case coverage matches issue #437 for `sqrt`,
`rsqrt`, `log`, `log1p`, `exp`, `expm1`, `erf`, `reciprocal`, `sign`,
and special predicates.
- [x] **AC-7**: Repository-level templates/docs now require future new
ops to include a dtype support matrix, acceptance checklist, and
benchmark table in the PR body.
- [x] **AC-8**: A representative unary benchmark file exists in
`benchmarks/ops/bench_unary_elementwise.py` and runs on a real GPU
machine with small, medium, and large shapes.
- [x] **AC-9**: Top-level `__init__.py` re-export files remain
unchanged.
- [x] Elementwise correctness suite passes on the real machine GPUs:
`127 passed, 2 warnings in 8.04s`.
- [x] Unary benchmark suite passes on the real machine GPUs: `21 passed,
23 warnings in 56.25s`.

## Benchmark

**Configuration**: H200, Driver `575.57.08`, CUDA `12.8` (torch), torch
`2.9.1+cu128`

| N_total | dtype | Op | TileOPs (ms) | Baseline (ms) | Ratio |
| --- | --- | --- | --- | --- | --- |
| 262,144 | fp16 | `exp` | 0.00250 | 0.00607 | 2.43x faster |
| 1,048,576 | fp16 | `exp` | 0.00334 | 0.00768 | 2.30x faster |
| 4,000,000 | fp16 | `exp` | 0.00680 | 0.01032 | 1.52x faster |
| 262,144 | bf16 | `exp` | 0.00251 | 0.00628 | 2.50x faster |
| 1,048,576 | bf16 | `exp` | 0.00334 | 0.00709 | 2.12x faster |
| 4,000,000 | bf16 | `exp` | 0.00669 | 0.01091 | 1.63x faster |
| 262,144 | fp16 | `gelu` | 0.00264 | 0.00734 | 2.78x faster |
| 1,048,576 | fp16 | `gelu` | 0.00401 | 0.00839 | 2.09x faster |
| 4,000,000 | fp16 | `gelu` | 0.00980 | 0.01323 | 1.35x faster |
| 262,144 | bf16 | `gelu` | 0.00267 | 0.00656 | 2.46x faster |
| 1,048,576 | bf16 | `gelu` | 0.00409 | 0.00845 | 2.07x faster |
| 4,000,000 | bf16 | `gelu` | 0.01009 | 0.01277 | 1.27x faster |
| 262,144 | fp16 | `logical_not` | 0.00262 | 0.00679 | 2.59x faster |
| 1,048,576 | fp16 | `logical_not` | 0.00545 | 0.00691 | 1.27x faster |
| 4,000,000 | fp16 | `logical_not` | 0.01467 | 0.00941 | 0.64x |
| 262,144 | int32 | `bitwise_not` | 0.00297 | 0.00715 | 2.41x faster |
| 1,048,576 | int32 | `bitwise_not` | 0.00604 | 0.00816 | 1.35x faster |
| 4,000,000 | int32 | `bitwise_not` | 0.01657 | 0.01404 | 0.85x |
| 262,144 | fp16 | `isnan` | 0.00263 | 0.00674 | 2.56x faster |
| 1,048,576 | fp16 | `isnan` | 0.00546 | 0.00690 | 1.26x faster |
| 4,000,000 | fp16 | `isnan` | 0.01473 | 0.01016 | 0.69x |

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 18:55:08 +08:00
Cao Ying 0e30b14531
[Chore][Tooling] Add Makefile as developer task runner (#349)
Closes #347

## Summary

- Add `Makefile` at repository root with targets: `install`, `lint`,
`test`, `bench`, `clean`
- `make install` bundles `pip install -e '.[dev]'` and `pre-commit
install` into a single command, eliminating the gap where developers
skip hook installation
- Update `CLAUDE.md` to reference `make install` as the setup command
- Update `docs/CONTRIBUTING.md` to reference `make install` in the Fork
& Branch workflow

## Test plan

- [x] pre-commit passed (all hooks: trailing whitespace, ruff,
codespell, mdformat, gitleaks)
- [x] `make -n install` outputs both `pip install -e '.[dev]' -v` and
`pre-commit install`
- [x] `make -n lint` outputs `pre-commit run --all-files`
- [x] `make -n test` outputs `python -m pytest -q tests`
- [x] `make -n bench` outputs `python -m pytest benchmarks/`
- [x] `make -n clean` outputs `rm -rf build/ dist/ *.egg-info`
- [x] `pyproject.toml` unchanged — Makefile is strictly a task runner,
not a build system

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 20:00:48 +08:00
Ang Gao cd0f95555c
[Chore][Skill] add check-kernel-format skill and kernel-op-conventions doc (#311)
## Summary

- **New skill** — `.claude/skills/check-kernel-format/SKILL.md`: a slim
(~30-line) post-delivery validation gate. Contains only the action flow
(when to run, checklist items, failure gate). Renamed to `SKILL.md`
(uppercase) per Claude Code spec. Restricted to read-only tools
(`allowed-tools: Read, Grep, Glob`).
- **New doc** — `docs/kernel-op-conventions.md`: extracted all stable
architectural knowledge from the skill (structural rules, rationale,
WRONG/CORRECT code examples, tuning deliverable reference). Zero
context-budget cost until explicitly read; human-readable without
Claude.
- **CLAUDE.md** — added `check-kernel-format` entry to the Skill Index
table.

## Design rationale

Per reviewer feedback on #306 (zhen8838), the original `skill.md` mixed
action instructions with reference documentation. The split follows the
pattern already in the repo (`migrating-new-op/SKILL.md` ↔
`docs/DEVELOPMENT.md`):

| What | Where |
|------|-------|
| Action instructions ("do what, when, how") | `SKILL.md` |
| Structural rules, rationale, code examples |
`docs/kernel-op-conventions.md` |

## Checklist

- [x] `SKILL.md` < 50 lines, single responsibility
- [x] `allowed-tools` constrains to read-only tools
- [x] `docs/kernel-op-conventions.md` covers §1 T.prim_func, §2 Kernel,
§3 Op, §4 Tuning, code examples
- [x] CLAUDE.md Skill Index updated
- [x] Split from FFT feature PR (#306) for independent review and
revertability

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-04 18:19:09 +08:00
Cao Ying ac88d33f1e
[Chore][Style] Codebase polish: exports, lint, stale-issues workflow, and style rules (#307)
## Summary

- Standardize `__init__.py` across all kernel sub-packages: add missing
`__all__`, normalize to double quotes, one-entry-per-line,
alphabetically sorted
- Replace star import in `utils/__init__.py` with explicit imports
- Fix `ops/deepseek_nsa.py`: use package-level kernel imports instead of
reaching into submodules; use relative import for `Op`
- Remove stale file-level lint suppressions (`# ruff: noqa`, `# flake8:
noqa`, invalid `# noqa: U100`)
- Fix import ordering (stdlib → third-party → local) in kernel files
- Add `.claude/rules/code-style.md` with project-level style conventions
- Add stale-issues workflow (closes issues with no comment activity for
4 weeks)
- Fix CONTRIBUTING.md layer count to match current 2-layer architecture

## Test plan

- [x] `ruff check tileops/` passes
- [x] `pre-commit run --all-files` passes
- [x] All package imports verified (`python -c "from tileops.kernels.*
import ..."`)
- [ ] CI `tileops_test_release` (previous failure was GitHub runner
network timeout, not code)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-04 17:59:42 +08:00
Zheng QiHang 3abd3b17b5
[Chore][Tooling] Unify type conventions and decompose PR lifecycle skill (#267)
## Summary

- Refactored `lifecycle-pull-request` SKILL.md to use explicit `Skill`
tool invocations instead of inline step repetition, decomposing the PR
flow into discrete, reusable skill calls
- Fixed review issues in the PR lifecycle skill: `validate.sh` bug,
timeout typo, and worktree detection logic
- Created `.claude/conventions/types.sh` as a single source of truth for
all type lists, regex patterns, and label mappings; updated all
validation scripts, CI workflows, SKILL docs, and `CONTRIBUTING.md` to
source it, eliminating type drift across 11+ files
- Removed legacy type aliases (`Feature`, `Docs`, `Build`, `Style`,
`Lint`) that had accumulated across files
- Synced repo labels to match canonical set (added `bench`, `test`,
`perf`)
- Fixed pre-commit autofix message wording

## Test plan

- [x] `source .claude/conventions/types.sh` renders correct regex
patterns
- [x] `validate.sh` scripts pass with patterns sourced from `types.sh`
- [x] CI workflows reference `types.sh` instead of hardcoded patterns
- [x] Legacy types (`Feature`, `Docs`, `Build`, `Style`, `Lint`) are
correctly rejected by validation
- [x] Repo labels (`bench`, `test`, `perf`) created and synced to
canonical mapping
- [x] pre-commit passed

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 13:19:21 +08:00
Zhejin Xu 741194a459
[Refactor] Remove L3 (Function) and L4 (Layer) layers (#220)
## Summary

- Remove L3 (`tileops/functions/`, `tests/functions/`) and L4
(`tileops/layers/`, `tests/layers/`) directories — simplify from 4-layer
to 2-layer architecture (L1 Kernel + L2 Op)
- Remove cross-layer `test_grouped_gemm_complete` test that imported
from `tileops.functions`
- Update all documentation (DEVELOPMENT.md, README.md, Claude.md, issue
templates, SKILL.md) to reflect 2-layer architecture

## Test plan

- [x] `ruff check` passes on modified Python files
- [x] No remaining imports of `tileops.functions` or `tileops.layers`
(verified via grep)
- [x] `import tileops` works correctly, exports `["ops"]`
- [x] CI lint/test pass

Closes #193

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 11:27:57 +08:00
Zheng QiHang a70f93f04f
[Refactor] Separate benchmark profiling from unit tests (#224)
## Summary

Closes #184

Refactors the test/benchmark infrastructure so that **correctness tests
and performance profiling are fully separated**:

- `pytest tests/` — validates correctness only (106 tests, no profiling)
- `pytest benchmarks/` — runs profiling only, auto-generates
`profile_run.log` (21 benchmarks across 7 ops)

### Architecture

Introduces four core abstractions:

| Class | Location | Role |
|---|---|---|
| `FixtureBase` | `tests/test_base.py` | Metaclass-based `@decorator`
for `pytest.mark.parametrize` |
| `TestBase` | `tests/test_base.py` | ABC: `gen_inputs()`,
`ref_program()`, `check()`, `check_fn()` |
| `BenchmarkBase` | `benchmarks/benchmark.py` | ABC wrapping `TestBase`,
adds `calculate_flops()`, `calculate_memory()`, `profile()` |
| `BenchmarkReport` | `benchmarks/benchmark.py` | Static collector:
`record()` → `dump()` markdown report |

### Changes

- **New infrastructure**: `tests/test_base.py`,
`benchmarks/benchmark.py`, `benchmarks/conftest.py`
- **Migrated all ops** to the new pattern (20+ test files in
`tests/ops/`, `tests/functions/`, `tests/layers/`)
- **Created benchmark files** in `benchmarks/ops/` for all ops (7 with
profile test functions, 13 class-only)
- **Removed legacy**: old benchmark subdirectories (`flash_attn/`,
`gemm/`, `grouped_gemm/`, etc.), CSV param files, profile scripts,
`benchmark_legacy.py`
- **Moved** `benchmarks/deepseek_nsa/utils.py` → `tests/nsa_utils.py`
- **Updated** `docs/DEVELOPMENT.md` to document the new architecture
- **Removed** `docs/plans/` (implementation complete)
- **Added** `python_files = ["test_*.py", "bench_*.py"]` to
`pyproject.toml`

## Test plan

- [x] `pytest tests/` collects 106 tests (same as main, no loss)
- [x] `pytest benchmarks/` collects 21 benchmarks, all pass, generates
`profile_run.log`
- [x] Individual test correctness verified (test_mhc_pre,
test_grouped_gemm, test_gqa_fn all pass)
- [x] Pre-existing failures on main (`test_matmul` CUDA resource,
`test_gemv` assertion) confirmed not introduced by this PR — tracked in
#219


🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 16:46:35 +08:00
Cao Ying 2d70b523c0
[Chore] Fix docs and config inconsistencies (#223)
## Summary

**Docs & config consistency fixes:**
- Rename CI workflow from `hello-self-hosted` to `CI`
- Mark mypy strict checking as *(planned)* in DEVELOPMENT.md — it is not
yet implemented (no config, no dependency, no CI job)
- Remove `ANN` from ruff lint select — every ANN sub-rule was
individually ignored, making it a no-op
- Fix README: `tilelang >= 0.1.8` → `== 0.1.8` to match the pinned
version in `pyproject.toml`
- Fix README: acknowledge `einops` in the "Lightweight Dependencies"
claim
- Clean `.gitignore`: remove unrelated legacy entries (nnfusion,
VisualGDB, docbuild artifacts, precompiled headers, etc.), restore
`!testing/python/debug` exception
- Fix `Claude.md`: replace reference to non-existent `conda activate
top` with generic venv instruction

**Claude Code skill & config fixes:**
- Move custom skills from `.claude/<name>/` to `.claude/skills/<name>/`
so they are auto-discovered as user-invocable (fixes
`/creating-pull-request` and `/migrating-new-op` not appearing in skill
list)
- Add `.claude/settings.json` enabling `superpowers` plugin for the
project

Relates to #221, #222

## Test plan

- [ ] Verify `pre-commit run --all-files` passes (lint-only changes)
- [ ] Verify `python -m build` still produces sdist + wheel correctly
- [ ] Verify `/creating-pull-request` and `/migrating-new-op` skills are
discoverable in a new Claude Code session

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 13:06:08 +08:00
Zhejin Xu eab6e6bfc4
[Refactor] Modernize pyproject.toml and remove redundant config files (#209)
## Summary
Closes #191

Modernize project configuration and streamline dependencies:

- Slim project dependencies to `torch>=2.1.0`, `tilelang==0.1.8`,
`einops`; dev deps to `ruff`, `codespell`, `pytest`
- Bump `requires-python` to `>=3.10`, add PEP 621 metadata (keywords,
classifiers, urls)
- Remove `"build"` from `build-system.requires`, align codespell to
2.4.1, relax pytest to `>=8.0`
- Remove 17 invalid ruff ignore rules (D1xx/D2xx/D4xx/T201) and unused
`[tool.ruff.lint.pydocstyle]` section
- Add `[tool.pytest.ini_options]` with `testpaths`
- Delete `.pre-commit-config.yaml`, `MANIFEST.in`, and
`requirements-lint.txt` (redundant with pyproject.toml)
- Add `.venv/` to `.gitignore`
- Add Python 3.12 classifier
- Remove yapf configuration and references
- Update README and DEVELOPMENT.md to match new configuration

## Test plan
- [x] `pip install -e .` installs successfully with correct dependencies
- [x] `ruff check tileops/` passes
- [x] `codespell tileops/` passes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 10:11:03 +08:00
Zheng QiHang 5a9e54d65c
[Refactor] Rename source directory from `top` to `tileops` (#190)
## Summary

Closes #186

- Rename `top/` → `tileops/` to align the source directory name with the
package name defined in `pyproject.toml` (`name = "tileops"`)
- Update all internal imports (`from top.` → `from tileops.`) across 116
Python files
- Update documentation paths in `DEVELOPMENT.md`, `README.md`,
`SKILL.md`, and issue templates
- Update `.pre-commit-config.yaml` yapf workaround path

## Motivation

The package is named `tileops` in `pyproject.toml`, but the source code
previously lived under `top/`. This creates a mismatch between the
package name and the module import path, which is confusing for
contributors and downstream users.

## Test plan

- [x] `pre-commit run --all-files` passed
- [x] `PYTHONPATH="$PWD" python -m pytest tests/ops/test_mha.py` — 6
passed
- [x] `PYTHONPATH="$PWD" python -m pytest tests/ops/test_gemm.py
tests/ops/test_gqa.py tests/functions/test_mha_func.py` — all passed
- [x] `import tileops` works correctly

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 19:22:37 +08:00
Zheng QiHang 4433c7273b
[Fix][Benchmark] Guard against zero latency division (#176) (#182)
Closes #176

## Summary

- Fix `ZeroDivisionError` by falling back to `event` backend when
`cupti` returns zero latency
- Root cause: CUPTI profiler can fail to capture kernel events in
certain environments (e.g. Nsight Compute exclusively holds CUPTI),
causing `do_bench` to return 0
- Fix: when cupti returns `<= 0`, automatically retry with `event`-based
timing which uses `cuda.Event` and does not depend on CUPTI
- Fix pytest command in `docs/DEVELOPMENT.md` to use `PYTHONPATH="$PWD"
python -m pytest`
- Deduplicate docs: `docs/DEVELOPMENT.md` (source) -> `Claude.md`
(reference) -> skill (reference)
- Add `creating-pull-request` skill with pull-before-push rule
- Fix repo path and dead reference in skill

## Related

- #184 — Separate benchmark profiling from unit tests (follow-up)
- #183 — Bandwidth unit conversion investigation (pre-existing)

## Test plan

- [x] `pre-commit run --all-files` passed
- [x] `PYTHONPATH="$PWD" python -m pytest tests/ops/test_mha.py` — 6
passed

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: ChongLi <35960466+RMLYC@users.noreply.github.com>
2026-02-25 16:34:35 +08:00
Lingxiao Ma 95f1839a6e
[Doc] Collaboration guidance (#120)
Collaboration guidance, including development and PR review guidance
2026-01-09 13:13:03 +08:00
Lingxiao Ma 65bbd895bd
[Doc] Fix development doc and add bug report issue template (#83)
## Description
<!-- Briefly describe the changes introduced by this PR -->
- Fix the project directory structure description in the development
guide
- Add bug report issue template

## Type of Change
- [ ] Bug fix
- [ ] New operator implementation
- [ ] Performance improvement
- [x] Documentation update
- [ ] Infrastructure/CI

## Checklist
- [x] I have run `pre-commit run --all-files` and fixed all linting
issues.
- [x] I have verified that my changes pass local unit tests.
- [ ] **(For new ops)** I have added the corresponding `Benchmark` class
in `benchmarks/`.
- [ ] **(For new ops)** I have reported benchmark results in the
tracking issue.
2026-01-07 10:51:25 +08:00
Cao Ying b8b7c07d7a
[Chore] Update README, pre-commit hooks and reformat. (#82)
This pull request enhances the project's code quality, developer
experience, and overall structural integrity. It mainly makes the
following changes:

* Introduced a new `.flake8` configuration file and updated the
`.pre-commit-config.yaml` to enable more linting and formatting hooks.
* Removed the `flash-attention` git submodule and updated `.gitignore`
and `MANIFEST.in` to streamline the project's dependencies and
packaging.
* The `pyproject.toml` file was updated to reflect the new linting
setup.
2026-01-05 18:20:15 +08:00
Lingxiao Ma 2f6e4f2137
[Doc] Refactor development docs (#81)
## Description
Refactor the DEVELOPMENT doc and the corresponding github template

* Documentation Refinement: The DEVELOPMENT.md guide has been updated to
streamline the 'Development Workflow' section.
* Enhanced Operator Development Workflow: The guide now includes more
detailed instructions for new operator development, such as task
decomposition for tracking issues, explicit docstring requirements for
each layer (Kernel, Op, Functional API, Layer), and a new dedicated step
for benchmark results.
* GitHub Template Updates: Minor adjustments were made to GitHub
templates; New issue template for new op subtask.

## Type of Change
- [ ] Bug fix
- [ ] New operator Implementation
- [ ] Performance improvement
- [x] Documentation update
- [ ] Infrastructure/CI

## Checklist
- [x] I have run `pre-commit run --all-files` and fixed all linting
issues.
- [x] I have verified that my changes pass local unit tests.
- [ ] **(For new ops)** I have added the corresponding `Benchmark` class
in `benchmarks/`.
- [ ] **(For new ops)** I have reported benchmark results in the
tracking issue.
2026-01-05 16:17:46 +08:00
Lingxiao Ma a4985db434
[Doc] Add development doc and update readme (#75)
This pull request refactors the project's `README.md` file. It mainly
makes the following changes:

1. The `README.md` has been refactored to
provide a more comprehensive and structured overview of the TileOPs
project, including detailed feature descriptions and design principles.
2. A new project logo has been added to the
`README.md` for improved branding and visual appeal.
2026-01-05 09:14:25 +08:00
Lingxiao Ma 3d8b6c2ac9
[Doc] Update README with Sparse MLA performance (#38)
* [Refactor] Refactor dependencies

* [Doc] Update README with Sparse MLA performance

* Update README.md

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Update README.md

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

* Update README.md

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
2025-09-30 20:36:02 +08:00
Yu Cheng cf79688819
[Doc] Add Sparse MLA perf figure (#36) 2025-09-30 02:12:40 +08:00