{"record":{"id":"cf30438606d06d30","repo":"tracel-ai/burn","slug":"can-t-differentiate-interpolate-backward","errorCode":null,"errorMessage":"Can't differentiate interpolate backward.","messagePattern":"Can't differentiate interpolate backward\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/burn-autodiff/src/ops/module.rs","lineNumber":1933,"sourceCode":"        {\n            OpsKind::Tracked(mut prep) => {\n                let x_state = prep.checkpoint(&x);\n                let output = B::interpolate(x.primitive.clone(), output_size, options.clone());\n                prep.finish((x_state, output_size, options), output)\n            }\n            OpsKind::UnTracked(prep) => {\n                prep.finish(B::interpolate(x.primitive, output_size, options))\n            }\n        }\n    }\n\n    fn interpolate_backward(\n        _x: FloatTensor<Autodiff<B, C>>,\n        _grad: FloatTensor<Autodiff<B, C>>,\n        _output_size: [usize; 2],\n        _options: InterpolateOptions,\n    ) -> AutodiffTensor<B> {\n        panic!(\"Can't differentiate interpolate backward.\");\n    }\n\n    fn attention(\n        query: FloatTensor<Autodiff<B, C>>,\n        key: FloatTensor<Autodiff<B, C>>,\n        value: FloatTensor<Autodiff<B, C>>,\n        mask: Option<burn_backend::tensor::BoolTensor<Autodiff<B, C>>>,\n        attn_bias: Option<FloatTensor<Autodiff<B, C>>>,\n        options: AttentionModuleOptions,\n    ) -> FloatTensor<Autodiff<B, C>> {\n        attention_fallback::<Self>(query, key, value, mask, attn_bias, options)\n    }\n\n    fn ctc_loss(\n        log_probs: FloatTensor<Autodiff<B, C>>,\n        targets: IntTensor<Autodiff<B, C>>,\n        input_lengths: IntTensor<Autodiff<B, C>>,\n        target_lengths: IntTensor<Autodiff<B, C>>,","sourceCodeStart":1915,"sourceCodeEnd":1951,"githubUrl":"https://github.com/tracel-ai/burn/blob/d16f7ba2ed0d41408189384044cc886fb4c8f957/crates/burn-autodiff/src/ops/module.rs#L1915-L1951","documentation":"interpolate_backward in the autodiff backend panics: gradients through the interpolate (resize) op are not implemented. The forward resize works, but a training step that backpropagates through it hits this panic.","triggerScenarios":"Training any model whose graph contains interpolate (image resize/upsampling, e.g. U-Net upsampling layers) with the autodiff backend.","commonSituations":"Segmentation/upsampling architectures (U-Net style) that resize feature maps; preprocessing inside the differentiable graph; migrating torchvision interpolate-based decoders.","solutions":["Use ConvTranspose2d or conv-based upsampling instead of interpolate inside the trained graph","Implement the resize backward as a composition of supported ops (e.g. gather/unsqueeze/broadcast)","Detach at the resize boundary: resize outside the autodiff graph or call detach() on its input","Use an inner backend whose interpolate backward exists and wrap only supported ops in autodiff"],"exampleFix":"// before\nlet up = interpolate(&x, [64, 64], InterpolateOptions::nearest());\n// after\nlet up = conv_transpose2d(&x, upsample_weight, None, [2, 2], [0, 0], [1, 1]);","handlingStrategy":"fallback","validationCode":"if graph_contains_interpolate && is_training {\n    eprintln!(\"interpolate backward panics in burn-autodiff; use conv_transpose2d or move resize outside the graph\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use conv_transpose2d or pixel-shuffle for learnable upsampling","Perform resizing in preprocessing, outside the differentiable graph","Smoke-test one backward step whenever adding a new op type to the model"],"tags":["rust","autodiff","unimplemented","backward-pass"],"backgroundTag":"unimplemented-op-backward","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"}