{"record":{"id":"c9da79987221f8d8","repo":"tracel-ai/burn","slug":"the-shapes-should-be-broadcastable","errorCode":null,"errorMessage":"The shapes should be broadcastable","messagePattern":"The shapes should be broadcastable","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-ndarray/src/ops/base.rs","lineNumber":554,"sourceCode":"\n        slices\n    }\n\n    pub fn swap_dims(mut tensor: SharedArray<E>, dim1: usize, dim2: usize) -> SharedArray<E> {\n        tensor.swap_axes(dim1, dim2);\n\n        tensor\n    }\n\n    pub fn permute(tensor: SharedArray<E>, axes: &[usize]) -> SharedArray<E> {\n        tensor.permuted_axes(axes.into_dimension())\n    }\n\n    /// Broadcasts the tensor to the given shape\n    pub(crate) fn expand(tensor: SharedArray<E>, shape: Shape) -> SharedArray<E> {\n        tensor\n            .broadcast(shape.into_dimension())\n            .expect(\"The shapes should be broadcastable\")\n            // need to convert view to owned array because NdArrayTensor expects owned array\n            // and try_into_owned_nocopy() panics for broadcasted arrays (zero strides)\n            .into_owned()\n            .into_shared()\n    }\n\n    pub fn flip(tensor: SharedArray<E>, axes: &[usize]) -> SharedArray<E> {\n        let slice_items: Vec<_> = (0..tensor.shape().num_dims())\n            .map(|i| {\n                if axes.contains(&i) {\n                    SliceInfoElem::Slice {\n                        start: 0,\n                        end: None,\n                        step: -1,\n                    }\n                } else {\n                    SliceInfoElem::Slice {\n                        start: 0,","sourceCodeStart":536,"sourceCodeEnd":572,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-ndarray/src/ops/base.rs#L536-L572","documentation":"expand broadcasts a tensor to a target shape using ndarray's broadcast(), which only succeeds when each target dimension equals the source dimension or is 1-expandable (source dim is 1, or the dim is prepended). If the given shape is incompatible, ndarray returns Err and this expect() panics.","triggerScenarios":"Calling Tensor::expand / Tensor::repeat with a shape whose trailing dims don't match the source (source dim != 1 and != target dim), or a target shape with fewer dims than the source tensor.","commonSituations":"Hard-coded expand shapes that assume a different input rank (e.g. after a squeeze/reshape change); expanding a [B, C, H, W] tensor to [B, C', H, W] where C' != C and C != 1; ONNX Expand nodes with mismatched shape inputs.","solutions":["Ensure each source dim is either 1 or equal to the corresponding target dim (right-aligned), and target rank >= source rank","Check the rank of the input at runtime; reshape/insert dims before expanding","Use repeat(dim, n) for cases where you want to replicate along one axis of an existing dim"],"exampleFix":"// before\nlet x: Tensor<NdArray, 2> = ...; // dims [3, 1]\nx.expand([2, 5]); // 3 != 5 -> panic\n// after\nlet x: Tensor<NdArray, 2> = ...; // dims [3, 1]\nx.expand([3, 5]); // leading dims must match or be 1","handlingStrategy":"validation","validationCode":"fn can_broadcast_to(src: &[usize], dst: &[usize]) -> bool {\n    dst.len() >= src.len()\n        && dst[dst.len()-src.len()..]\n            .iter()\n            .zip(src)\n            .all(|(d, s)| *d == *s || *s == 1)\n}\n// if !can_broadcast_to(&x.dims(), &[3, 5]) { /* fix shape */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Right-align shapes mentally: every src dim must equal the dst dim or be 1","Ensure target rank >= source rank; use reshape/unsqueeze to add dims first","Recompute expand shapes when input rank changes after squeeze/reshape refactors","Add debug_assert!s on dims in helper functions wrapping expand"],"tags":["rust","ndarray","panic","broadcast","shape"],"backgroundTag":"tensor-broadcast-shape-mismatch","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"}