tracel-ai/burn · error

{other:?} reduction is not supported

Error message

{other:?} reduction is not supported

What it means

TripletMarginLoss's reduced `forward` only handles Reduction::Mean/Auto and Reduction::Sum; any other variant panics. Since the reduced call returns a scalar `Tensor<1>`, unsupported reduction modes are rejected by the catch-all match arm.

Source

Thrown at crates/burn-nn/src/loss/triplet_margin.rs:91

    ///
    /// # Shapes
    ///
    /// - anchor:   `[batch_size, embedding_dim]`
    /// - positive: `[batch_size, embedding_dim]`
    /// - negative: `[batch_size, embedding_dim]`
    /// - output:   `[1]`
    pub fn forward(
        &self,
        anchor: Tensor<2>,
        positive: Tensor<2>,
        negative: Tensor<2>,
        reduction: Reduction,
    ) -> Tensor<1> {
        let loss = self.forward_no_reduction(anchor, positive, negative);
        match reduction {
            Reduction::Mean | Reduction::Auto => loss.mean(),
            Reduction::Sum => loss.sum(),
            other => panic!("{other:?} reduction is not supported"),
        }
    }

    /// Compute the loss for each triplet, without reducing.
    ///
    /// # Shapes
    ///
    /// - anchor:   `[batch_size, embedding_dim]`
    /// - positive: `[batch_size, embedding_dim]`
    /// - negative: `[batch_size, embedding_dim]`
    /// - output:   `[batch_size]`
    pub fn forward_no_reduction(
        &self,
        anchor: Tensor<2>,
        positive: Tensor<2>,
        negative: Tensor<2>,
    ) -> Tensor<1> {
        // Pairwise distances over the embedding dim: shape [batch_size, 1] -> [batch_size].

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Pass Reduction::Mean, Reduction::Auto, or Reduction::Sum.
  2. Call `forward_no_reduction(anchor, positive, negative)` for the per-triplet (unreduced) loss.
  3. Validate the Reduction value before calling forward.

Example fix

// before
let loss = triplet_loss.forward(anchor, pos, neg, Reduction::None);
// after
let per_triplet = triplet_loss.forward_no_reduction(anchor, pos, neg);
let loss = per_triplet.mean();
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(|| triplet_loss.forward(a, p, n, reduction));
match result {
    Ok(loss) => loss,
    Err(_) => triplet_loss.forward_no_reduction(a, p, n).mean(),
}

Prevention

When it happens

Trigger: Calling `TripletMarginLoss::forward(anchor, positive, negative, reduction)` with a Reduction variant other than Mean, Auto, or Sum, typically Reduction::None.

Common situations: Porting triplet loss code from PyTorch using reduction='none'; a shared Reduction config value reused across losses with different support; new enum variants from a burn upgrade.

Related errors


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