tracel-ai/burn · error

int_scalar_op: unsupported dtype {:?}

Error message

int_scalar_op: unsupported dtype {:?}

What it means

int_scalar_op applies a scalar i64 op to integer tensors elementwise; the scalar is truncated to the target dtype (matching PyTorch). U64/U32/U16/U8 are handled via i64 arithmetic; other dtypes (floats, bool, or unlisted signed variants) panic. It backs int_add_scalar, int_sub_scalar, int_mul_scalar, int_div_scalar, int_remainder_scalar and bitwise_and_scalar.

Source

Thrown at crates/burn-flex/src/ops/binary.rs:414

        DType::I16 => scalar_op_typed(tensor, scalar as i16, |a: i16, b: i16| {
            op(a as i64, b as i64) as i16
        }),
        DType::I8 => scalar_op_typed(tensor, scalar as i8, |a: i8, b: i8| {
            op(a as i64, b as i64) as i8
        }),
        DType::U64 => scalar_op_typed(tensor, scalar as u64, |a: u64, b: u64| {
            op(a as i64, b as i64) as u64
        }),
        DType::U32 => scalar_op_typed(tensor, scalar as u32, |a: u32, b: u32| {
            op(a as i64, b as i64) as u32
        }),
        DType::U16 => scalar_op_typed(tensor, scalar as u16, |a: u16, b: u16| {
            op(a as i64, b as i64) as u16
        }),
        DType::U8 => scalar_op_typed(tensor, scalar as u8, |a: u8, b: u8| {
            op(a as i64, b as i64) as u8
        }),
        _ => panic!("int_scalar_op: unsupported dtype {:?}", dtype),
    }
}

// Tests kept here exercise flex-specific behavior of `binary_op` /
// `scalar_op`: non-contiguous (transposed/narrowed/permuted) strides,
// flex f16/bf16 half-precision storage paths, and broadcast patterns
// that probe the flex layout system. Plain contiguous add/sub/mul/div
// and scalar-op smoke tests have been dropped in favor of the
// equivalent coverage in burn-backend-tests, which exercises every
// backend. When adding new tests, keep them here only if they probe
// flex-internal dispatch; otherwise add them to
// crates/burn-backend-tests/tests/tensor/float/ops/.
#[cfg(test)]
#[allow(clippy::needless_range_loop)]
mod tests {
    use super::*;
    use alloc::vec;
    use burn_backend::{TensorData, Tolerance};

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. For float tensors use scalar_op / float_add_scalar instead: float_add_scalar(tensor, s).
  2. Cast Bool to an integer dtype first: tensor.cast(DType::U8) then apply the int scalar op.
  3. Verify the tensor's dtype with tensor.dtype() and route to the correct scalar-op family.

Example fix

// before
let y = int_add_scalar(x_f32, 3); // panics
// after
let y = float_add_scalar(x_f32, 3.0);
Defensive patterns

Strategy: validation

Validate before calling

if !matches!(tensor.dtype(), DType::U64 | DType::U32 | DType::U16 | DType::U8 | DType::I64 | DType::I32) {
    tensor = tensor.cast(DType::I64);
}
let y = int_add_scalar(tensor, s);

Type guard

fn is_supported_int(d: DType) -> bool {
    matches!(d, DType::U64 | DType::U32 | DType::U16 | DType::U8 | DType::I64 | DType::I32)
}

Try / catch

let y = std::panic::catch_unwind(|| int_add_scalar(tensor.clone(), s))
    .unwrap_or_else(|_| int_add_scalar(tensor.cast(DType::I64), s));

Prevention

When it happens

Trigger: Calling any int_*_scalar op on a float tensor, a Bool tensor, or a signed dtype not covered by the match (e.g. passing through with a dtype the dispatch never listed). Common when a scalar bias is applied to float data using the int entry point by mistake.

Common situations: Applying integer offsets to float feature tensors; bool flags combined with scalar bit masks; migrating PyTorch code relying on implicit type promotion.

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/2d130b7f33a67494. Report an issue: GitHub.