tracel-ai/burn · error

Data type mismatch (lhs: {:?}, rhs: {:?})

Error message

Data type mismatch (lhs: {:?}, rhs: {:?})

What it means

A macro in burn-ndarray for binary tensor ops matches on the (lhs, rhs) dtype pair and falls through to a panic when both operands don't share a supported matching element type. Mixed-dtype arithmetic (e.g. f32 tensor + i64 tensor) is not performed implicitly.

Source

Thrown at crates/burn-ndarray/src/tensor.rs:134

///
/// # Panics
/// Since there is no automatic type cast at this time, binary operations for different
/// floating point precision data types will panic with a data type mismatch.
#[macro_export]
macro_rules! execute_with_dtype {
    (($lhs:expr, $rhs:expr),$element:ident,  $op:expr, [$($dtype: ident => $ty: ty),*]) => {{
        let lhs_dtype = burn_backend::TensorMetadata::dtype(&$lhs);
        let rhs_dtype = burn_backend::TensorMetadata::dtype(&$rhs);
        match ($lhs, $rhs) {
            $(
                ($crate::NdArrayTensor::$dtype(lhs), $crate::NdArrayTensor::$dtype(rhs)) => {
                    #[allow(unused)]
                    type $element = $ty;
                    // Convert storage to SharedArray for compatibility with existing operations
                    $op(lhs.into_shared(), rhs.into_shared()).into()
                }
            )*
            _ => panic!(
                "Data type mismatch (lhs: {:?}, rhs: {:?})",
                lhs_dtype, rhs_dtype
            ),
        }
    }};
    // Binary op: type automatically inferred by the compiler
    (($lhs:expr, $rhs:expr), $op:expr) => {{
        $crate::execute_with_dtype!(($lhs, $rhs), E, $op)
    }};

    // Binary op: generic type cannot be inferred for an operation
    (($lhs:expr, $rhs:expr), $element:ident, $op:expr) => {{
        $crate::execute_with_dtype!(($lhs, $rhs), $element, $op, [
            F64 => f64, F32 => f32,
            I64 => i64, I32 => i32, I16 => i16, I8 => i8,
            U64 => u64, U32 => u32, U16 => u16, U8 => u8,
            Bool => bool
        ])

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Cast one operand so both dtypes match: lhs.cast(DType::F32) (or rhs)
  2. Ensure model weights and activations load with the same dtype (set the generic param E of the backend accordingly)
  3. Where the API allows, use explicit numeric conversions on scalar literals so they adopt the tensor's dtype

Example fix

// before
let c = lhs + rhs; // f32 + i64 -> panic
// after
let c = lhs + rhs.cast(DType::F32);
Defensive patterns

Strategy: type-guard

Validate before calling

if lhs.dtype() != rhs.dtype() {
    return Err(...);
}

Type guard

fn same_dtype<T: TensorOps>(a: &T, b: &T) -> bool {
    a.dtype() == b.dtype()
}

Prevention

When it happens

Trigger: Any binary tensor operation (add, mul, matmul, etc.) where lhs.dtype() != rhs.dtype(), e.g. adding an f32 tensor to an i64 tensor on the ndarray backend.

Common situations: Mixing integer masks/indices with float activations; loading weights in a different precision than activations; combining a tensor created from integer data with float computation.

Related errors


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