tracel-ai/burn · error

Expected autodiff-wrapped float tensor for backend {backend}

Error message

Expected autodiff-wrapped float tensor for backend {backend}.

What it means

In the `@autodiff` unwrap arm, if the tensor's kind is not `DispatchTensorKind::Autodiff` at all (it is a plain backend tensor or another kind), the macro panics asking for an autodiff-wrapped float tensor. The operation requires gradients, so a primitive tensor is insufficient.

Source

Thrown at crates/burn-dispatch/src/macros.rs:415

                    "Tensor is on the wrong backend (expected {}).",
                    stringify!($Backend)
                ),
            })
            .collect::<Vec<_>>()
    };

    // Autodiff-wrapped backend
    (@autodiff $Backend:ident, $vec:expr, $kind:ident) => {
        $vec.into_iter()
            .map(|t| match t.kind {
                $crate::DispatchTensorKind::Autodiff(inner) => match *inner {
                    $crate::DispatchTensorKind::$Backend(inner) => inner.$kind(),
                    _ => panic!(
                        "Autodiff float tensor is on the wrong backend (expected {}).",
                        stringify!($Backend)
                    ),
                },
                _ => panic!(
                    "Expected autodiff-wrapped float tensor for backend {}.",
                    stringify!($Backend)
                ),
            })
            .collect::<Vec<_>>()
    };
}

/// Match arm generator for `transaction_op`.
macro_rules! transaction_op_arms {
    ($tx:ident, $first:expr; $([$Backend:ident, $cfg:meta]),*) => {{
        match &$first.kind {
            // Autodiff arm first
            #[cfg(feature = "autodiff")]
            $crate::DispatchTensorKind::Autodiff(inner) => {
                // Recursively dispatch on inner
                match **inner {
                    $(

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Pass an `AutodiffTensor` (created via `AutodiffTensor::from` / backend tensor `.autodiff()`), not the primitive tensor
  2. Ensure the operation is invoked through the Autodiff backend, not the base backend directly
  3. Check the tensor is a float tensor as required by the op

Example fix

// before
op(primitive_tensor);
// after
op(AutodiffTensor::from(primitive_tensor));
Defensive patterns

Strategy: type-guard

Type guard

fn as_autodiff<B: AutodiffBackend>(t: &Tensor<B, D>) -> &Tensor<B, D> { t } // Rust's type system: pass Tensor<Autodiff<B>, D> not Tensor<B, D>; the compiler rejects primitives

Prevention

When it happens

Trigger: Calling an autodiff-dispatched float operation with a raw backend tensor (not `AutodiffTensor`), or a non-float tensor where a float autodiff tensor is required.

Common situations: Mixing inference-time primitive tensors into a training graph; calling `.detach()`/`inner()` on a tensor and reusing the result where the autodiff tensor is expected.

Related errors


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