{"record":{"id":"0a6380d39dfcde43","repo":"tracel-ai/burn","slug":"an-autodiff-float-primitive-must-have-an-enabled-a-0a6380","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-dispatch/src/ops/qtensor.rs","lineNumber":125,"sourceCode":"                                    TensorPrimitive::QFloat(rhs.quantized()),\n                                );\n                                wrap_q_matmul_autodiff!($Backend, output, strategy)\n                            })\n                        }\n                        #[cfg(not(feature = \"autodiff\"))]\n                        DispatchAutodiffContext::Enabled(_) => {\n                            panic!(\"autodiff context requires the `autodiff` feature\")\n                        }\n                    }\n                }\n            )*\n            #[cfg(feature = \"autodiff\")]\n            (DispatchTensorKind::Autodiff(lhs), rhs) => match (*lhs, rhs) {\n                $(\n                    #[cfg($cfg)]\n                    (DispatchTensorKind::$Backend(lhs), DispatchTensorKind::$Backend(rhs)) => {\n                        let DispatchAutodiffContext::Enabled(strategy) = $autodiff else {\n                            panic!(\"an autodiff float primitive must have an enabled autodiff context\")\n                        };\n                        with_autodiff_backend!($Backend, strategy, |B| {\n                            let output = B::q_matmul(\n                                TensorPrimitive::Float(lhs.autodiff()),\n                                TensorPrimitive::QFloat(rhs.quantized()),\n                            );\n                            wrap_q_matmul_autodiff!($Backend, output, strategy)\n                        })\n                    }\n                )*\n                #[allow(unreachable_patterns)]\n                _ => panic!(\"q_matmul inputs are on different backends\"),\n            },\n            #[allow(unreachable_patterns)]\n            _ => panic!(\"q_matmul inputs are on different backends\"),\n        }\n    }};\n}","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-dispatch/src/ops/qtensor.rs#L107-L143","documentation":"In q_matmul_fq_arms, when the lhs float tensor is stored as an Autodiff primitive (DispatchTensorKind::Autodiff), the code requires the dispatch autodiff context to be DispatchAutodiffContext::Enabled so it can unwrap the gradation strategy. If the context is Disabled while the tensor is an autodiff primitive, the invariant is broken and burn panics: an autodiff-wrapped tensor cannot be used without its gradient-tracking context.","triggerScenarios":"Calling q_matmul where lhs.kind is DispatchTensorKind::Autodiff but the autodiff argument is DispatchAutodiffContext::Disabled — e.g. an autodiff tensor from a gradation-enabled scope used inside a context that was constructed with autodiff disabled.","commonSituations":"Using a tensor returned from an Autodiff backend scope inside a plain (non-grad) dispatch scope; constructing a DispatchTensor manually with mismatched autodiff context; caching autodiff tensors across contexts in a module or server that toggles gradation.","solutions":["Enable the autodiff context (gradation) around the matmul so the context matches the tensor primitive","Use the tensor's inner float value (detach / .inner()) when working outside a gradation context","Ensure tensors produced by an Autodiff backend are only consumed within that same context","Rebuild the tensor through the same backend/context chain that created it"],"exampleFix":"// before\nlet out = dispatch::q_matmul(autodiff_lhs, q_rhs, DispatchAutodiffContext::Disabled);\n// after\nlet out = dispatch::q_matmul(autodiff_lhs, q_rhs, DispatchAutodiffContext::Enabled(strategy));","handlingStrategy":"type-guard","validationCode":"fn autodiff_tensor_in_enabled_ctx(t: &DispatchTensor, ctx: &DispatchAutodiffContext) -> bool {\n    !matches!(t.kind, DispatchTensorKind::Autodiff(_))\n        || matches!(ctx, DispatchAutodiffContext::Enabled(_))\n}","typeGuard":"fn is_autodiff(t: &DispatchTensor) -> bool {\n    matches!(t.kind, DispatchTensorKind::Autodiff(_))\n}","tryCatchPattern":null,"preventionTips":["Only consume Autodiff-kind tensors inside a gradation (Enabled) context","Detach to the inner float tensor before crossing into a no-grad scope","Never hand-construct DispatchTensors with a Disabled context for Autodiff kinds","Centralize context creation so it always matches the tensors it operates on"],"tags":["burn","autodiff","gradient-context","panic"],"backgroundTag":"autodiff-context-mismatch","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"}