{"record":{"id":"eb30934dfba11ce4","repo":"huggingface/candle","slug":"backward-not-supported-for-non-uniform-upscaling-f","errorCode":null,"errorMessage":"backward not supported for non uniform upscaling factors","messagePattern":"backward not supported for non uniform upscaling factors","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-core/src/backprop.rs","lineNumber":403,"sourceCode":"                        let kernel = Tensor::ones((c, 1, scale), arg.dtype(), arg.device())?;\n                        let conv_sum = grad.conv1d(&kernel, 0, scale, 1, c)?;\n                        let sum_grad = grads.or_insert(arg)?;\n                        *sum_grad = conv_sum;\n                    }\n                    Op::UpsampleNearest2D {\n                        arg,\n                        target_h,\n                        target_w,\n                    } => {\n                        let (_n, c, h, w) = arg.dims4()?;\n                        if target_h % h != 0 || target_w % w != 0 {\n                            crate::bail!(\"backward not supported for non integer upscaling factors\")\n                        }\n                        let scale_h = target_h / h;\n                        let scale_w = target_w / w;\n\n                        if scale_h != scale_w {\n                            crate::bail!(\"backward not supported for non uniform upscaling factors\")\n                        };\n                        let kernel =\n                            Tensor::ones((c, 1, scale_h, scale_w), arg.dtype(), arg.device())?;\n                        let conv_sum = grad.conv2d(&kernel, 0, scale_h, 1, c)?;\n                        let sum_grad = grads.or_insert(arg)?;\n                        *sum_grad = conv_sum;\n                    }\n                    Op::UpsampleBilinear2D { .. } => {\n                        crate::bail!(\"backward not supported for upsample_bilinear2d\")\n                    }\n                    Op::SliceScatter0(lhs, rhs, start_rhs) => {\n                        let rhs_sum_grad = grads.or_insert(rhs)?;\n                        let rhs_grad = grad.narrow(0, *start_rhs, rhs.dim(0)?)?;\n                        *rhs_sum_grad = rhs_sum_grad.add(&rhs_grad)?;\n\n                        let lhs_sum_grad = grads.or_insert(lhs)?;\n                        let lhs_grad = grad.slice_scatter0(&rhs.zeros_like()?, *start_rhs)?;\n                        *lhs_sum_grad = lhs_sum_grad.add(&lhs_grad)?","sourceCodeStart":385,"sourceCodeEnd":421,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-core/src/backprop.rs#L385-L421","documentation":"Even when both height and width scale factors are integers, candle additionally requires them to be equal (uniform scaling) for the UpsampleNearest2D backward, because the gradient is accumulated with a single square kernel Tensor::ones((c,1,scale_h,scale_w)) fed to conv2d whose stride is set to scale_h. scale_h != scale_w would corrupt that computation, so candle bails.","triggerScenarios":"backward() over Op::UpsampleNearest2D where target_h/h != target_w/w, e.g. Tensor::upsample_nearest2d(&t, 8, 12) on input with h=2,w=3 (scale 4 vs 4 is fine, but h=2,w=2 with target 8x12 gives 4 vs 6).","commonSituations":"Non-square feature maps upsampled with different aspect ratios; models ported from PyTorch that use nn.Upsample(scale_factor=(2.0, 3.0)) or explicit size with anisotropic scaling.","solutions":["Use uniform scale factors so target_h/h == target_w/w (e.g. 2x2, 4x4 upscaling).","Split the anisotropic upscale into consecutive uniform steps if the scales share a common factor.","Register a custom backward implementation for anisotropic nearest upsampling.","Avoid the upsample in autograd contexts: treat it as a fixed preprocessing step outside the graph and drop its gradient."],"exampleFix":"// before\nlet up = x.upsample_nearest2d(8, 12)?; // scale_h=4, scale_w=6 -> non uniform\n// after\nlet up = x.upsample_nearest2d(8, 8)?;  // uniform 4x scaling","handlingStrategy":"validation","validationCode":"let (_n, _c, h, w) = x.dims4()?;\nif target_h % h != 0 || target_w % w != 0 || (target_h / h) != (target_w / w) {\n    return Err(anyhow::anyhow!(\"backward requires uniform integer upscaling: got scale_h={} scale_w={}\", target_h / h, target_w / w));\n}","typeGuard":null,"tryCatchPattern":"match result { Err(e) if e.to_string().contains(\"non uniform upscaling\") => { // switch to uniform scale or detach\n}, other => other?, }","preventionTips":["Use a single scale_factor variable instead of separate (scale_h, scale_w) configs.","Reject anisotropic upsample configs at model-construction time.","Document that candle nearest-2D backward only supports square integer scales."],"tags":["autograd","tensor","shape-mismatch","rust"],"backgroundTag":"non-uniform-upscale-factor","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}