tracel-ai/burn · error
binary_op: unsupported dtype {:?}
Error message
binary_op: unsupported dtype {:?} What it means
binary_op in burn-flex applies an elementwise float op by dispatching on dtype; it supports F32 (with a SIMD fast path), F64, F16 and BF16 (via f32 round-trip) and panics on anything else. Public and used by both user code and backward-pass ops like relu_backward, gelu_backward and sigmoid_backward, so a wrongly-typed gradient tensor will panic here too.
Source
Thrown at crates/burn-flex/src/ops/binary.rs:57
F64Op: Fn(f64, f64) -> f64 + Copy,
{
debug_assert_eq!(lhs.dtype(), rhs.dtype(), "binary_op: dtype mismatch");
// Broadcast tensors to the same shape if needed
let (lhs, rhs) = crate::ops::expand::broadcast_binary(lhs, rhs);
let dtype = lhs.dtype();
match dtype {
DType::F32 => binary_op_f32(lhs, rhs, f32_op, simd_hint),
DType::F64 => binary_op_typed(lhs, rhs, f64_op),
DType::F16 => binary_op_typed(lhs, rhs, |a: f16, b: f16| {
f16::from_f32(f32_op(a.to_f32(), b.to_f32()))
}),
DType::BF16 => binary_op_typed(lhs, rhs, |a: bf16, b: bf16| {
bf16::from_f32(f32_op(a.to_f32(), b.to_f32()))
}),
_ => panic!("binary_op: unsupported dtype {:?}", dtype),
}
}
/// Specialized binary operation for f32 with SIMD fast path.
#[cfg(feature = "simd")]
fn binary_op_f32<Op>(
mut lhs: FlexTensor,
mut rhs: FlexTensor,
op: Op,
simd_hint: Option<BinaryOp>,
) -> FlexTensor
where
Op: Fn(f32, f32) -> f32,
{
// In-place SIMD fast path: lhs unique contiguous at offset 0, rhs
// contiguous (no broadcast).
if let Some(simd_op) = simd_hint
&& lhs.is_unique()View on GitHub (pinned to d16f7ba2ed)
Solutions
- Cast both operands to the same float dtype before the op: a.cast(DType::F32).op(b.cast(DType::F32)).
- Fix the producing op so the tensor is float before it reaches the binary op or its backward.
- For masks, use float masks (mask.cast(DType::F32)) or a dedicated where/select op instead of arithmetic.
Example fix
// before let y = x * mask; // x: F32, mask: Bool -> binary_op panic // after let y = x.mul(mask.cast(DType::F32));
Defensive patterns
Strategy: type-guard
Validate before calling
if lhs.dtype() != rhs.dtype() || !matches!(lhs.dtype(), DType::F32 | DType::F64 | DType::F16 | DType::BF16) {
lhs = lhs.cast(DType::F32);
rhs = rhs.cast(DType::F32);
} Type guard
fn is_float_dtype(d: DType) -> bool {
matches!(d, DType::F32 | DType::F64 | DType::F16 | DType::BF16)
} Try / catch
let y = std::panic::catch_unwind(|| binary_add(lhs.clone(), rhs.clone()))
.unwrap_or_else(|_| binary_add(lhs.cast(DType::F32), rhs.cast(DType::F32))); Prevention
- Cast bool masks to float before arithmetic.
- Never rely on implicit type promotion — burn-flex has none.
- Check dtypes after every cast-producing op in the pipeline.
- Use binary_op only for float tensors; use int_binary_op for ints.
When it happens
Trigger: Any float binary op (add/sub/mul/div on float tensors) with a non-float dtype; backward passes (relu_backward, gelu_backward, sigmoid_backward, log_sigmoid_backward, prelu) receiving integer or bool tensors; test helper test_binary_add_f16 with an exotic dtype.
Common situations: Bool mask multiplied with float activations without casting; integer features fed into an activation with a float sibling; autodiff gradient produced with mismatched dtype; PyTorch-style implicit type promotion expectations that Rust burn does not perform.
Related errors
- int_binary_op: unsupported dtype {:?}
- softmax: unsupported dtype {:?}
- burn_flex::layer_norm: unsupported dtype {:?}
- attention: unsupported dtype {:?}
- scalar_op: unsupported dtype {:?}
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/54e15b1cc4e7e023.
Report an issue: GitHub.