{"record":{"id":"d7faa6507e5044d8","repo":"tracel-ai/burn","slug":"other-reduction-is-not-supported-d7faa6","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/multi_margin.rs","lineNumber":100,"sourceCode":"    ///\n    /// `Reduction::Auto` behaves as `Reduction::Mean`.\n    ///\n    /// # Shapes\n    ///\n    /// - input:  `[batch_size, num_classes]`\n    /// - target: `[batch_size]` (class indices in `0..num_classes`)\n    /// - output: `[1]`\n    pub fn forward(\n        &self,\n        input: Tensor<2>,\n        target: Tensor<1, Int>,\n        reduction: Reduction,\n    ) -> Tensor<1> {\n        let loss = self.forward_no_reduction(input, target);\n        match reduction {\n            Reduction::Mean | Reduction::Auto => loss.mean(),\n            Reduction::Sum => loss.sum(),\n            other => panic!(\"{other:?} reduction is not supported\"),\n        }\n    }\n\n    /// Compute the loss for each sample, without reducing.\n    ///\n    /// # Shapes\n    ///\n    /// - input:  `[batch_size, num_classes]`\n    /// - target: `[batch_size]` (class indices in `0..num_classes`)\n    /// - output: `[batch_size]`\n    pub fn forward_no_reduction(&self, input: Tensor<2>, target: Tensor<1, Int>) -> Tensor<1> {\n        let [batch_size, num_classes] = input.dims();\n        let target_indices = target.reshape([batch_size, 1]);\n\n        // Score of the correct class per sample: [batch_size, 1].\n        let correct = input.clone().gather(1, target_indices);\n\n        // Sum over ALL classes of max(0, margin - x[y] + x[i]) ^ p: [batch_size, 1].","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-nn/src/loss/multi_margin.rs#L82-L118","documentation":"Reduction-enum exhaustiveness guard in MultiMarginLoss::forward: supports Mean/Auto and Sum only; any other `Reduction` value panics when passed to forward, indicating an unsupported reduction variant.","triggerScenarios":"Calling MultiMarginLoss::forward(input, target, reduction) with Reduction::None or any non-Mean/Auto/Sum variant.","commonSituations":"Porting PyTorch MultiMarginLoss(reduction='none'); a single reduction setting shared across multiple losses where this one is stricter; stale enum values from config files.","solutions":["Use Reduction::Mean, Reduction::Sum, or Reduction::Auto.","Use MultiMarginLoss::forward_no_reduction and reduce manually if per-sample values are needed.","Validate/map the reduction in the config layer before invoking the loss."],"exampleFix":"// before\nlet loss = criterion.forward(input, target, Reduction::None); // panics\n// after\nlet elem = criterion.forward_no_reduction(input, target);\nlet loss = elem.mean();","handlingStrategy":"validation","validationCode":"fn ensure_supported(r: &Reduction) -> Result<(), String> {\n    match r {\n        Reduction::Mean | Reduction::Auto | Reduction::Sum => Ok(()),\n        other => Err(format!(\"unsupported reduction for multi margin: {other:?}\")),\n    }\n}","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(std::panic::AssertUnwindSafe(||\n    criterion.forward(input, target, reduction.clone())));","preventionTips":["Pass only Mean/Auto/Sum to MultiMarginLoss::forward.","Use forward_no_reduction for per-sample values.","Validate reduction in config parsing for all losses.","Test every reduction variant your training configs can produce."],"tags":["rust","burn","loss","multi-margin","reduction"],"backgroundTag":"unsupported-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"}