tracel-ai/burn · error

only float tensors may use an autodiff primitive

Error message

only float tensors may use an autodiff primitive

What it means

The dispatch macro routes tensor kinds to backend arms, but autodiff primitives are only defined for float tensors. When the source tensor kind is non-float (int/bool), and the operation would use an autodiff primitive, the generated Autodiff arm panics because autodiff only wraps float backends.

Source

Thrown at crates/burn-backend-extension/src/dispatch.rs:215

            panic!("Autodiff should not wrap an autodiff tensor.")
        }),
        fallback: quote!(panic!("unsupported dispatch backend")),
    });
    let arms = routing::backend_kind_arms(
        &paths,
        &backends,
        selected.as_ref(),
        autodiff_match,
        |_, backend, autodiff| {
            backend_route_body(backend, operation, &float_inputs, autodiff, source)
        },
    );
    let direct_arms = arms.concrete;
    let autodiff_route = if source_is_non_float {
        quote! {
            #[cfg(feature = "autodiff")]
            crate::DispatchTensorKind::Autodiff(_) => {
                panic!("only float tensors may use an autodiff primitive")
            }
        }
    } else {
        arms.autodiff.expect("autodiff backend arms should exist")
    };

    quote! {
        #selection
        match #source_kind {
            #(#direct_arms)*
            #autodiff_route
            #[allow(unreachable_patterns)]
            _ => panic!("unsupported dispatch backend"),
        }
    }
}

fn float_input_presence(

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Pass a Float tensor (DispatchTensorKind::Float) to autodiff-routed operations
  2. Remove the autodiff routing from non-float primitives so they dispatch directly to the concrete backend
  3. Split mixed-dtype operations into separate float and int dispatch calls
  4. Check macro annotations so only float primitives get the autodiff flag

Example fix

// before
let idx: IntTensor<_> = ...;
dispatch_op!(autodiff)(&idx); // panic
// after
let x: FloatTensor<_> = ...;
dispatch_op!(autodiff)(&x);
Defensive patterns

Strategy: type-guard

Validate before calling

// Dispatch autodiff primitives only with float tensors
fn dispatch_float_only<B: Backend>(x: &FloatTensor<B>) { /* dispatch */ }

Type guard

fn ensure_float<B: Backend, const D: usize>(t: &Tensor<B, D>) -> &Tensor<B, D>
where B: FloatDTypeSupport { t } // rely on the type system: FloatTensor vs IntTensor types differ

Prevention

When it happens

Trigger: Invoking a dispatch-generated operation marked for autodiff with a DispatchTensor holding an int or bool kind; declaring a primitive as autodiff-capable but calling it from non-float tensor paths (expand_from_input / expand_from_candidates).

Common situations: Autodiff-wrapped operation tables mistakenly including int kernels; passing IntTensor into a generic dispatch function expecting FloatTensor; macro attribute errors when annotating primitives.

Related errors


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