·
Last changedVersion:
This version passed the hardening gate. Hardening updated the skill content and independently checked the resulting changes. Classified findings before hardening: 6. Classified findings closed: 2. Classified findings remaining: 4. Unclassified scanner findings remaining: 0. Review findings closed: 0. Review findings remaining: 16.
1
3
2
2
2
Expand | File | Group | Subtype | Severity | Status |
|---|---|---|---|---|---|
SKILL.md | Obfuscation & Evasion | Trigger-based activation | High | Closed | |
SKILL.md | Tool & MCP Manipulation | MCP over-permissioning | Medium | Open | |
references/workflow.md | Sensitive Data & Secret Exposure | Hardcoded secret | Medium | Open | |
BENCHMARK.md | Sensitive Data & Secret Exposure | Agent snooping | Medium | Closed | |
references/search-strategies.md | Sensitive Data & Secret Exposure | Hardcoded secret | Low | Open | |
references/kernel-type-templates.md | Sensitive Data & Secret Exposure | Hardcoded secret | Low | Open |
6 findings
Add autotuning to CuTile kernels using the exhaustive_search API with tune-once/cache/direct-launch pattern.
Follow the decision tree to classify the kernel, design a search space, implement the tune-once/cache/launch pattern, and validate performance.
references/kernel-type-templates.md; prune to ≤ 30 configs in the final code via arch filters (directed exploration probes may temporarily exceed this — see Design Philosophy)exhaustive_search + cache + ct.launch following the Step-by-Step Workflow; handle in-place writes with split-buffer if neededDISABLE_AUTOTUNE=1references/search-strategies.md| What are you trying to do? | Go to |
|---|---|
Add autotune to a new kernel (most common) | Quick Reference below → Workflow: Adding Autotune → |
Debug: data corruption / wrong results after first run | Pitfall #1 (In-Place Kernel) |
Debug: autotune taking 5+ minutes | Pitfall #2 (Compilation Timeout) |
Debug: search space generator returning zero configs | Pitfall #5 first; also check arch filters, size guards, and |
Optimize an existing autotune config | Workflow: Optimizing an Existing Config |
Most CuTile kernels (elementwise, reduction, LayerNorm) need only occupancy tuning. Copy this pattern:
Key rules:
exhaustive_search runs only on first call per shape; subsequent calls use cached config + ct.launch with zero overheadexhaustive_search requires a Sequence (list/tuple) — convert generators with list()When to use this pattern: Kernel has fixed block size (not tile-size tunable). Includes: elementwise (SwiGLU, GeGLU), reduction (RMSNorm, LayerNorm), RoPE, and persistent kernels with heuristic block sizes (grouped GEMM).
For complex kernels (matmul with tile sizes, FMHA, FP8 with num_ctas), read the full guide below + kernel-type-templates.md.
references/ docs. For in-place kernels, also read Pitfall #1.references/ docs.5-step summary: Classify kernel → Design search space (parameter-space-design.md) → Implement using template (kernel-type-templates.md) → Validate with A/B test → Check Pitfall Checklist.
Reading references: Read only the reference relevant to your kernel type — e.g., for FMHA, read the Template 5 section in references/kernel-type-templates.md; for hardware constraints, read only the target architecture's section. Avoid reading all references end-to-end when a targeted lookup suffices.
Build a small, precise search space bottom-up — not a large space trimmed down. CuTile compilation is much heavier than Triton (~0.5-1s per config), so the final code should contain ≤ 30 configs. The approach is: classify the kernel type first, then construct only the relevant configs for that type and architecture.
Directed exploration during development: If the initial template configs yield speedup < 1.0, you may run a temporary larger probe (30–100 configs) to identify which dimensions matter — but this probe must be directional, not a blind cartesian product. Use the kernel type classification to decide which dimensions to vary (e.g. for dual-GEMM, probe num_ctas × occupancy while fixing tile sizes; for FMHA, probe TILE_M × num_ctas while fixing TILE_N). Once the probe identifies the winning region, lock the final code's search space to ≤ 8 top candidates. Do NOT write the large probe into the source file — it is a one-shot diagnostic tool.
All kernels should have autotuning added. The question is not whether to autotune, but what dimensions to search:
Why memory-bound kernels only search occupancy (not num_ctas or tile sizes):
num_ctas has zero benefit: num_ctas > 1 enables TMA multicast, where multiple CTAs share tile data in shared memory (e.g., matmul A/B tiles reused across CTAs). Memory-bound kernels use per-element ct.gather/ct.scatter with no tile reuse — multi-CTA cooperation adds overhead with no data sharing benefit.Note on memory-bound kernels: Adding occupancy-only autotune is always worthwhile because:
Occupancy controls how many CTAs run concurrently per SM. Use this as a starting point when designing the occupancy search space:
| Occupancy Range | Best For | Example Kernels |
|---|---|---|
1–4 | Compute-bound (heavy math) | Complex transforms, matmul |
4–8 | Balanced (GEMM, TMA) | Matrix multiply, FMHA |
8–16 | Memory-bound (reductions) | Softmax, LayerNorm |
16–32 | Very light (copies, casts) | Type conversions, elementwise |
Use these ranges to seed your initial search space. For occupancy-only kernels, [1, 2, 4, 8] covers most cases — see Quick Reference above.
See references/api-reference.md for the full
exhaustive_search API surface — current signature, TuningResult, the
tune-once/cache/launch pattern, replace_hints, kernel hints, search_space
design, and grid_fn patterns.
See references/workflow.md for the end-to-end
workflow — adding autotune to a new kernel, handling existing
multi-architecture configs, integration with torch.autograd.Function,
cross-backend config transfer (Triton → CuTile), and optimizing an existing
config.
See references/pitfalls.md for the full list of
common pitfalls — in-place data corruption, compilation timeout, cold-cache
performance skew, NCU profiling interference, search_space generator
exhaustion, FP8 precision loss, and replace_hints recompilation on hot
paths.
This skill covers only autotune configuration: search space design, exhaustive_search invocation, caching, and ct.launch with tuned hints. It does not modify kernel code.
In scope (autotune config):
exhaustive_search() calls and result handlingkernel.replace_hints() for applying tuned hintsct.launch() with tuned kernelDISABLE_AUTOTUNE fallback pathOut of scope (kernel code modifications — do NOT make these changes):
After adding autotuning, the following kernel-level optimizations may yield additional gains. These are outside the scope of this skill — mention them to the user as potential next steps, but do not implement them as part of autotuning:
flush_to_zero=True + rounding_mode=APPROX can provide 34-72% improvement for FMHA-class kernels (set via environment variables TILEIR_ENABLE_FTZ=1 TILEIR_ENABLE_APPROX=1 or in kernel code). Causal chain: larger tiles initially decrease performance by 18-43% due to subnormal handling overhead; enabling FTZ+APPROX rescues this and flips the result to +34-72%. Math flags are therefore a prerequisite for large-tile configs to be effective on FMHA-class kernels.slice_hint, buffer_depth, copy_config — requires modifying kernel IR codect.load) instead of ct.gather; removing unnecessary bounds checks (check_bounds=False when safe)padding_value parameter instead of manual ct.where masking; removing safe_offsKey differences: Triton uses @triton.autotune decorator with Config(...) objects; CuTile uses exhaustive_search() with SimpleNamespace configs + separate cache + ct.launch. CuTile has no num_warps/num_stages (compiler decides) — only tile sizes + occupancy + num_ctas. CuTile compilation is heavier (keep ≤30 configs in final code). CuTile cache is user-managed in-memory (no automatic persistence). CuTile separates args_fn (kernel args) from hints_fn (compiler hints).
| Category | Document | Content |
|---|---|---|
API Reference |
| |
Workflow | End-to-end workflow: adding autotune to a new kernel, multi-architecture configs, | |
Pitfalls | Common pitfalls: in-place corruption, compilation timeout, cold-cache skew, NCU interference, | |
Parameter Design | Per-kernel-type parameter spaces, cross-arch patterns, grid_fn patterns, pruning rules | |
Search Strategies | Exhaustive search, A/B test methodology, DISABLE_AUTOTUNE pattern | |
Templates | Copy-paste autotune templates for 8 kernel types | |
Hardware | Per-architecture constraints, tile size ranges, num_ctas rules, TMA requirements |
Key files: ops/cutile/matmul.py (matmul autotune), ops/cutile/attention.py (FMHA autotune), suites/unsloth/cutile/ct_ops.py (shared autotune_configs() occupancy=[1,2,4,8]), suites/unsloth/cutile/swiglu.py (elementwise example), suites/unsloth/cutile/rope_embedding.py (split-buffer pattern), suites/unsloth/cutile/grouped_gemm.py (persistent GEMM, occupancy-only).
Each example shows the before → after pattern: fixed_launch.py (hardcoded ct.launch) and autotuned_launch.py (refactored to tune-once/cache/launch).
| Directory | Kernel | Autotune Pattern | Complexity | Key Teaching Point |
|---|---|---|---|---|
RMSNorm (reduction) | Occupancy-only | Low | Most common pattern — no tile tuning, just find best occupancy. Grid = | |
GEMM C=A@B | Full: | High | Compute-bound kernel with multiple tunable dimensions. | |
RoPE embedding (in-place) | Occupancy-only, with split-buffer | Medium | In-place kernel MUST use split-buffer during search to avoid corruption. Search writes to scratch; final |
Get started with chainctlchainctl skill install public/nvidia/tilegym-cutile-autotuning:latest
Bring Chainguard's hardening pipeline to your first-party skills — custom rulesets, automated remediation, full audit trail.
skills.cgr.dev/public/github.com/nvidia/skills/tilegym-cutile-autotuning:latest
Apache-2.0
BENCHMARK.md
HARDENING.md
LICENSE
SKILL.md
assets/examples/01_rmsnorm_occupancy_only/autotuned_launch.py
assets/examples/01_rmsnorm_occupancy_only/fixed_launch.py
assets/examples/02_matmul_full_search/autotuned_launch.py
assets/examples/02_matmul_full_search/fixed_launch.py
assets/examples/03_rope_inplace_splitbuffer/autotuned_launch.py
assets/examples/03_rope_inplace_splitbuffer/fixed_launch.py
evals/evals.json
references/api-reference.md
references/hardware-constraints.md
references/kernel-type-templates.md
references/parameter-space-design.md
references/pitfalls.md
references/search-strategies.md
references/workflow.md
skill-card.md
skill.oms.sig