tracel-ai/burn · error

conv2d: unsupported dtype {:?}

Error message

conv2d: unsupported dtype {:?}

What it means

conv2d in the burn-flex module ops matches the input dtype against F32/F64/F16/BF16 and delegates to the corresponding typed conv kernel; any other dtype hits the catch-all panic. Conv2d requires float tensors, so integer or bool input tensors are rejected at runtime rather than at compile time, since Flex is a dynamic-dtype backend.

Source

Thrown at crates/burn-flex/src/ops/module.rs:74

            DType::F16 => conv::conv1d_f16(x, weight, bias, &options),
            DType::BF16 => conv::conv1d_bf16(x, weight, bias, &options),
            dtype => panic!("conv1d: unsupported dtype {:?}", dtype),
        }
    }

    fn conv2d(
        x: FloatTensor<Flex>,
        weight: FloatTensor<Flex>,
        bias: Option<FloatTensor<Flex>>,
        options: ConvOptions<2>,
    ) -> FloatTensor<Flex> {
        let (x, options) = pad_asymmetric_conv_input::<Flex, 2>(x, options);
        match x.dtype() {
            DType::F32 => conv::conv2d_f32(x, weight, bias, &options),
            DType::F64 => conv::conv2d_f64(x, weight, bias, &options),
            DType::F16 => conv::conv2d_f16(x, weight, bias, &options),
            DType::BF16 => conv::conv2d_bf16(x, weight, bias, &options),
            dtype => panic!("conv2d: unsupported dtype {:?}", dtype),
        }
    }

    fn deform_conv2d(
        x: FloatTensor<Flex>,
        offset: FloatTensor<Flex>,
        weight: FloatTensor<Flex>,
        mask: Option<FloatTensor<Flex>>,
        bias: Option<FloatTensor<Flex>>,
        options: DeformConvOptions<2>,
    ) -> FloatTensor<Flex> {
        match x.dtype() {
            DType::F32 => deform_conv::deform_conv2d_f32(
                x,
                offset,
                weight,
                mask,
                bias,

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Cast the image/input tensor to a float dtype before conv2d: x.cast(DType::F32).
  2. Check the dtype of both input and weight with .dtype() to locate which tensor is non-float.
  3. For quantized inference, explicitly dequantize int8 activations/weights to f32 or bf16 before the conv.
  4. If support for another dtype is genuinely needed, add the corresponding arm (e.g. conv2d_i8) in crates/burn-flex/src/ops/module.rs.

Example fix

// before
let out = model.conv2(image_u8_tensor);
// panic: conv2d: unsupported dtype U8

// after
let x = image_u8_tensor.cast(burn::tensor::DType::F32);
let out = model.conv2(x);
Defensive patterns

Strategy: validation

Validate before calling

let x = if matches!(x.dtype(), DType::F32 | DType::F64 | DType::F16 | DType::BF16) { x } else { x.cast(DType::F32) };
let out = conv2d(x, weight, bias, options);

Type guard

fn is_float(t: &Tensor<Flex>) -> bool {
    matches!(t.dtype(), DType::F32 | DType::F64 | DType::F16 | DType::BF16)
}

Try / catch

let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| conv2d(x.clone(), w.clone(), b.clone(), opts.clone())))
    .unwrap_or_else(|_| conv2d(x.cast(DType::F32), w, b, opts));

Prevention

When it happens

Trigger: Calling conv2d (directly or via a conv2d module) with an input tensor whose dtype is I8/I16/I32/I64/U8/Bool/etc.; passing quantized int8 activations into conv2d without dequantization.

Common situations: Running an int8-quantized vision model where the quantized conv node was not mapped to a dequantize-conv-requantize flow; preprocessing images as u8 tensors fed straight into the model; checkpoint dtype mismatches after format conversion.

Related errors


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