tracel-ai/burn · error
Incompatible shapes for broadcasting: {:?} and {:?}
Error message
Incompatible shapes for broadcasting: {:?} and {:?} What it means
When preparing a binary elementwise op, both operands are broadcast to a common shape. Broadcasting fails when, at some trailing-aligned dimension, neither side is 1 and the two dimensions differ. The backend panics with the two incompatible shapes.
Source
Thrown at crates/burn-ndarray/src/ops/base.rs:824
let lhs_dim = if i < lhs_shape.len() {
lhs_shape[lhs_shape.len() - 1 - i]
} else {
1
};
let rhs_dim = if i < rhs_shape.len() {
rhs_shape[rhs_shape.len() - 1 - i]
} else {
1
};
if lhs_dim == rhs_dim {
broadcast_shape[ndims - 1 - i] = lhs_dim;
} 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)View on GitHub (pinned to d16f7ba2ed)
Solutions
- Reshape/unsqueeze the smaller tensor so its dimensions align with broadcast rules (trailing dimensions must be equal or 1).
- Expand one operand explicitly to the target shape before the op.
- Fix the pipeline so both operands are produced with compatible shapes.
- Print lhs.dims() and rhs.dims() and verify each trailing dimension pair is equal or one of them is 1.
Example fix
// before let a = Tensor::<_,_,NdArray>::zeros([3, 4], &device); let b = Tensor::zeros([5, 4], &device); let c = a.greater(b); // after let b = Tensor::zeros([1, 4], &device).repeat(0, 3); // or fix dims to [3,4] let c = a.greater(b);
Defensive patterns
Strategy: validation
Validate before calling
fn can_broadcast(a: &[usize], b: &[usize]) -> bool {
a.iter().rev().zip(b.iter().rev()).all(|(x, y)| x == y || *x == 1 || *y == 1)
}
assert!(can_broadcast(&lhs.dims(), &rhs.dims())); Type guard
fn can_broadcast(a: &[usize], b: &[usize]) -> bool {
a.iter().rev().zip(b.iter().rev()).all(|(x, y)| x == y || *x == 1 || *y == 1)
} Prevention
- Follow broadcasting rules: trailing dims equal or 1
- unsqueeze/reshape to align ranks before elementwise ops
- Add shape assertions at pipeline boundaries
When it happens
Trigger: Applying elementwise ops (remainder, equal, greater, greater_equal, lower_equal, lower) on tensors whose shapes cannot be broadcast, e.g. [3, 4] vs [5, 4] or [3, 4] vs [2].
Common situations: Comparing tensors of different batch sizes; comparing a [N] tensor with a [M, N] tensor expecting implicit prepending broadcast (not supported the same way); dimension count errors from squeeze/unsqueeze omissions.
Related errors
- expand: cannot expand dimension {} from {} to {}
- Unsupported dimension, only the last dimension can differ: T
- capture tensor operations must run inside CaptureDevice::cap
- capture tensor {} has no initialized value
- seeding is not supported during graph capture
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/3a872b7fd93a3b23.
Report an issue: GitHub.