tracel-ai/burn · error
Requires autodiff tensor.
Error message
Requires autodiff tensor.
What it means
backward() only handles tensors whose outer kind is DispatchTensorKind::Autodiff. Any other kind (NdArray, LibTorch, Cube, Flex, Remote, Capture) reaching backward() directly panics with 'Requires autodiff tensor.' — the tensor was never wrapped for gradient tracking.
Source
Thrown at crates/burn-dispatch/src/backend.rs:351
#[cfg(cube_backend)]
DispatchTensorKind::Cube(tensor) => tensor.autodiff().backward(),
#[cfg(any(feature = "flex", default_backend))]
DispatchTensorKind::Flex(tensor) => tensor.autodiff().backward(),
#[cfg(feature = "ndarray")]
DispatchTensorKind::NdArray(tensor) => tensor.autodiff().backward(),
#[cfg(feature = "tch")]
DispatchTensorKind::LibTorch(tensor) => tensor.autodiff().backward(),
#[cfg(feature = "remote")]
DispatchTensorKind::Remote(tensor) => tensor.autodiff().backward(),
#[cfg(feature = "capture")]
DispatchTensorKind::Capture(_) => {
panic!("Capture tensors do not support autodiff")
}
DispatchTensorKind::Autodiff(_) => {
panic!("Autodiff should not wrap an autodiff tensor.")
}
},
_ => panic!("Requires autodiff tensor."),
}
}
fn grad(tensor: &DispatchTensor, grads: &Self::Gradients) -> Option<DispatchTensor> {
let DispatchTensor { kind, .. } = tensor;
let grad: Option<DispatchTensorKind> = match &kind {
DispatchTensorKind::Autodiff(inner_kind) => match &**inner_kind {
#[cfg(cube_backend)]
DispatchTensorKind::Cube(tensor) => tensor
.as_autodiff()
.grad(grads)
.map(|t| DispatchTensorKind::Cube(crate::BackendTensor::Float(t))),
#[cfg(any(feature = "flex", default_backend))]
DispatchTensorKind::Flex(tensor) => tensor
.as_autodiff()
.grad(grads)
.map(|t| DispatchTensorKind::Flex(crate::BackendTensor::Float(t))),
#[cfg(feature = "ndarray")]View on GitHub (pinned to d16f7ba2ed)
Solutions
- Ensure the tensor comes from an autodiff-tracked computation (training forward pass), not an eval/inference call
- Enable the 'autodiff' feature and use Autodiff-wrapped tensors for training
- Do not reuse grad()/inner() results as backward() roots; recompute the loss with the autodiff backend
Example fix
// before let out = model.eval(x); let grads = out.backward(); // panics: not an autodiff tensor // after let out = model.forward(x); // autodiff-tracked let grads = out.backward();
Defensive patterns
Strategy: type-guard
Validate before calling
fn ensure_autodiff(t: &DispatchTensor) -> Result<(), String> {
match &t.kind {
DispatchTensorKind::Autodiff(_) => Ok(()),
_ => Err("backward() requires an autodiff-wrapped tensor".into()),
}
} Type guard
fn is_autodiff_tensor(t: &DispatchTensor) -> bool {
matches!(t.kind, DispatchTensorKind::Autodiff(_))
} Try / catch
let result = std::panic::catch_unwind(AssertUnwindSafe(|| Dispatch::backward(loss)));
match result {
Ok(grads) => grads,
Err(_) => panic!("loss tensor was not autodiff-tracked; recompute with training forward"),
} Prevention
- Call backward() only on tensors from a training (autodiff) forward pass
- Do not reuse grad()/inner()/eval outputs as backward roots
- Enable the 'autodiff' feature when training
When it happens
Trigger: Calling Dispatch::backward(tensor) where tensor.kind is not Autodiff — e.g. a plain inference tensor from backend.eval()/forward, or a grad() output (which returns inner-backend tensors with autodiff: Disabled) fed back into backward().
Common situations: Calling backward() on outputs of no_grad/eval inference; using a tensor returned by grad() or inner() as a new loss root; forgetting to enable the 'autodiff' feature so tensors are never autodiff-wrapped.
Related errors
- an enabled float tensor must use an autodiff primitive
- Should be float, got autodiff
- Should be bool, got autodiff
- an autodiff float primitive must have an enabled autodiff co
- an enabled float tensor must use an autodiff primitive
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/5045026be1c66378.
Report an issue: GitHub.