tracel-ai/burn · error

Concatenate data type mismatch (expected {:?}, got {:?})

Error message

Concatenate data type mismatch (expected {:?}, got {:?})

What it means

The ndarray concatenate macro validates each input tensor's storage variant matches the expected dtype (taken from the first tensor). If any tensor in the list has a different dtype, it panics with expected vs got dtypes.

Source

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

///
/// Uses zero-copy views from storage for concatenation.
///
/// # 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! cat_with_dtype {
    ($tensors: expr, $dim: expr, [$($dtype: ident),*]) => {
        match &$tensors[0] {
            $(NdArrayTensor::$dtype(_) => {
                let tensors = $tensors
                    .iter()
                    .map(|t| {
                        if let NdArrayTensor::$dtype(storage) = t {
                            // Use storage.view() for zero-copy access
                            storage.view()
                        } else {
                            panic!("Concatenate data type mismatch (expected {:?}, got {:?})", $tensors[0].dtype(), t.dtype())
                        }
                    })
                    .collect::<Vec<_>>();
                NdArrayOps::concatenate(&tensors, $dim).into()
            })*
            _ => panic!("Unsupported dtype: {:?}", $tensors[0].dtype())
        }
    };
}

/// Macro to execute an operation that returns a given element type.
#[macro_export]
macro_rules! execute_with_float_out_dtype {
    ($out_dtype:expr, $element:ident, $op:expr, [$($dtype: ident => $ty: ty),*]) => {{
        match $out_dtype {
            $(
                burn_std::FloatDType::$dtype => {
                    #[allow(unused)]

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Cast all tensors to the same dtype before concatenating: tensors.iter().map(|t| t.cast(DType::F32))
  2. Verify how each input tensor was created/loaded and fix the one with the wrong dtype
  3. Concatenate only tensors coming from the same backend generic parameter E

Example fix

// before
let out = Tensor::cat(vec![a_f32, b_i32], 0); // panics
// after
let out = Tensor::cat(vec![a_f32, b_i32.cast(DType::F32)], 0);
Defensive patterns

Strategy: validation

Validate before calling

let dt = tensors[0].dtype();
assert!(tensors.iter().all(|t| t.dtype() == dt), "cat requires uniform dtype");

Type guard

fn all_same_dtype<T: TensorOps>(ts: &[T]) -> bool {
    ts.iter().all(|t| t.dtype() == ts[0].dtype())
}

Prevention

When it happens

Trigger: Calling tensor.cat(tensors, dim) / NdArray::cat where the tensors in the slice have heterogeneous dtypes (e.g. mostly f32 but one i32 tensor).

Common situations: Concatenating feature tensors produced by different sub-graphs with mismatched precision; appending a placeholder tensor created from integer data; model-export bugs where one weight loads in the wrong dtype.

Related errors


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