tracel-ai/burn · error

expand: cannot expand dimension {} from {} to {}

Error message

expand: cannot expand dimension {} from {} to {}

What it means

The flex backend's expand (broadcast) op can only grow a dimension whose source size is 1, or keep a dimension whose size already equals the target. If a source dimension has size >1 and differs from the requested target size, no valid stride can describe the result, so the backend panics. This is a shape/broadcastability violation caught at layout-construction time.

Source

Thrown at crates/burn-flex/src/ops/expand.rs:121

    for i in 0..target_ndims {
        let target_dim = target_shape[i];

        if i < dim_diff {
            // New dimension prepended - must be broadcastable from size 1
            new_strides.push(0);
        } else {
            let src_idx = i - dim_diff;
            let src_dim = src_dims[src_idx];
            let src_stride = src_strides[src_idx];

            if src_dim == target_dim {
                // Same size - keep stride
                new_strides.push(src_stride);
            } else if src_dim == 1 {
                // Broadcast dimension - stride becomes 0
                new_strides.push(0);
            } else {
                panic!(
                    "expand: cannot expand dimension {} from {} to {}",
                    i, src_dim, target_dim
                );
            }
        }
    }

    let new_layout = Layout::new(target_shape, new_strides, start_offset);
    FlexTensor::from_arc(tensor.data_arc(), new_layout, dtype)
}

// Tests kept here probe flex-internal expand behavior: stride metadata
// (stride 0 on broadcast dims, preservation of negative strides on
// flipped inputs, preserved start-offset on narrowed inputs) and the
// flex-only `broadcast_binary` helper. Public-API expand coverage for
// transpose/flip/narrow variants lives in
// crates/burn-backend-tests/tests/tensor/{float,int,bool}/ops/expand.rs
// so it runs on every backend.

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Check the source tensor's shape with tensor.shape() and confirm every dimension is either equal to the target or of size 1
  2. Fix the target shape so it only prepends new dimensions or grows size-1 dimensions (proper broadcasting)
  3. If you need arbitrary resizing, use an actual resize op (interpolate/upsample) or slice+concat, not expand
  4. Verify the input tensor wasn't produced by an upstream op with an unexpected shape (log shapes before expand)

Example fix

// before: src [4, 2], target [4, 3] -> panic
let out = x.expand([4, 3]);
// after: broadcast only size-1 or matching dims
let x = x.unsqueeze::<2>(); // e.g. [4, 2, 1]
let out = x.expand([4, 2, 3]); // dim of size 1 grows to 3
Defensive patterns

Strategy: validation

Validate before calling

fn assert_broadcastable(src: &[usize], target: &[usize]) -> Result<(), String> {
    if target.len() < src.len() {
        return Err(format!("target rank {} < source rank {}", target.len(), src.len()));
    }
    let skip = target.len() - src.len();
    for (i, (&s, &t)) in src.iter().zip(&target[skip..]).enumerate() {
        if s != t && s != 1 {
            return Err(format!("dim {} (size {}) cannot expand to {}", i, s, t));
        }
    }
    Ok(())
}

Type guard

fn can_expand(src_dim: usize, target_dim: usize) -> bool {
    src_dim == target_dim || src_dim == 1
}

Prevention

When it happens

Trigger: Calling tensor.expand/expand_to (or any broadcasting binary op that routes through expand) with a target shape where an existing dimension of size N>1 is expected to become M, with M != N. E.g. expanding [4, 1] to [4, 3] is fine, but [4, 2] to [4, 3] panics.

Common situations: Manually computed target shapes that don't match the actual input shape (off-by-one or stale constant); mixing tensors whose shapes changed upstream; NumPy-style broadcasting assumptions applied in reverse (expand cannot shrink or resize); feeding a tensor of batch size B into a layer hard-coded for a different batch.

Related errors


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