tracel-ai/burn · error

{other:?} reduction is not supported

Error message

{other:?} reduction is not supported

What it means

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.

Source

Thrown at crates/burn-nn/src/loss/soft_margin.rs:45

    }

    /// Compute the criterion on the input tensor.
    ///
    /// # Shapes
    ///
    /// - logits: `[batch_size, num_targets]`
    /// - targets: `[batch_size, num_targets]` (values in `{-1, 1}`)
    pub fn forward<const D: usize>(
        &self,
        logits: Tensor<D>,
        targets: Tensor<D>,
        reduction: Reduction,
    ) -> Tensor<1> {
        let tensor = self.forward_no_reduction(logits, targets);
        match reduction {
            Reduction::Mean | Reduction::Auto => tensor.mean(),
            Reduction::Sum => tensor.sum(),
            other => panic!("{other:?} reduction is not supported"),
        }
    }

    /// Compute the criterion on the input tensor without reducing.
    pub fn forward_no_reduction<const D: usize>(
        &self,
        logits: Tensor<D>,
        targets: Tensor<D>,
    ) -> Tensor<D> {
        // log(1 + exp(-target * logit)) = softplus(-target * logit)
        softplus(targets.mul(logits).neg(), 1.0)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use burn::tensor::TensorData;

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Pass Reduction::Mean, Reduction::Auto, or Reduction::Sum.
  2. Use `forward_no_reduction(logits, targets)` for element-wise loss.
  3. Normalize deserialized reduction values before calling forward.

Example fix

// before
let loss = soft_margin.forward(logits, targets, Reduction::None);
// after
let loss = soft_margin.forward_no_reduction(logits, targets);
Defensive patterns

Strategy: validation

Validate before calling

fn is_supported_reduction(r: &Reduction) -> bool {
    matches!(r, Reduction::Mean | Reduction::Auto | Reduction::Sum)
}
assert!(is_supported_reduction(&reduction));

Type guard

fn is_supported_reduction(r: &Reduction) -> bool {
    matches!(r, Reduction::Mean | Reduction::Auto | Reduction::Sum)
}

Try / catch

let result = std::panic::catch_unwind(|| soft_margin.forward(logits, targets, reduction));
match result {
    Ok(loss) => loss,
    Err(_) => soft_margin.forward_no_reduction(logits, targets).mean(),
}

Prevention

When it happens

Trigger: Calling `SoftMarginLoss::forward(logits, targets, reduction)` with a Reduction other than Mean, Auto, or Sum (e.g. Reduction::None).

Common situations: 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.

Related errors


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