tracel-ai/burn · error

{other:?} reduction is not supported

Error message

{other:?} reduction is not supported

What it means

Reduction-enum exhaustiveness guard in HingeEmbeddingLoss::forward: only Mean, Auto (treated as Mean), and Sum are implemented; any other `Reduction` variant reaches the fallback arm and panics. It fires when a caller passes a reduction value the loss does not reduce with (typically a newly added enum variant or a bad cast).

Source

Thrown at crates/burn-nn/src/loss/hinge_embedding.rs:79

    ///
    /// `Reduction::Auto` behaves as `Reduction::Mean`.
    ///
    /// # Shapes
    ///
    /// - input:  `[...dims]`
    /// - target: `[...dims]` (values in `{-1, 1}`)
    /// - output: `[1]`
    pub fn forward<const D: usize>(
        &self,
        input: Tensor<D>,
        target: Tensor<D>,
        reduction: Reduction,
    ) -> Tensor<1> {
        let loss = self.forward_no_reduction(input, target);
        match reduction {
            Reduction::Mean | Reduction::Auto => loss.mean(),
            Reduction::Sum => loss.sum(),
            other => panic!("{other:?} reduction is not supported"),
        }
    }

    /// Compute the loss element-wise for the input and target.
    ///
    /// # Shapes
    ///
    /// - input:  `[...dims]`
    /// - target: `[...dims]` (values in `{-1, 1}`)
    /// - output: `[...dims]`
    pub fn forward_no_reduction<const D: usize>(
        &self,
        input: Tensor<D>,
        target: Tensor<D>,
    ) -> Tensor<D> {
        // y == 1  -> x ;  y == -1 -> max(0, margin - x)
        let negative = input.clone().neg().add_scalar(self.margin).clamp_min(0.0);
        let positive_mask = target.equal_scalar(1);

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Use Reduction::Mean, Reduction::Sum, or Reduction::Auto.
  2. Use HingeEmbeddingLoss::forward_no_reduction for element-wise losses and reduce yourself.
  3. Validate the reduction variant against a per-loss whitelist before calling forward.

Example fix

// before
let loss = criterion.forward(input, target, Reduction::None); // panics
// after
let elem = criterion.forward_no_reduction(input, target);
let loss = elem.mean();
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_supported(r: &Reduction) -> Result<(), String> {
    match r {
        Reduction::Mean | Reduction::Auto | Reduction::Sum => Ok(()),
        other => Err(format!("unsupported reduction for hinge embedding: {other:?}")),
    }
}

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(std::panic::AssertUnwindSafe(||
    criterion.forward(input, target, reduction.clone())));

Prevention

When it happens

Trigger: Calling HingeEmbeddingLoss::forward(input, target, reduction) with Reduction::None or any unsupported variant.

Common situations: Migrating PyTorch HingeEmbeddingLoss(reduction='none'); config-driven reduction values not validated per loss type; assuming all burn losses accept Reduction::None.

Related errors


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