tracel-ai/burn · error
Failed to broadcast lhs
Error message
Failed to broadcast lhs
What it means
broadcast_for_binary_ops aligns two tensors for elementwise comparison/remainder ops by broadcasting the left-hand array to the merged shape. If lhs cannot be broadcast to that shape (its trailing dims neither match nor are 1), ndarray returns Err and this expect() panics.
Source
Thrown at crates/burn-ndarray/src/ops/base.rs:837
} else if lhs_dim == 1 {
broadcast_shape[ndims - 1 - i] = rhs_dim;
} else if rhs_dim == 1 {
broadcast_shape[ndims - 1 - i] = lhs_dim;
} else {
panic!(
"Incompatible shapes for broadcasting: {:?} and {:?}",
lhs_shape, rhs_shape
);
}
}
// Create IxDyn from broadcast shape
let broadcast_dim = ndarray::IxDyn(&broadcast_shape);
// Broadcast both arrays
let lhs_broadcast = lhs
.broadcast(broadcast_dim.clone())
.expect("Failed to broadcast lhs");
let rhs_broadcast = rhs
.broadcast(broadcast_dim)
.expect("Failed to broadcast rhs");
(lhs_broadcast, rhs_broadcast)
}
/// The mean of zero elements, which is `0 / 0`.
///
/// `NaN` for a float, matching numpy and torch. Integers have no such value, so an integer mean of
/// nothing is rejected rather than silently reported as some other number.
pub(crate) fn empty_mean<E: NdArrayElement>() -> E {
assert!(
E::dtype().is_float(),
"Cannot compute mean of empty tensor for the integer type {:?}",
E::dtype()
);
0.elem::<E>() / 0.elem::<E>()View on GitHub (pinned to d16f7ba2ed)
Solutions
- Print/check both tensor dims and make them broadcastable: equal dims, or one side's dim == 1 (right-aligned)
- Insert reshape/expand or squeeze/unsqueeze so ranks align before the comparison
- Fix upstream ops (cat, slice, reshape) that produced divergent shapes
Example fix
// before let a: Tensor<NdArray, 2> = ...; // [2, 3] let b: Tensor<NdArray, 2> = ...; // [4, 3] let eq = a.equal(b); // panic // after let a2 = a.reshape([1, 2, 3]); let eq = a2.equal(b.reshape([1, 4, 3]).transpose()); // make shapes align/broadcastable
Defensive patterns
Strategy: validation
Validate before calling
fn broadcastable(a: &[usize], b: &[usize]) -> bool {
let n = a.len().max(b.len());
(0..n).all(|i| {
let da = a.get(a.len().checked_sub(1 + i).unwrap_or(usize::MAX)).copied();
let db = b.get(b.len().checked_sub(1 + i).unwrap_or(usize::MAX)).copied();
match (da, db) { (Some(x), Some(y)) => x == y || x == 1 || y == 1, _ => true }
})
}
// assert!(broadcastable(&lhs.dims(), &rhs.dims())); Prevention
- Check both operand dims before equal/greater/lower/remainder ops
- Use unsqueeze/reshape to align ranks when comparing tensors from different branches
- Watch for batch/spatial dims diverging after slice/cat in dual-branch models
- Log shapes at comparison sites during development
When it happens
Trigger: Calling remainder, equal, greater, greater_equal, lower_equal or lower on tensors whose shapes are not broadcastable - e.g. [2, 3] vs [4, 3], or trailing dims that don't match and neither side is 1.
Common situations: Comparing tensors from different pipeline branches whose batch/spatial dims diverged; comparing [N] with [M]; a reshape dropped/changed a dim upstream so comparison operands no longer align.
Related errors
- Failed to broadcast rhs
- The shapes should be broadcastable
- broadcast_shape: incompatible dimensions {} and {} at positi
- Broadcast arguments must be greater than the number of dimen
- Broadcast arguments must be positive or -1! Got {}
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/6e96ccfb47fbb376.
Report an issue: GitHub.