tracel-ai/burn · error

Can't differentiate linear_x_backward.

Error message

Can't differentiate linear_x_backward.

What it means

Dead-code sentinel: `linear_x_backward` is an intentionally unreachable backward op. Burn's linear layer never computes the gradient of its input via this backward-only helper because x's gradient is fused into `linear_backward`; reaching this panic indicates the autodiff graph dispatched a backward step that the module op registry declares impossible.

Solutions

  1. Quantize on the concrete inner backend before routing (quantize weights at build time, route only inference ops that are supported).
  2. Use a backend that implements QTensorOps directly (e.g. the target compute backend) for the quantization step.
  3. Check burn's issue tracker/CHANGELOG for router quantization routing support.

Example fix

// before
let q = tensor_quantize_scheme(&router_backend_tensor, &scheme); // panics
// after
let q = tensor_quantize_scheme(&concrete_backend_tensor, &scheme);
Defensive patterns

Strategy: fallback

Validate before calling

fn ensure_quantize_target<B: Backend>(b: &B) -> Result<(), &'static str> {
    // BackendRouter::quantize is unimplemented
    Err("quantize() 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(&scheme, qparams))
    .map_err(|_| anyhow::anyhow!("router quantize is a stub; switch backends"))?;

Prevention

When it happens

Trigger: Calling Tensor::quantize / quantize() on a tensor whose backend is BackendRouter — e.g. quantizing a model on a routed backend.

Common situations: Post-training quantization of models running through burn-router; generic Backend code where the router is selected; version mismatches where quantization isn't yet routed.

Related errors


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

Appendix: source

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

                    let x_state = weight_tracked.then(|| prep.checkpoint(&x));
                    let weight_state = x_tracked.then(|| prep.checkpoint(&weight));
                    prep.finish(
                        (x_state, weight_state),
                        B::linear(x.primitive, weight.primitive, None),
                    )
                }
                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>,

View on GitHub (pinned to d16f7ba2ed)