tracel-ai/burn · error

Failed to broadcast rhs

Error message

Failed to broadcast rhs

What it means

Same as the lhs broadcast failure, but for the right-hand operand: broadcast_for_binary_ops broadcasts rhs to the merged shape and panics if ndarray's broadcast() fails. Indicates the two operands of a comparison/remainder op are not broadcast-compatible.

Source

Thrown at crates/burn-ndarray/src/ops/base.rs:840

            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>()
}

impl<E> NdArrayMathOps<E>

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Make rhs broadcastable to lhs: matching trailing dims or rhs dims of 1; add unsqueeze for rank alignment
  2. Reshape rhs explicitly before the op (e.g. [B] -> [B, 1])
  3. Fix the upstream producer of rhs so its shape matches expectations

Example fix

// before
let labels: Tensor<NdArray, 1> = ...; // [B]
let eq = logits.greater_equal(labels); // [B, C] vs [B] fine only if C aligned; e.g. [B,C] vs [C'] panics
// after
let labels2 = labels.unsqueeze(); // [B, 1]
let eq = logits.greater_equal(labels2);
Defensive patterns

Strategy: validation

Validate before calling

// ensure rhs broadcasts to lhs' shape before comparison ops
fn align_rhs(lhs_dims: &[usize], rhs: Tensor<NdArray<F>, 1>) -> Tensor<NdArray<F>, 2> {
    // e.g. [B] -> [B, 1] to compare against [B, C]
    rhs.unsqueeze()
}
// check trailing dims match or one is 1 before calling op

Prevention

When it happens

Trigger: Calling remainder, equal, greater, greater_equal, lower_equal, or lower where the rhs tensor's shape cannot be broadcast to the computed broadcast_shape (dims mismatch and rhs dim != 1, or rhs rank exceeds available dims).

Common situations: Comparing model output [B, 10] against labels [B] or [B, 8]; scalar-like tensor created with wrong shape; pipeline refactors that changed one operand's rank.

Related errors


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