{"record":{"id":"fb906d9a99429edb","repo":"tracel-ai/burn","slug":"can-t-differentiate-linear-bias-backward","errorCode":null,"errorMessage":"Can't differentiate linear_bias_backward.","messagePattern":"Can't differentiate linear_bias_backward\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-autodiff/src/ops/module.rs","lineNumber":194,"sourceCode":"        }\n    }\n\n    fn linear_x_backward(\n        _weight: AutodiffTensor<B>,\n        _output_grad: AutodiffTensor<B>,\n    ) -> AutodiffTensor<B> {\n        panic!(\"Can't differentiate linear_x_backward.\");\n    }\n\n    fn linear_weight_backward(\n        _x: AutodiffTensor<B>,\n        _output_grad: AutodiffTensor<B>,\n    ) -> AutodiffTensor<B> {\n        panic!(\"Can't differentiate linear_weight_backward.\");\n    }\n\n    fn linear_bias_backward(_output_grad: AutodiffTensor<B>) -> AutodiffTensor<B> {\n        panic!(\"Can't differentiate linear_bias_backward.\");\n    }\n\n    fn conv1d(\n        x: AutodiffTensor<B>,\n        weight: AutodiffTensor<B>,\n        bias: Option<AutodiffTensor<B>>,\n        options: ConvOptions<1>,\n    ) -> AutodiffTensor<B> {\n        #[derive(Debug)]\n        struct Conv1DWithBias;\n        #[derive(Debug)]\n        struct Conv1DNoBias;\n\n        impl<B: Backend> Backward<B, 3> for Conv1DWithBias {\n            type State = (NodeId, NodeId, NodeId, ConvOptions<1>);\n\n            fn backward(\n                self,","sourceCodeStart":176,"sourceCodeEnd":212,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-autodiff/src/ops/module.rs#L176-L212","documentation":"Dead-code sentinel: `linear_bias_backward` exists only to satisfy the backward-op trait, but the bias gradient is computed as part of `linear_backward` (a reduction over x's gradient). Reaching this panic means the dispatcher attempted a per-parameter backward that the linear op never registers as runnable.","triggerScenarios":"Calling dequantize (or Tensor::dequantize) on a QuantizedTensor whose backend is BackendRouter — e.g. materializing float output from a quantized computation under the router.","commonSituations":"End of a quantized inference pipeline needing float results; mixing quantized and float ops via the router; export paths that dequantize weights.","solutions":["Dequantize on the concrete backend that produced the quantized tensor, before values re-enter routed code.","Keep quantized tensors on a native quantization-capable backend end-to-end.","Pre-convert weights to float and route only float ops."],"exampleFix":"// before\nlet f = BackendRouter::<R>::dequantize(q_tensor, FloatDType::F32); // panics\n// after\nlet f = ConcreteBackend::dequantize(q_tensor, FloatDType::F32);","handlingStrategy":"fallback","validationCode":"fn ensure_dequant_backend<B: Backend>() -> Result<(), &'static str> {\n    Err(\"dequantize is not implemented for BackendRouter; dequantize on the producing backend\")\n}","typeGuard":"fn is_quantized<B: Backend>(t: &QuantizedTensor<B>) -> bool { true } // all quantized tensors hit the stub on router","tryCatchPattern":"let f = std::panic::catch_unwind(|| q_tensor.clone().dequantize(FloatDType::F32))\n    .map_err(|_| anyhow::anyhow!(\"router dequantize is a stub; use the concrete backend\"))?;","preventionTips":["Dequantize on the backend that produced the quantized tensor.","Do not let QuantizedTensor values cross into BackendRouter-typed code.","Convert weights to float before export/inference if routing is required.","Keep quantized inference entirely on a quantization-capable backend."],"tags":["rust","burn-router","quantization","dequantize","unimplemented"],"backgroundTag":"unimplemented-api-stub","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"}