{"record":{"id":"7dd6195bc3412960","repo":"tracel-ai/burn","slug":"cannot-compute-max-of-empty-tensor","errorCode":null,"errorMessage":"Cannot compute max of empty tensor","messagePattern":"Cannot compute max of empty tensor","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-ndarray/src/ops/base.rs","lineNumber":1267,"sourceCode":"                        false => -one,\n                    }\n                }\n            })\n            .into_shared()\n    }\n}\n\nimpl<E> NdArrayMathOps<E>\nwhere\n    E: Copy + NdArrayElement + PartialOrd,\n{\n    /// Max of all elements - zero-copy for borrowed storage.\n    pub fn max_view(view: ArrayView<'_, E, IxDyn>) -> SharedArray<E> {\n        let max = view\n            .iter()\n            .copied()\n            .reduce(|a, b| if a > b { a } else { b })\n            .expect(\"Cannot compute max of empty tensor\");\n        ArrayD::from_elem(IxDyn(&[1]), max).into_shared()\n    }\n\n    /// Max of all floating-point elements with NaN propagation.\n    pub fn max_float_view(view: ArrayView<'_, E, IxDyn>) -> SharedArray<E>\n    where\n        E: FloatNdArrayElement,\n    {\n        let max = view\n            .iter()\n            .copied()\n            .reduce(|a, b| {\n                if a.partial_cmp(&a).is_none() || a > b {\n                    a\n                } else {\n                    b\n                }\n            })","sourceCodeStart":1249,"sourceCodeEnd":1285,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-ndarray/src/ops/base.rs#L1249-L1285","documentation":"max_view reduces a (zero-copy) view of the tensor to its maximum element using reduce(), which returns None when the iterator is empty. The expect() then panics, because there is no defined max of zero elements. Applies to the max_dim reduction (full reduction) on the ndarray backend.","triggerScenarios":"Calling Tensor::max_dim / max reduction on a tensor with zero elements (any dimension of size 0), e.g. after slicing an empty range or a batch dimension of size 0.","commonSituations":"Empty batches in a data loader with drop logic that lets an empty batch reach max pooling; slicing with an empty range (0..0); dynamic shapes that collapse to 0 under certain inputs.","solutions":["Guard: if tensor.num_elements() == 0, skip the reduction or return a sentinel value instead of calling max","Fix upstream slicing/shape logic so dimensions are never 0 at the reduction point","Filter empty batches before running the model"],"exampleFix":"// before\nlet m = empty_batch.max(); // panics\n// after\nif empty_batch.num_elements() > 0 {\n    let m = empty_batch.max();\n} else {\n    // handle empty case: skip or default value\n}","handlingStrategy":"validation","validationCode":"fn safe_max<E: burn_ndarray::FloatElement, const D: usize>(t: &Tensor<NdArray<E>, D>) -> Option<Tensor<NdArray<E>, 1>> {\n    if t.num_elements() == 0 { None } else { Some(t.max()) }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check num_elements() > 0 before any full reduction (max/min/sum/mean)","Guard against empty slices (0..0) and empty batches upstream","Handle zero-sized validation splits explicitly in metric loops","Remember ONNX allows reducing empty dims; burn-ndarray panics - add guards at graph boundaries"],"tags":["rust","ndarray","panic","max","empty-tensor","reduction"],"backgroundTag":"empty-tensor-reduction","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"}