tracel-ai/burn · error

Should be int, got autodiff

Error message

Should be int, got autodiff

What it means

BackendTensor::int() was called on an Autodiff-wrapped tensor handle. The Autodiff variant stores FloatTensor<Autodiff<B>> and cannot yield an int primitive, so the code panics. A gradient-tracking tensor reached an int-only code path — doubly wrong, since autodiff tensors are float by definition.

Source

Thrown at crates/burn-dispatch/src/tensor.rs:68

        match self {
            BackendTensor::Float(tensor) => tensor,
            BackendTensor::Int(_) => panic!("Should be float, got int"),
            BackendTensor::Bool(_) => panic!("Should be float, got bool"),
            BackendTensor::Quantized(_) => panic!("Should be float, got quantized"),
            #[cfg(feature = "autodiff")]
            BackendTensor::Autodiff(_) => panic!("Should be float, got autodiff"),
        }
    }

    /// Returns the inner int tensor primitive.
    pub fn int(self) -> B::IntTensorPrimitive {
        match self {
            BackendTensor::Int(tensor) => tensor,
            BackendTensor::Float(_) => panic!("Should be int, got float"),
            BackendTensor::Bool(_) => panic!("Should be int, got bool"),
            BackendTensor::Quantized(_) => panic!("Should be int, got quantized"),
            #[cfg(feature = "autodiff")]
            BackendTensor::Autodiff(_) => panic!("Should be int, got autodiff"),
        }
    }

    /// Returns the inner bool tensor primitive.
    pub fn bool(self) -> B::BoolTensorPrimitive {
        match self {
            BackendTensor::Bool(tensor) => tensor,
            BackendTensor::Float(_) => panic!("Should be bool, got float"),
            BackendTensor::Int(_) => panic!("Should be bool, got int"),
            BackendTensor::Quantized(_) => panic!("Should be bool, got quantized"),
            #[cfg(feature = "autodiff")]
            BackendTensor::Autodiff(_) => panic!("Should be bool, got autodiff"),
        }
    }

    /// Returns the inner quantized tensor primitive.
    pub fn quantized(self) -> B::QuantizedTensorPrimitive {
        match self {

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Unwrap or detach first: call as_autodiff()/autodiff() and use inner()/valid() on the Autodiff backend to get the raw primitive, casting to int as needed
  2. Keep autodiff tensors on the training path and int index tensors on the raw-backend path
  3. If the site should support gradients, use float primitives and let the cast happen through autodiff-aware ops
  4. Make code generic over B handle the Autodiff variant explicitly when the feature is enabled

Example fix

// before
let idx = train_handle.int(); // panics: Autodiff variant
// after
#[cfg(feature = "autodiff")]
let idx = train_handle.as_autodiff().inner(); // raw backend primitive; cast to int via backend ops
Defensive patterns

Strategy: type-guard

Validate before calling

#[cfg(feature = "autodiff")]
if matches!(handle, BackendTensor::Autodiff(_)) {
    let raw = handle.as_autodiff().inner(); // unwrap before int/float paths
}

Type guard

#[cfg(feature = "autodiff")]
fn is_autodiff<B: BackendTypes>(t: &BackendTensor<B>) -> bool {
    matches!(t, BackendTensor::Autodiff(_))
}

Prevention

When it happens

Trigger: With feature = "autodiff", calling int() on a training-graph tensor; passing an Autodiff backend tensor into code expecting raw int primitives without unwrapping; casting a float training tensor to int and keeping it wrapped.

Common situations: Mixing training (Autodiff) tensors into indexing/scatter logic that consumes int primitives; custom ops written against B receiving Autodiff<B> tensors; rounding indices from a grad-tracked computation and passing the wrapped result.

Related errors


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