tracel-ai/burn · error

compare: unsupported dtype {:?}

Error message

compare: unsupported dtype {:?}

What it means

compare in burn-flex performs elementwise tensor-vs-tensor comparisons (greater, greater_equal, lower, lower_equal, equal, not_equal), dispatching on the input dtype. F32 (SIMD fast path), F64, F16 and BF16 are supported; other dtypes panic. An out_dtype parameter selects the boolean output representation.

Source

Thrown at crates/burn-flex/src/ops/comparison.rs:49

    F64Cmp: Fn(f64, f64) -> bool + Copy,
{
    debug_assert_eq!(lhs.dtype(), rhs.dtype(), "compare: dtype mismatch");

    // Broadcast to same shape if needed
    let (lhs, rhs) = crate::ops::expand::broadcast_binary(lhs, rhs);

    let dtype = lhs.dtype();

    match dtype {
        DType::F32 => compare_f32(lhs, &rhs, out_dtype, f32_cmp, simd_hint),
        DType::F64 => compare_typed(lhs, &rhs, out_dtype, f64_cmp),
        DType::F16 => compare_typed(lhs, &rhs, out_dtype, |a: f16, b: f16| {
            f32_cmp(a.to_f32(), b.to_f32())
        }),
        DType::BF16 => compare_typed(lhs, &rhs, out_dtype, |a: bf16, b: bf16| {
            f32_cmp(a.to_f32(), b.to_f32())
        }),
        _ => panic!("compare: unsupported dtype {:?}", dtype),
    }
}

/// Specialized comparison for f32 with SIMD fast path.
#[cfg(feature = "simd")]
fn compare_f32<Cmp>(
    lhs: FlexTensor,
    rhs: &FlexTensor,
    out_dtype: BoolDType,
    cmp: Cmp,
    simd_hint: Option<CompareOp>,
) -> FlexTensor
where
    Cmp: Fn(f32, f32) -> bool,
{
    // SIMD fast path: both tensors contiguous
    if let (Some((l_start, l_end)), Some((r_start, r_end))) = (
        lhs.layout().contiguous_offsets(),

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Cast operands to a float dtype before comparing: a.cast(DType::F32).equal(b.cast(DType::F32)).
  2. Check for an integer/bool comparison variant in the ops module and use that instead.
  3. If comparing for exact equality on ints is intended, extend compare_typed with the needed element type instantiation.

Example fix

// before
let eq = lower(a_i64, b_i64); // panics
// after
let eq = lower(a_i64.cast(DType::F32), b_i64.cast(DType::F32));
Defensive patterns

Strategy: validation

Validate before calling

if !matches!(lhs.dtype(), DType::F32 | DType::F64 | DType::F16 | DType::BF16) {
    lhs = lhs.cast(DType::F32);
    rhs = rhs.cast(DType::F32);
}
let mask = equal(lhs, rhs, out_dtype);

Type guard

fn is_float_dtype(d: DType) -> bool {
    matches!(d, DType::F32 | DType::F64 | DType::F16 | DType::BF16)
}

Try / catch

let mask = std::panic::catch_unwind(|| equal(lhs.clone(), rhs.clone(), out_dtype))
    .unwrap_or_else(|_| equal(lhs.cast(DType::F32), rhs.cast(DType::F32), out_dtype));

Prevention

When it happens

Trigger: Calling any of greater/greater_equal/lower/lower_equal/equal/not_equal on integer, unsigned or bool tensors — the comparison entry points shown here only wire up the float branches. E.g. comparing two i64 index tensors.

Common situations: Comparing token indices or integer labels; comparing bool masks for equality; expecting PyTorch-style comparisons that accept any dtype.

Related errors


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