tracel-ai/burn · error

Data type mismatch

Error message

Data type mismatch

What it means

The module_op! macro matches the tensor dtype variants F32 then F64; if the underlying NdArrayTensor is neither (i.e. an int/bool tensor was passed to a float module op), the wildcard arm panics with 'Data type mismatch'. Module ops like conv2d/interpolate are float-only.

Source

Thrown at crates/burn-ndarray/src/ops/module.rs:49

    // Converts NdArrayStorage to SharedArray for compatibility with existing operations.
    (inp($($x:tt),+), opt($($opt:tt),*), $element:ident, $op:expr) => {{
        #[allow(unused_parens, unreachable_patterns)]
        match ($($x),+) {
            ($(NdArrayTensor::F32($x)),+) => {
                type $element = f32;
                $op(
                    $($x.into_shared()),+
                    $(, $opt.map(|o| match o { NdArrayTensor::F32(val) => val.into_shared(), _ => panic!("Optional argument type mismatch") }))*
                )
            }
            ($(NdArrayTensor::F64($x)),+) => {
                type $element = f64;
                $op(
                    $($x.into_shared()),+
                    $(, $opt.map(|o| match o { NdArrayTensor::F64(val) => val.into_shared(), _ => panic!("Optional argument type mismatch") }))*
                )
            }
            _ => panic!("Data type mismatch"),
        }
    }};
}

impl ModuleOps<Self> for NdArray {
    fn conv2d(
        x: NdArrayTensor,
        weight: NdArrayTensor,
        bias: Option<NdArrayTensor>,
        options: ConvOptions<2>,
    ) -> NdArrayTensor {
        let (x, options) = pad_asymmetric_conv_input::<NdArray, 2>(x, options);
        module_op!(inp(x, weight), opt(bias), E, |x, weight, bias| {
            #[cfg(feature = "simd")]
            let (x, weight, bias) = match try_conv2d_simd(x, weight, bias, options.clone()) {
                Ok(out) => return out.into(),
                Err(args) => args,
            };

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Ensure the input is a float tensor: cast with tensor.cast::<f32>() (or the backend's float element type) before the module op.
  2. Check the element type parameter of your Tensor<Backend, D> — module ops require E: Float.
  3. Convert int outputs (argmax, etc.) to float before feeding back into conv/pool layers.
  4. Add explicit float type annotations on tensors passed to module ops.

Example fix

// before
let x = logits.argmax(1); // int tensor
let y = conv2d(x, weight, None, options); // panic: Data type mismatch
// after
let xf = x.cast::<f32>();
let y = conv2d(xf, weight, None, options);
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_float_input<E: burn::tensor::Float>(t: &Tensor<NdArray<E>, D>) { /* compile-time: E: Float bound excludes ints */ }

Type guard

// enforce at type level: only accept tensors with a Float element type
fn conv_input<E: burn::tensor::element::Float>(x: Tensor<NdArray<E>, 3>) -> Tensor<NdArray<E>, 3> { x }

Prevention

When it happens

Trigger: Passing an integer or bool tensor to a module op such as conv2d, pool2d, or interpolate; a generic function that lost its float element-type bound and received an int tensor.

Common situations: Using int tensors from argmax/argwhere output directly in conv/pool ops; forgetting to convert embeddings/indices back to float; generic code without the Float element-type bound.

Related errors


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