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
- Pass a Float tensor (DispatchTensorKind::Float) to autodiff-routed operations
- Remove the autodiff routing from non-float primitives so they dispatch directly to the concrete backend
- Split mixed-dtype operations into separate float and int dispatch calls
- 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
- Keep int/bool tensors on concrete backend primitives, never autodiff routes
- Split mixed-dtype pipelines into separate typed calls
- Verify macro annotations: only float primitives get autodiff routing
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
- Autodiff should not wrap an autodiff tensor.
- Should be int, got autodiff
- Should be bool, got autodiff
- Can't differentiate avg pool 2d backward.
- Can't differentiate max pool2d with indices backward.
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/af929747cef72e55.
Report an issue: GitHub.