{"record":{"id":"4dd44c594b72f124","repo":"tracel-ai/burn","slug":"an-autodiff-float-primitive-must-have-an-enabled-a","errorCode":null,"errorMessage":"an autodiff float primitive must have an enabled autodiff context","messagePattern":"an autodiff float primitive must have an enabled autodiff context","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-backend-extension/src/routing.rs","lineNumber":535,"sourceCode":"    extraction: &Extraction<'_>,\n    autodiff_variant: bool,\n) -> TokenStream {\n    let InputKind::Tensor { kind, borrowed } = input.kind else {\n        unreachable!(\"selected input must be a tensor\")\n    };\n    let name = &input.name;\n    let selected = format_ident!(\"__burn_selected\");\n    let dispatch_root = &extraction.paths.dispatch_root;\n    let backend_alias = &extraction.paths.backend_alias;\n    let context = quote!(#dispatch_root::DispatchAutodiffContext);\n    assert!(\n        kind == TensorKind::Float || !autodiff_variant,\n        \"only a float input can directly select an autodiff primitive\"\n    );\n    let validate_context = if kind == TensorKind::Float && autodiff_variant {\n        quote! {\n            let #context::Enabled(_) = __burn_selected_context else {\n                panic!(\"an autodiff float primitive must have an enabled autodiff context\")\n            };\n        }\n    } else if kind == TensorKind::Float {\n        quote! {\n            let #context::Disabled = __burn_selected_context else {\n                panic!(\"an enabled float tensor must use an autodiff primitive\")\n            };\n        }\n    } else {\n        TokenStream::new()\n    };\n\n    if kind == TensorKind::Float && extraction.autodiff && !autodiff_variant {\n        let autodiff_trait = &extraction.paths.autodiff_trait;\n        if borrowed {\n            let lifted = format_ident!(\"__lifted_{name}\");\n            quote! {\n                #validate_context","sourceCodeStart":517,"sourceCodeEnd":553,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-backend-extension/src/routing.rs#L517-L553","documentation":"Generated by extract_selected_input when a float tensor input is routed to an autodiff primitive: the macro pattern-matches the DispatchAutodiffContext and requires it to be Enabled. If the selected context is Disabled (or otherwise not enabled), the operation panics because an autodiff primitive cannot run without gradient tracking active.","triggerScenarios":"Calling a dispatch operation whose selected input resolves to the Autodiff float primitive while the tensor's autodiff context is DispatchAutodiffContext::Disabled — i.e. an ad-wrapped backend tensor created without enabling the autodiff context.","commonSituations":"Mixing tensors created with autodiff disabled with ops that require the autodiff primitive; disabling gradient tracking globally and then invoking a routing path that targets the autodiff backend; config/state mismatch after toggling autodiff on a tensor.","solutions":["Ensure the tensor's autodiff context is Enabled (create it via the autodiff backend with gradient tracking on) before the call","Use the non-autodiff routing/primitive for tensors created with autodiff disabled","Audit where the tensor was constructed and keep context (Enabled/Disabled) consistent with the operation's expected primitive"],"exampleFix":"// before\nlet tensor = Tensor::<DispatchBackend, 2>::from_data(data, &device); // context Disabled\n// after\nlet tensor = Tensor::<AutodiffBackend, 2>::from_data(data, &device).require_grad(); // context Enabled","handlingStrategy":"type-guard","validationCode":"fn require_enabled_context(t: &DispatchTensor) -> Result<(), String> {\n    match t.autodiff {\n        DispatchAutodiffContext::Enabled(_) => Ok(()),\n        _ => Err(\"autodiff float primitive requires an enabled autodiff context\".into()),\n    }\n}","typeGuard":"fn is_grad_enabled(t: &DispatchTensor) -> bool {\n    matches!(t.autodiff, DispatchAutodiffContext::Enabled(_))\n}","tryCatchPattern":"let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| op(&tensor)))\n    .map_err(|_| \"autodiff context was disabled; recreate tensor with require_grad\".to_string())?","preventionTips":["Create autodiff-routed tensors with gradient tracking enabled","Do not globally disable autodiff for tensors destined for autodiff primitives","Keep context state consistent from tensor creation through every op"],"tags":["rust","autodiff","gradient","proc-macro"],"backgroundTag":"autodiff-context-not-enabled","analyzedSha":"d16f7ba2ed0d41408189384044cc886fb4c8f957","analyzedAt":"2026-09-05T13:19:14.260Z","contentChangedAt":"2026-09-05T13:19:14.260Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}