tracel-ai/burn · error

Can't differentiate linear_weight_backward.

Error message

Can't differentiate linear_weight_backward.

What it means

Dead-code sentinel: `linear_weight_backward` is declared but never invoked by the autodiff engine, since the weight gradient for a linear layer is produced together with the input gradient in `linear_backward`. Hitting this panic means the op dispatcher tried to run a backward step that the linear implementation explicitly does not define.

Source

Thrown at crates/burn-autodiff/src/ops/module.rs:190

                OpsKind::UnTracked(prep) => {
                    prep.finish(B::linear(x.primitive, weight.primitive, None))
                }
            },
        }
    }

    fn linear_x_backward(
        _weight: AutodiffTensor<B>,
        _output_grad: AutodiffTensor<B>,
    ) -> AutodiffTensor<B> {
        panic!("Can't differentiate linear_x_backward.");
    }

    fn linear_weight_backward(
        _x: AutodiffTensor<B>,
        _output_grad: AutodiffTensor<B>,
    ) -> AutodiffTensor<B> {
        panic!("Can't differentiate linear_weight_backward.");
    }

    fn linear_bias_backward(_output_grad: AutodiffTensor<B>) -> AutodiffTensor<B> {
        panic!("Can't differentiate linear_bias_backward.");
    }

    fn conv1d(
        x: AutodiffTensor<B>,
        weight: AutodiffTensor<B>,
        bias: Option<AutodiffTensor<B>>,
        options: ConvOptions<1>,
    ) -> AutodiffTensor<B> {
        #[derive(Debug)]
        struct Conv1DWithBias;
        #[derive(Debug)]
        struct Conv1DNoBias;

        impl<B: Backend> Backward<B, 3> for Conv1DWithBias {

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Perform dynamic quantization on a concrete backend that implements it.
  2. Restructure so quantization happens outside the routed portion of the graph.
  3. Track upstream burn-router work for quantized op routing.

Example fix

// before
let q = BackendRouter::<R>::quantize_dynamic(tensor, &scheme); // panics
// after
let q = ConcreteBackend::quantize_dynamic(concrete_tensor, &scheme);
Defensive patterns

Strategy: fallback

Validate before calling

fn ensure_dynamic_quant_backend<B: Backend>() -> Result<(), &'static str> {
    Err("quantize_dynamic is not implemented for BackendRouter; use a concrete backend")
}

Type guard

fn is_router_backend_marker<B: Backend>() -> bool {
    std::any::TypeName::<B>().contains("BackendRouter")
}

Try / catch

let q = std::panic::catch_unwind(|| tensor.clone().quantize_dynamic(&scheme))
    .map_err(|_| anyhow::anyhow!("router dynamic quantization is a stub"))?;

Prevention

When it happens

Trigger: Calling quantize_dynamic on a float tensor whose backend is BackendRouter — e.g. dynamic quantization of activations/weights at runtime on a routed backend.

Common situations: Dynamic quantization pipelines run under the router; generic Backend-trait code resolving to BackendRouter; quantization support not yet routed.

Related errors


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