tracel-ai/burn · error

autodiff float input reached concrete dispatch

Error message

autodiff float input reached concrete dispatch

What it means

Generated as the `invalid_autodiff_float` arm: when an operation is routed to the concrete (non-autodiff) backend, an input arriving under `DispatchTensorKind::Autodiff` for a float kind is rejected. An autodiff (gradient-tracking) float tensor cannot be consumed by a concrete backend primitive, so the codegen panics with this message to prevent silently dropping gradient tracking.

Source

Thrown at crates/burn-backend-extension/src/routing.rs:788

                        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")
                        }
                    },
                    #[allow(unreachable_patterns)]
                    _ => #mismatch,
                }
            });
        }
    } else {
        let target = ir::with_backend(ty, quote!(#backend_root::#backend));
        quote! {
            let #name = <#target as #extension_trait<#backend_root::#backend>>::map_from_dispatch(
                #name,
                |__tensor| {
                    match __tensor.kind {
                        #dispatch_kind::#backend(tensor) => tensor,
                        #[allow(unreachable_patterns)]
                        _ => #mismatch,
                    }

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Detach/convert the autodiff tensor to its inner concrete float tensor before the call (e.g. via the non-autodiff repr)
  2. Route the call to the autodiff variant of the op so Autodiff inputs are accepted
  3. Restructure so differentiating tensors never leave the tracked region into concrete-only ops

Example fix

// before
let y = concrete_only_op::<B>(ad_tensor); // panics: autodiff float input reached concrete dispatch
// after
let inner = ad_tensor.inner(); // strip autodiff wrapper
let y = concrete_only_op::<B>(inner);
Defensive patterns

Strategy: type-guard

Validate before calling

if let DispatchTensorKind::Autodiff(_) = t.kind { /* not safe for concrete-only ops */ detach_or_reroute(); }

Type guard

fn is_concrete_dispatch(t: &DispatchTensor) -> bool { !matches!(&t.kind, DispatchTensorKind::Autodiff(_)) }

Prevention

When it happens

Trigger: Calling a routed op compiled for the concrete backend (no autodiff lifting) with a tensor wrapped in the Autodiff dispatch kind — e.g. mixing differentiating and non-differentiating paths, or calling a concrete-only extension op inside a backward pass.

Common situations: Calling inference-only routed ops with training tensors; routing signatures missing the autodiff parameter so the concrete variant was generated; handing tensors out of a `grad` closure into non-autodiff code paths.

Related errors


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