Skip to content

Rust and SPIR-V float rounding semantics are different #229

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
LegNeato opened this issue Apr 9, 2025 · 1 comment
Open

Rust and SPIR-V float rounding semantics are different #229

LegNeato opened this issue Apr 9, 2025 · 1 comment

Comments

@LegNeato
Copy link
Collaborator

LegNeato commented Apr 9, 2025

There is a footgun when trying to share code between CPU and GPU. Rust and SPIR-V have different semantics when rounding floats:

Rust:

  • Rust’s built-in conversion using as truncates the fractional part, effectively rounding toward zero.
  • For example, 1743028479.999... becomes 1743028479.
    Rust Language Reference

SPIR-V:

fn main() {
    let x = 1743028480i32;
    let y = (x as f64) * (1.0 / (i32::MAX as f64));

    // Without explicit rounding, differs:
    let without = (y * (i32::MAX as f64)) as i32;
    // Using `trunc()` forces Rust’s truncation:
    let with = (y * (i32::MAX as f64)).trunc() as i32;

    println!("x = {}. Without rounding = {}. With trunc() = {}.", x, without, with);
}

I'm not sure which should be the default. If it is Rust's we'll want to polyfill on the spir-v side. Might be good to have this user controlled in any case.

Originally posted by @LegNeato in #228 (comment)

@LegNeato
Copy link
Collaborator Author

Related:

#211

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

No branches or pull requests

1 participant