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
Generated by extract_extension (autodiff path): within an `Autodiff` dispatch variant, the inner `BackendTensor` must itself be the `Autodiff` variant (i.e. a float tensor under gradient tracking). The match panics when the inner tensor is Int, Bool, Quantized, or otherwise not an autodiff float — only float tensors can carry autodiff state.
Source
Thrown at crates/burn-backend-extension/src/routing.rs:772
if autodiff {
let target = ir::with_backend(ty, quote!(#backend_alias));
let context = quote!(#dispatch_root::DispatchAutodiffContext);
quote! {
let #name = <#target as #extension_trait<#backend_alias>>::map_from_dispatch(#name, |__tensor| {
let __input_context = __tensor.autodiff;
match __tensor.kind {
#dispatch_kind::Autodiff(inner) => {
let #context::Enabled(_) = __input_context else {
panic!("an autodiff float primitive must have an enabled autodiff context")
};
let tensor = match *inner {
#dispatch_kind::#backend(tensor) => tensor,
#[allow(unreachable_patterns)]
_ => #mismatch,
};
match tensor {
#backend_tensor::Autodiff(tensor) => #backend_tensor::Float(tensor),
_ => panic!("only float tensors may use an autodiff primitive"),
}
}
#dispatch_kind::#backend(tensor) => match tensor {
#backend_tensor::Float(tensor) => {
let #context::Disabled = __input_context else {
panic!("an enabled float tensor must use an autodiff primitive")
};
#backend_tensor::Float(
<#backend_alias as #autodiff_trait>::from_inner(tensor)
)
}
#backend_tensor::Int(tensor) => #backend_tensor::Int(tensor),
#backend_tensor::Bool(tensor) => #backend_tensor::Bool(tensor),
#backend_tensor::Quantized(tensor) => #backend_tensor::Quantized(tensor),
#backend_tensor::Autodiff(_) => {
panic!("autodiff float input reached concrete dispatch")
}
},View on GitHub (pinned to d16f7ba2ed)
Solutions
- Pass non-float tensors as their concrete kind (not wrapped in Autodiff)
- Verify upstream code did not change the tensor kind; keep autodiff wrapping only for float tensors
- Adjust the routed signature so the input is declared with its actual kind
Example fix
// before DispatchTensorKind::Autodiff(Box::new(DispatchTensorKind::Candle(BackendTensor::Int(t)))) // panics // after DispatchTensorKind::Candle(BackendTensor::Int(t)) // pass Int directly
Defensive patterns
Strategy: type-guard
Validate before calling
if let DispatchTensorKind::Autodiff(inner) = &t.kind { assert!(matches!(**inner_inner_is_autodiff_float(inner)), "only float tensors may be autodiff-wrapped"); } Type guard
fn is_autodiff_float(t: &DispatchTensor) -> bool { matches!(&t.kind, DispatchTensorKind::Autodiff(inner) if matches!(inner.as_ref(), DispatchTensorKind::Target(BackendTensor::Autodiff(_)))) } Prevention
- Only wrap float tensors in the Autodiff kind
- Keep Int/Bool/Quantized tensors in their concrete kinds
- Review generic wrappers that blanket-wrap inputs in Autodiff
When it happens
Trigger: Wrapping a non-float tensor (Int indices, Bool mask, Quantized weights) in the Autodiff dispatch kind and passing it to an autodiff-routed extension input.
Common situations: Generic helper that wraps every input in `Autodiff(...)` regardless of dtype; tensor kind changed to Int/Bool upstream while routing metadata still says autodiff float; quantized models routed through autodiff primitives.
Related errors
- autodiff float input reached concrete dispatch
- Expected autodiff-wrapped float tensor for backend {backend}
- autodiff context requires the `autodiff` feature
- Operation not marked for autodiff.
- an autodiff float primitive must have an enabled autodiff co
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/f403679ffeaee712.
Report an issue: GitHub.