{"record":{"id":"a56422e6cdb5416a","repo":"tracel-ai/burn","slug":"other-reduction-is-not-supported-a56422","errorCode":null,"errorMessage":"{other:?} reduction is not supported","messagePattern":"(.+?) reduction is not supported","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-nn/src/loss/soft_margin.rs","lineNumber":45,"sourceCode":"    }\n\n    /// Compute the criterion on the input tensor.\n    ///\n    /// # Shapes\n    ///\n    /// - logits: `[batch_size, num_targets]`\n    /// - targets: `[batch_size, num_targets]` (values in `{-1, 1}`)\n    pub fn forward<const D: usize>(\n        &self,\n        logits: Tensor<D>,\n        targets: Tensor<D>,\n        reduction: Reduction,\n    ) -> Tensor<1> {\n        let tensor = self.forward_no_reduction(logits, targets);\n        match reduction {\n            Reduction::Mean | Reduction::Auto => tensor.mean(),\n            Reduction::Sum => tensor.sum(),\n            other => panic!(\"{other:?} reduction is not supported\"),\n        }\n    }\n\n    /// Compute the criterion on the input tensor without reducing.\n    pub fn forward_no_reduction<const D: usize>(\n        &self,\n        logits: Tensor<D>,\n        targets: Tensor<D>,\n    ) -> Tensor<D> {\n        // log(1 + exp(-target * logit)) = softplus(-target * logit)\n        softplus(targets.mul(logits).neg(), 1.0)\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n    use burn::tensor::TensorData;","sourceCodeStart":27,"sourceCodeEnd":63,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-nn/src/loss/soft_margin.rs#L27-L63","documentation":"SoftMarginLoss's reduced `forward` supports only Reduction::Mean/Auto and Reduction::Sum; other variants hit the panic arm. Reduced forward always returns a `Tensor<1>` scalar, so unsupported reduction modes are rejected eagerly.","triggerScenarios":"Calling `SoftMarginLoss::forward(logits, targets, reduction)` with a Reduction other than Mean, Auto, or Sum (e.g. Reduction::None).","commonSituations":"Translating PyTorch soft_margin_loss with reduction='none'; passing a shared config enum with an unsupported variant; version drift where new Reduction variants were added.","solutions":["Pass Reduction::Mean, Reduction::Auto, or Reduction::Sum.","Use `forward_no_reduction(logits, targets)` for element-wise loss.","Normalize deserialized reduction values before calling forward."],"exampleFix":"// before\nlet loss = soft_margin.forward(logits, targets, Reduction::None);\n// after\nlet loss = soft_margin.forward_no_reduction(logits, targets);","handlingStrategy":"validation","validationCode":"fn is_supported_reduction(r: &Reduction) -> bool {\n    matches!(r, Reduction::Mean | Reduction::Auto | Reduction::Sum)\n}\nassert!(is_supported_reduction(&reduction));","typeGuard":"fn is_supported_reduction(r: &Reduction) -> bool {\n    matches!(r, Reduction::Mean | Reduction::Auto | Reduction::Sum)\n}","tryCatchPattern":"let result = std::panic::catch_unwind(|| soft_margin.forward(logits, targets, reduction));\nmatch result {\n    Ok(loss) => loss,\n    Err(_) => soft_margin.forward_no_reduction(logits, targets).mean(),\n}","preventionTips":["Use forward_no_reduction for per-element loss.","Map external reduction configs to supported variants before constructing losses.","Add unit tests covering every Reduction variant you pass."],"tags":["rust","panic","loss-function","unsupported-argument"],"backgroundTag":"unsupported-reduction-mode","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"}