Skip to content

fix(cutile-compiler): preserve unsigned integer literal ranges - #1557

Open
robertream wants to merge 1 commit into
NVIDIA:mainfrom
robertream:fix/int-literal-encoding
Open

robertream wants to merge 1 commit into
NVIDIA:mainfrom
robertream:fix/int-literal-encoding

Conversation

@robertream

@robertream robertream commented Oct 20, 2026 •

Copy link
Copy Markdown

Summary

32-bit and 64-bit integer constants are encoded using the full signed/unsigned range of their Tile IR width. Invalid or unparsable integer literals now return an error instead of silently becoming zero.

Why

Tile IR erases integer signedness. Previously, 32-bit values were parsed via i32 and 64-bit values via i64, so values above the signed maximum—including high-bit u32 values used by unsigned atomic comparisons—were encoded as zero. The same fallback affected hexadecimal spellings produced for named constants.

Changes

  • Parse decimal and hexadecimal integer spellings through a width-independent signed representation.
  • Accept the complete signed/unsigned range for 32-bit and 64-bit elements.
  • Preserve the low bytes in the emitted little-endian constant data.
  • Surface invalid literals at their source span.

Tests

  • Unit coverage for signed/unsigned boundaries, high-bit values, hexadecimal spellings, and rejection of invalid input.
  • Compile-only integration coverage asserting 0x8000_0010u32 reaches the IR constant pool byte-for-byte.

I used an AI assistant (Claude) to write and check this change. I reviewed the diff and validated it.

@copy-pr-bot

copy-pr-bot Bot commented Oct 20, 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.

@robertream
robertream marked this pull request as ready for review October 20, 2026 04:52
@robertream
robertream requested a review from elibol as a code owner October 20, 2026 04:52
robertream added a commit to robertream/cuda-rust that referenced this pull request Oct 20, 2026
Adds typed atomic aggregation capabilities with compile-time operation and element validation, launch-time alias checks, and compile-only and GPU test coverage.

Depends on NVIDIA#1557 (fix/cutile-compiler: preserve unsigned integer literal ranges).

Storage identity is opaque: `Tensor::storage_id`, the stored-binding
traits, and `validate_binding_aliases` carry a `StorageId` (equality is its
whole public surface) rather than a bare `usize` address.

Signed-off-by: Robert Ream <[email protected]>
robertream added a commit to robertream/cuda-rust that referenced this pull request Oct 20, 2026
Adds typed atomic aggregation capabilities with compile-time operation and element validation, launch-time alias checks, and compile-only and GPU test coverage.

Depends on NVIDIA#1557 (fix/cutile-compiler: preserve unsigned integer literal ranges).

Storage identity is opaque: `Tensor::storage_id`, the stored-binding
traits, and `validate_binding_aliases` carry a `StorageId` (equality is its
whole public surface) rather than a bare `usize` address.

Signed-off-by: Robert Ream <[email protected]>
robertream added a commit to robertream/cuda-rust that referenced this pull request Oct 20, 2026
Adds typed atomic aggregation capabilities with compile-time operation and element validation, launch-time alias checks, and compile-only and GPU test coverage.

Depends on NVIDIA#1557 (fix/cutile-compiler: preserve unsigned integer literal ranges).

Storage identity is opaque: `Tensor::storage_id`, the stored-binding
traits, and `validate_binding_aliases` carry a `StorageId` (equality is its
whole public surface) rather than a bare `usize` address.

Signed-off-by: Robert Ream <[email protected]>
robertream added a commit to robertream/cuda-rust that referenced this pull request Oct 20, 2026
Adds typed atomic aggregation capabilities with compile-time operation and element validation, launch-time alias checks, and compile-only and GPU test coverage.

Depends on NVIDIA#1557 (fix/cutile-compiler: preserve unsigned integer literal ranges).

Storage identity is opaque: `Tensor::storage_id`, the stored-binding
traits, and `validate_binding_aliases` carry a `StorageId` (equality is its
whole public surface) rather than a bare `usize` address.

Signed-off-by: Robert Ream <[email protected]>
robertream added a commit to robertream/cuda-rust that referenced this pull request Oct 20, 2026
Adds typed atomic aggregation capabilities with compile-time operation and element validation, launch-time alias checks, and compile-only and GPU test coverage.

Depends on NVIDIA#1557 (fix/cutile-compiler: preserve unsigned integer literal ranges).

Storage identity is opaque: `Tensor::storage_id`, the stored-binding
traits, and `validate_binding_aliases` carry a `StorageId` (equality is its
whole public surface) rather than a bare `usize` address.

Signed-off-by: Robert Ream <[email protected]>
…nt encoding

`encode_literal_bytes` silently produced wrong constant bytes for two whole
classes of literal, each found when a real GPU run returned wrong data.

Integer literals above the signed maximum. Every 32-bit literal was parsed
through `i32` and every 64-bit one through `i64`, with a silent `unwrap_or(0)`
on failure. The Tile IR scalar is signedness-erased, so a `u32` element
shares the 32-bit slot, and `constant(0x8000_0010u32, ..)` quietly became
zero in the constant pool; the same default zeroed the named-constant path
for integers, since `T::ONE` arrives spelled `0x1`. Each width now accepts
the union of its signed and unsigned ranges from decimal or `0x` hex, and a
literal that does not fit or does not parse is an error naming it.

16-bit floating-point constants. The named-constant path spells `T::ONE` as
raw-bits hex, and the decoder chose the bit layout by string length, so every
4-digit spelling decoded as `f16`; `bf16::ONE` (`0x3f80`) read through the
`f16` layout is 1.875, which every `constant(bf16::ONE, ..)` kernel added on
the device. The `f16` and `bf16` arms now decode a hex spelling through their
own target's bit layout; decimal spellings are unchanged.

`encode_literal_bytes` and `build_constant_op` return `Result`, and the three
call sites surface the error at the literal's span. Unit tests pin the exact
little-endian bytes at both integer widths' boundaries and both 16-bit float
types' 1.0 patterns, through decimal and hex, and the by-name rejection of
out-of-range and unparsable literals.

Signed-off-by: Robert Ream <[email protected]>
@robertream
robertream force-pushed the fix/int-literal-encoding branch from 6694792 to 35547ba Compare October 21, 2026 00:04
robertream added a commit to robertream/cuda-rust that referenced this pull request Oct 21, 2026
Adds typed atomic aggregation capabilities with compile-time operation and element validation, launch-time alias checks, and compile-only and GPU test coverage.

Depends on NVIDIA#1557 (fix/cutile-compiler: preserve unsigned integer literal ranges).

Storage identity is opaque: `Tensor::storage_id`, the stored-binding
traits, and `validate_binding_aliases` carry a `StorageId` (equality is its
whole public surface) rather than a bare `usize` address.



Library kernels built on these capabilities live in `cutile-kernels`:
`scatter_add_f32`, `embedding_backward_scatter_add_f32`, `segment_sum_f32`,
`histogram_u32`, `weighted_histogram_f32`, `max_reduce_i32`/`max_reduce_u32`
(the element selects the signed/unsigned comparison, and `reduce_max` carries
the same signedness, pinned by a regression test), and `bitmask_or_u32`. Each
takes ordinary tensor inputs and a matching aggregation destination; compile-
only tests assert the emitted mode per operation and element, host references
cover the edge cases, and device tests compare against them.

GPU correctness of the unsigned-comparison and bf16/64-bit-constant cells
depends on the literal-encoding fixes (PR NVIDIA#1557); the combined tree passed
20/20 required tests on an H100 (sm_90).

Signed-off-by: Robert Ream <[email protected]>
robertream added a commit to robertream/cuda-rust that referenced this pull request Oct 21, 2026
Adds typed atomic aggregation capabilities with compile-time operation and element validation, launch-time alias checks, and compile-only and GPU test coverage.

Depends on NVIDIA#1557 (fix/cutile-compiler: preserve unsigned integer literal ranges).

Storage identity is opaque: `Tensor::storage_id`, the stored-binding
traits, and `validate_binding_aliases` carry a `StorageId` (equality is its
whole public surface) rather than a bare `usize` address.

Library kernels built on these capabilities live in `cutile-kernels`,
generic over the element wherever the added value comes from an input
(`scatter_add`, `embedding_backward_scatter_add`, `segment_sum`,
`weighted_histogram` over `AtomicAdd`; `max_reduce` over `AtomicOrd` with the
element selecting signed vs unsigned for both the intra-tile reduction and
the atomic; `bitmask_or` over `AtomicBitwise`).
Compile-only tests drive each kernel across its whole element set asserting
the emitted mode per pair, host references cover the edge cases, and device
tests compare against them.

GPU correctness of the unsigned-comparison and bf16/64-bit-constant cells
depends on the literal-encoding fixes (PR NVIDIA#1557); the combined tree passed
20/20 required tests on an H100 (sm_90).

`ElementType` gains a `ONE` constant, so every kernel is generic over
its element, `histogram` included (its increment is `E::ONE` materialized
on-device).

Signed-off-by: Robert Ream <[email protected]>
robertream added a commit to robertream/cuda-rust that referenced this pull request Oct 21, 2026
Adds typed atomic aggregation capabilities with compile-time operation and element validation, launch-time alias checks, and compile-only and GPU test coverage.

Depends on NVIDIA#1557 (fix/cutile-compiler: preserve unsigned integer literal ranges).

Storage identity is opaque: `Tensor::storage_id`, the stored-binding
traits, and `validate_binding_aliases` carry a `StorageId` (equality is its
whole public surface) rather than a bare `usize` address.

Library kernels built on these capabilities live in `cutile-kernels`,
generic over the element wherever the added value comes from an input
(`scatter_add`, `embedding_backward_scatter_add`, `segment_sum`,
`weighted_histogram` over `AtomicAdd`; `max_reduce` over `AtomicOrd` with the
element selecting signed vs unsigned for both the intra-tile reduction and
the atomic; `bitmask_or` over `AtomicBitwise`).
Compile-only tests drive each kernel across its whole element set asserting
the emitted mode per pair, host references cover the edge cases, and device
tests compare against them.

GPU correctness of the unsigned-comparison and bf16/64-bit-constant cells
depends on the literal-encoding fixes (PR NVIDIA#1557); the combined tree passed
20/20 required tests on an H100 (sm_90).

`ElementType` gains a `ONE` constant, so every kernel is generic over
its element, `histogram` included (its increment is `E::ONE` materialized
on-device).

Signed-off-by: Robert Ream <[email protected]>

This branch has not been deployed

No deployments
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