{"record":{"id":"54e15b1cc4e7e023","repo":"tracel-ai/burn","slug":"binary-op-unsupported-dtype","errorCode":null,"errorMessage":"binary_op: unsupported dtype {:?}","messagePattern":"binary_op: unsupported dtype (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-flex/src/ops/binary.rs","lineNumber":57,"sourceCode":"    F64Op: Fn(f64, f64) -> f64 + Copy,\n{\n    debug_assert_eq!(lhs.dtype(), rhs.dtype(), \"binary_op: dtype mismatch\");\n\n    // Broadcast tensors to the same shape if needed\n    let (lhs, rhs) = crate::ops::expand::broadcast_binary(lhs, rhs);\n\n    let dtype = lhs.dtype();\n\n    match dtype {\n        DType::F32 => binary_op_f32(lhs, rhs, f32_op, simd_hint),\n        DType::F64 => binary_op_typed(lhs, rhs, f64_op),\n        DType::F16 => binary_op_typed(lhs, rhs, |a: f16, b: f16| {\n            f16::from_f32(f32_op(a.to_f32(), b.to_f32()))\n        }),\n        DType::BF16 => binary_op_typed(lhs, rhs, |a: bf16, b: bf16| {\n            bf16::from_f32(f32_op(a.to_f32(), b.to_f32()))\n        }),\n        _ => panic!(\"binary_op: unsupported dtype {:?}\", dtype),\n    }\n}\n\n/// Specialized binary operation for f32 with SIMD fast path.\n#[cfg(feature = \"simd\")]\nfn binary_op_f32<Op>(\n    mut lhs: FlexTensor,\n    mut rhs: FlexTensor,\n    op: Op,\n    simd_hint: Option<BinaryOp>,\n) -> FlexTensor\nwhere\n    Op: Fn(f32, f32) -> f32,\n{\n    // In-place SIMD fast path: lhs unique contiguous at offset 0, rhs\n    // contiguous (no broadcast).\n    if let Some(simd_op) = simd_hint\n        && lhs.is_unique()","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-flex/src/ops/binary.rs#L39-L75","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlet y = x * mask; // x: F32, mask: Bool -> binary_op panic\n// after\nlet y = x.mul(mask.cast(DType::F32));","handlingStrategy":"type-guard","validationCode":"if lhs.dtype() != rhs.dtype() || !matches!(lhs.dtype(), DType::F32 | DType::F64 | DType::F16 | DType::BF16) {\n    lhs = lhs.cast(DType::F32);\n    rhs = rhs.cast(DType::F32);\n}","typeGuard":"fn is_float_dtype(d: DType) -> bool {\n    matches!(d, DType::F32 | DType::F64 | DType::F16 | DType::BF16)\n}","tryCatchPattern":"let y = std::panic::catch_unwind(|| binary_add(lhs.clone(), rhs.clone()))\n    .unwrap_or_else(|_| binary_add(lhs.cast(DType::F32), rhs.cast(DType::F32)));","preventionTips":["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."],"tags":["panic","dtype","binary-op","unsupported-dtype"],"backgroundTag":"unsupported-dtype","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}