feat(cutile): support scalar specialization overrides
Maintainers usually reply within 2 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 25/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Stale
- Tech stack
- rust
- Domain
- backend, performance
Research direction
Read AGENTS.md's “Transplanting a cutile-rs pull request” section first; this issue tracks the closed NVlabs/cutile-rs#227 pull request, whose branch can be replayed with that procedure. The original work names cutile/tests/specialization_bits.rs and the TileKernel trait; inspect the transplanted changes and verify the two specialization assertions, noting the report that end-to-end GPU tests were not rerun after the rebase.
Written by the indexing model from the issue text.
Description
Tracks pull request NVlabs/cutile-rs#227 (https://github.com/NVlabs/cutile-rs/pull/227) by @lucifer1004, opened 2026-08-20: feat(cutile): support scalar specialization overrides. The branch was rebased onto cutile-rs main on 2026-10-07 and merges cleanly.
@lucifer1004: that repository has moved here and is being archived, so the pull request is closed there, not rejected. If you want to continue the work, please recreate it against NVIDIA/cuda-rust. AGENTS.md in NVIDIA/cuda-rust has a "Transplanting a cutile-rs pull request" section that lets an agent do the replay (it fetches pull/227/head from NVlabs/cutile-rs, keeps your authorship and sign-off, and maps the moved paths).
Original description:
Motivation
The launcher infers divisibility hints (DivHint) for integer scalar and raw-pointer kernel parameters from their runtime values, and those hints feed the JIT specialization key. For truly dynamic scalars this backfires: a value that happens to be divisible by 4/8/16 on some launches (e.g. a decode batch size m that varies per step) silently produces multiple JIT specializations for the same kernel, each triggering a recompile.
What this adds
A scalar_hint(name, hint) builder method on the generated kernel launcher (declared on the TileKernel trait) that replaces the inferred hint for a named parameter — or adds one — before hints are consumed:
.scalar_hint("m", DivHint::default())(divisor 1) disables specialization for a genuinely dynamic scalar, so incidental runtime divisibility no longer creates extra JIT variants..scalar_hint("n", hint)can also pin a stronger hint than the inferred one when the caller knows a contract the runtime value doesn't reveal.
Overrides apply on both the launch path and the specialization path, so the two stay consistent. On the launch path, an override of an inferred hint is written into the launch-site probe key, so a cached kernel is only reused for the same effective hints, and a launch without overrides still allocates nothing. An override for a parameter without an inferred hint is not part of that key, so such a launch bypasses the launch-site cache.
Example
kernel(ptr, m)
.grid(grid)
.scalar_hint("m", DivHint::default()) // m is truly dynamic; do not specialize on it
.sync()?;
Tests
Added two GPU launch tests in cutile/tests/specialization_bits.rs that dump the generated MLIR and assert:
- an override replaces the inferred hint (
n=12infersdiv_by<4>; overriding withdiv_by<8>emitsassume div_by<8>and nodiv_by<4>); - a default-hint override removes the scalar
assumeentirely while the raw-pointer assume is untouched.
Before the rebase onto current main, all 4 raw_pointer_launch* tests in that file passed on an SM120 GPU. After the rebase I checked the two new tests through CUTILE_DUMP=ir: the emitted Tile IR matches their assertions. My local tileiras currently fails to compile any Tile IR program, main included, so they have not been re-run end to end on a GPU.
🤖 Generated with Claude Code
- Dominant language
- Rust
- Stars
- 3.7k
- Forks
- 312
- Avg merge
- 6d 5h
- Merged PRs (30d)
- 68
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from NVIDIA/cuda-rust
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 70/100
NVIDIA/cuda-rust#1568 · 1 comment ·
Maintainers usually reply within 2 days
-
[BUG]: The doc of trait `LoadTileLike` is incorrectPossibly taken @akhil9tiet claimed this 5 days ago. Openbug
Difficulty 1/5 Under an hour Newbie friendliness 72/100
NVIDIA/cuda-rust#1523 · 2 comments ·
Maintainers usually reply within 2 days
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 2 days
-
Target feature scan splits LLVM IR on ';', so conjunctive predicates match across the whole module (integer redux + any f32 reads as ReduxF32)Possibly taken @vyncint claimed this 32 days ago. Open
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
NVIDIA/cuda-rust#1303 · 1 comment ·
Maintainers usually reply within 2 days
All issues in NVIDIA/cuda-rust
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 62/100
rustls/rustls-platform-verifier#262 · 2 comments · 2 reactions ·
-
needs-triage
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
bherbruck/solvecraft#4493 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
IngvarConsulting/unica#1911 ·
Maintainers usually reply within 1 day