Skip to content

fix(cutile): attribute generated entry setup to the user signature - #1480

Merged
elibol merged 4 commits into
NVIDIA:mainfrom
elibol:fix/cutile-entry-source-locations
Oct 30, 2026
Merged

elibol merged 4 commits into
NVIDIA:mainfrom
elibol:fix/cutile-entry-source-locations

Conversation

@elibol

@elibol elibol commented Oct 10, 2026 •

Copy link
Copy Markdown
Collaborator

Current review head: 9f19c0c84e32e0b686154695b0f9bd96451b5d1f, incorporating main through 0d62b682b after #1528 and #1600 merged. The diff against main remains four files and one source-policy change: generated entry setup uses the user signature span.

Refresh validation: 36 tests passed on CUDA 13.3 with serial execution: 20 debug-info, three constant-origin, six generated-origin, and seven JIT-override tests. This includes ignored assembler, GPU, and live CUDA-GDB cases. Formatting and diff checks pass. Fresh CI is running; independent review is still needed. The older validation details below are historical evidence, not a claim that every suite was rerun at this head.

Generated entry setup currently inherits Span::call_site(), so CUDA-GDB attributes the wrapper and its generated assumptions to the module header. Use the original user function's signature span for the synthesized wrapper, including its call into the user kernel. The original kernel body and nested helper locations remain unchanged.

The regression checks wrapper operations and assumptions, the outer caller in inline chains, and the serialized entry subprogram's declaration line. Constants compiled from synthesized types are outside this change; #1385 has now merged their separate frontend-origin fix. Backend assertion-trap/coredump attribution remains under #1379.

Validation:

  • The new regression fails with the original wrapper span and passes with this change.
  • All nine debug_info tests pass, including real tileiras/nvdisasm checks, execution in all debug modes, and the live cuda-gdb cross-file helper test.
  • Live CUDA-GDB confirms the wrapper frame and the entry instruction now point to the user function signature.
  • Scoped formatting and cargo clippy --locked -p cutile-compiler --lib -- -D warnings pass.
  • Ran the required scripts/run_all.sh: CPU/assembler tests, 26 supported examples, and all eight benchmark smoke tests passed. One example was skipped because it requires Tile IR 13.4 and the installed assembler is 13.3. All GPU targets passed except one existing test-order dependency in warmup_suite; the whole 16-test cache suite passes serially on this branch. The script therefore returned nonzero for that unrelated cache test.

The unrelated cache failure is reproducible on unchanged base bafffe45662a5cdc064a1c6674c6c02d466a58e0: retain_predicate_may_reenter_the_cache_without_deadlock leaves the same specialization cached, while composed_builder_compile_terminal_warms_the_dispatched_specialization expects its compile count to increase by one. Running the baseline test binary with RUSTC_BOOTSTRAP=1 <warmup_suite-binary> warmup_composed:: -Z unstable-options --shuffle-seed 3 --test-threads 1 reproduces that assertion. This setting only enables the test harness's shuffle option; it does not rebuild or change the pinned toolchain.

For benchmark validation, the existing runner drops its bare smoke-test argument. For this run, its invocation was temporarily corrected to --features smoke-test so all eight benchmarks used the intended smoke configuration. The runner was restored afterward; that correction is not part of the PR.

Part of #1475. The inline call-line breakpoint resolver is addressed separately by NVIDIA/cuda-gdb#29. The generated assertion trap's backend source attribution remains under #1379.

Signed-off-by: Melih Elibol <elibol@users.noreply.github.com>
@copy-pr-bot

copy-pr-bot Bot commented Oct 10, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@elibol
elibol marked this pull request as ready for review October 10, 2026 21:29
@elibol

elibol commented Oct 21, 2026

Copy link
Copy Markdown
Collaborator Author

Reviewing this against the entry-wrapper and wrapper-generated-assumption items in #1475. The existing regression checks the wrapper's origin, outer inline caller, assumptions, and serialized subprogram declaration; the documented live kernel-entry stop is also the right end-to-end evidence.

The remaining test gap is optimized line-info mode: please run the provenance regression for both Line and Full and inspect the emitted cubin line mapping for the wrapper setup in both modes. #1475's audit showed that assumption locations can propagate onto existing optimized instructions even when assumptions emit no separate instructions, so an IR-only/full-debug result does not establish that case. No separate breakpoint on every assumption is required.

Retain the exact nested cross-file helper file/line/caller-chain regression and the live entry-address breakpoint check when rebasing. A generated setup instruction should map to the user signature while helper instructions retain their own locations. Generated constants have their separate scope in #1385, so this PR need not eliminate every module-header row by itself.

This covers two portions of #1475; it should not close the whole audit, #1476's debugger resolver issue, or #1379's assertion-trap/coredump attribution. Also, #1480 is still open; the earlier issue comment saying it had landed is premature.

…odes

Integrate current main, resolve the changelog conflict, and verify exact nested helper chains and entry-instruction cubin locations in both modes. Run the assembler regression in CPU CI.

Signed-off-by: Melih Elibol <1884921+elibol@users.noreply.github.com>
@elibol

elibol commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator Author

/ok to test 899e14b

@elibol

elibol commented Oct 26, 2026

Copy link
Copy Markdown
Collaborator Author

Pushed 899e14b9f9a7686a116992bb0eb0580efe014795: merged current main and completed Line/Full coverage for wrapper operations/assumptions, exact nested cross-file caller chains, and the first assembled instruction's signature location. The assembler regression now runs in CPU CI.

All 11 debug tests pass locally on CUDA 13.3, including GPU execution and live CUDA-GDB. Restoring the unchanged main wrapper generator makes both new wrapper regressions fail. Formatting passes. Updated CUDA 13.2/13.4 Tile CI, build and semver checks pass; Rust CodeQL is still running.

This covers the entry-wrapper/assumption part of #1475. The separate 13.4 inline-frame loss reported on #1385 also reproduces with the pre-existing optional inline-debug test here; the entry-signature test itself passes. Release tracking: #1606.

…ssions

Signed-off-by: Melih Elibol <1884921+elibol@users.noreply.github.com>
@elibol

elibol commented Oct 28, 2026

Copy link
Copy Markdown
Collaborator Author

/ok to test 6e95929

@elibol

elibol commented Oct 28, 2026

Copy link
Copy Markdown
Collaborator Author

Refreshed against main through f613887c4; current head is 6e95929cc7a67fa24ef86139299d4f2571a8dc7d. The source change remains limited to using the original user signature for synthesized entry setup; #1385's separate constant-origin fix and assembler regression are preserved.

Self-review found no new blocker. All 19 debug_info tests pass locally with CUDA 13.3, including the ignored assembler, GPU, and live CUDA-GDB tests, with serial execution. Formatting and diff checks pass. Fresh CI is running. Independent review should check exact wrapper/assumption origins, unchanged user-body and nested helper origins, and whether the assembled first instruction uses the signature in both Line and Full modes. This remains a partial fix for #1475; it does not fix #1379's assertion-trap/coredump attribution or require NVIDIA/cuda-gdb#29.

…ion PR

Signed-off-by: Melih Elibol <1884921+elibol@users.noreply.github.com>
@elibol

elibol commented Oct 29, 2026

Copy link
Copy Markdown
Collaborator Author

/ok to test 9f19c0c

@elibol
elibol merged commit b025a8b into NVIDIA:main Oct 30, 2026
25 checks passed
@elibol
elibol deleted the fix/cutile-entry-source-locations branch October 30, 2026 19:36
elibol added a commit that referenced this pull request Oct 30, 2026
…py (#1516)

Closes #1506. First change under #1460; implements the `bool` decision
recorded there and in #1461 and #1503.

Safe element casts previously checked size and alignment but could turn
a byte containing `2` into a Rust `bool`. This PR rejects those casts,
supports initialized `bool` buffers, and closes the host-side
initialization, atomic-reference, kernel-argument, and pinned-alignment
holes found during review and follow-up auditing.

## Element validity

`DeviceBuffer::cast_elem`, `cast_chunks`, `can_cast_chunks`, and
`Tensor::reinterpret` require `bytemuck::AnyBitPattern` on the target.
Casting into `bool` is therefore a compile error.

The two safe buffer casts also require `T: bytemuck::NoUninit` on their
source: padding or `MaybeUninit` bytes must not become initialized
destination values. `can_cast_chunks` remains a layout query. These
bounds do not restrict `DeviceCopy` itself, and bool-to-byte casts
remain supported.

`bool` implements `DeviceCopy`: valid values can be copied between host
and device, and its all-zero representation is valid. `DeviceCopy` does
not promise that every bit pattern is valid. It remains independent of
`DType`.

The numeric `DType` newtypes implement `Pod`, and `half` enables its
bytemuck feature, preserving numeric reinterpretation targets. cuda-core
re-exports `bytemuck` for downstream marker implementations. Vector
types in cuda-device also implement `Pod`, preserving `cast_chunks`
usage.

## Owned atomic-buffer conversions

`wrap_elem` and `peel_elem` use the unsafe marker `DeviceRepr<Inner>`.
Its contract requires identical layout, valid initialized
representations in both directions, no element destruction, and no
additional ownership obligations. It has no methods and grants no
reference conversions.

The integer and floating-point atomic macros implement `DeviceRepr`, not
`TransparentWrapper`. Consequently, safe
`DeviceAtomicU32::wrap_ref(&u32)` and the reverse `peel_ref` conversion
are unavailable. Owned scalar buffers can still be wrapped for atomic
kernel access and peeled for readback, retaining their allocation,
context, and deallocation stream. Kernel accesses must obey the existing
borrowing and synchronization contracts.

The marker lives in the dependency-free, `no_std` cuda-repr crate and is
re-exported by cuda-core and cuda-device. This lets both sides share one
trait without making kernel-only crates depend on the host runtime. The
dependent lockfiles add this local package without changing registry or
git dependencies. CI path filters include the new crate.

The atomic examples use `wrap_elem`/`peel_elem`. `KernelSliceArg` is not
restricted to `DeviceCopy`, since atomic wrappers are legitimate kernel
element types that cannot implement `Copy`.

## Completed zero-initialization

`DeviceBuffer::zeroed` queues the zero-fill and synchronizes its stream
before returning. A safe readback or launch on another stream can
therefore rely on initialization having completed, including for `bool`.
Empty allocations retain their fast path.

This makes nonempty `zeroed` a blocking constructor. Asynchronous
initialization with automatically retained completion dependencies
belongs to the subsequent runtime work; callers are not asked to repair
a safe API through manual synchronization.

## Host-side argument contracts and pinned alignment

`KernelInputStored` and `KernelOutputStored` now require `unsafe impl`.
Their contracts cover truthful dtype/layout/specialization metadata,
argument ABI, addressable extent, and storage/access retention through
completion and graph replay. Previously an entirely safe custom binding
could present `Tensor<bool>` storage as `u8` output, so a normal byte
kernel could write invalid bool values. The input counterpart could
similarly mislabel arbitrary byte storage as booleans. The safe
`KernelInput`/`KernelOutput` conversion traits remain available and must
return stored bindings satisfying those contracts. Existing owned,
borrowed, view, and mapped bindings retain their behavior.

`PinnedHostBuffer` reserves alignment slack, exposes an aligned interior
pointer, and retains the original CUDA pointer for deallocation. It also
rejects allocation sizes that exceed Rust slice/pointer-arithmetic
limits. Empty and zero-sized buffers keep their aligned dangling
pointers and allocation-free behavior.

## Tensor alias accounting

Tensor aliases and lazy copy operations share a separate ownership
token. Completion leases retain the storage itself without contributing
to that token. Uniqueness therefore stays correct while a lease is being
registered or destroyed: a real alias cannot become a mutable partition,
and retiring a lease cannot spuriously reject a unique tensor. Access
exclusion and completion retention remain enforced.

The acquisition and destruction regressions fail on the previous
implementation and pass with this change. A separate test preserves
ownership held by an unsubmitted copy operation.

## Compatibility and validation

The new `AnyBitPattern` target and `NoUninit` source bounds are breaking
changes for safe casts whose element types do not implement those
traits. Numeric targets remain supported; atomics use the owned-buffer
conversions. Tuple types remain usable as buffer elements but are not
reinterpretation targets. Custom stored Tile argument implementations
must now explicitly uphold the documented unsafe contract.

Earlier validation of the underlying changes:

- Full cuda-core and cuda-device tests, including GPU buffer tests,
compile-fail tests for invalid bool casts and both atomic
shared-reference conversions, and layout checks for all 21 scoped atomic
types.
- A gated-stream regression that fails without the initialization
synchronization and passes with it. It inspects bytes, avoiding invalid
Rust bool values in the failing case.
- Owned wrapper roundtrip coverage for pointer identity, context, stream
retention, and readback.
- GPU runs of `legacy_atomic_rmw_cas`, `legacy_atomic_fadd`, and
`hashmap` on an RTX 5090; all six Tile tensor reinterpretation tests.
- Clippy for cuda-core/cuda-repr, cuda-device/cuda-host, and cutile;
host and component formatting; cuda-core/cuda-repr rustdoc with warnings
denied.
- Device-only build, example lock consistency,
dependency-license/SPDX/source-reference/test-matrix guards, and
cargo-deny for the host, SIMT, backend, device-only, and Tile
workspaces.

The Tile UI snapshot now uses the normalized external-crate path. Both
UI harness tests (all 12 compile-fail cases) pass, and the CPU CI script
now runs them. The version-only update to the planned v0.5.0 API
boundary has landed on main in #1614; host and Tile semver checks pass.
SIMT workflow branch filters now include stacked PRs targeting
`pull-request/<n>` prerequisite mirrors.

Follow-up validation for the host-side argument and pinned-buffer fixes:

- Both new compile-fail cases compiled before the fix and now fail
specifically because `unsafe impl` is required; snapshots were reviewed
and rerun without overwrite.
- The pinned alignment regression failed before the fix, without
constructing misaligned references. It now passes, alongside
over-aligned copying, empty/ZST coverage, and allocation-size boundary
tests.
- Full cuda-core suite: 105 passed, 3 ignored. Selected Tile
library/GPU/tensor/view suites: 168 passed, 2 ignored.
Submission-lifetime suite: all 9 passed, including forgotten borrowed
work and graph replay.
- cuda-core and cutile Clippy with warnings denied, host/Tile
formatting, and SPDX checks passed. cuda-core rustdoc with warnings
denied passed. Tile documentation builds, but its stricter
warnings-as-errors check reports 12 existing link warnings outside the
added trait documentation.

Earlier host-argument follow-up validation: the complete CPU runner
passes (1,408 tests, 98 intentionally ignored), including the Tile UI
suites. All 25 targeted GPU buffer and pinned-host-buffer tests pass,
including the cross-stream initialization regression. The branch
includes the #1602 debug-source fixes and the same version metadata as
#1614.

Current validation (2026-10-30): head
`117205c1277a9e6d422df20499342690b412bc16` includes main through
`76ac10216`. The new regression fixture compiled before the
source-validity fix, then all five trybuild cases passed afterward
without snapshot regeneration. The new-main `math_special` example
lockfile includes the host dependencies at the versions used by other
examples; the full example dependency-policy guard passes. Fresh CI is
running. GitHub dismissed the previous approval after the source
changes, and renewed review has been requested.


The expanded atomics example from current main uses owned
`wrap_elem`/`peel_elem` conversions, with explicit checked ownership
transfer for its standard-library atomic case. Strict example Clippy
passes, and all 24 runtime atomic cases pass on both this PR and the
combined shared-host stack on RTX 5090 / CUDA 13.3.


Merge-readiness refresh (2026-10-30): head
`c5ea583c5b5f06b424a9ab0c48174c771e99ff52` includes main through the
merged #1480 (`b025a8b31`). The only manual conflict resolution
preserved both changelog entries; source and tests from #1480 merged
unchanged. The combined release candidate has an identical source/test
tree to previously validated `c6c5a860a` (only the changelog and merge
ancestry changed). New-head CI is running. Merge #1516 into main first,
then retarget #1603 to main and merge it, then retarget #1604 to main
and merge it. Do not merge the children into the temporary
`pull-request/*` bases. Issue/release inclusion tracking: #1606.

---------

Signed-off-by: Melih Elibol <1884921+elibol@users.noreply.github.com>
Co-authored-by: Melih Elibol <1884921+elibol@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant