{"record":{"id":"6f00deb6fba0c658","repo":"huggingface/candle","slug":"strides-have-to-be-the-same-on-both-axis-pads","errorCode":null,"errorMessage":"strides have to be the same on both axis {pads:?} {}","messagePattern":"strides have to be the same on both axis (.+?) (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"candle-onnx/src/eval.rs","lineNumber":941,"sourceCode":"                                let p2 = p2 as usize;\n                                let p3 = p3 as usize;\n                                let p4 = p4 as usize;\n                                if p1 != p2 || p1 != p3 || p1 != p4 {\n                                    (0, xs.pad_with_zeros(2, p1, p3)?.pad_with_zeros(3, p2, p4)?)\n                                } else {\n                                    (p1, xs.clone())\n                                }\n                            }\n                            Some(pads) => {\n                                bail!(\"more pads than expected in conv2d {pads:?} {}\", node.name)\n                            }\n                        };\n                        let strides = match strides {\n                            None => 1,\n                            Some([p]) => *p as usize,\n                            Some([p1, p2]) => {\n                                if p1 != p2 {\n                                    bail!(\n                                        \"strides have to be the same on both axis {pads:?} {}\",\n                                        node.name\n                                    )\n                                }\n                                *p1 as usize\n                            }\n                            Some(s) => {\n                                bail!(\"more strides than expected in conv2d {s:?} {}\", node.name)\n                            }\n                        };\n                        let dilations = match dilations {\n                            None => 1,\n                            Some([p]) => *p as usize,\n                            Some([p1, p2]) => {\n                                if p1 != p2 {\n                                    bail!(\n                                        \"dilations have to be the same on both axis {pads:?} {}\",\n                                        node.name","sourceCodeStart":923,"sourceCodeEnd":959,"githubUrl":"https://github.com/huggingface/candle/blob/d5fee525bfde3273eb7c9b75fd2bc4937be867ca/candle-onnx/src/eval.rs#L923-L959","documentation":"When a Conv node's `strides` attribute has two values (one per axis), candle-onnx requires them to be equal because it passes a single scalar stride to candle's conv2d. If p1 != p2 the evaluator bails with this message (note the message text mistakenly interpolates `pads`, not strides).","triggerScenarios":"simple_eval encounters a Conv node with 2D weights and strides like [2,1] — different horizontal/vertical strides.","commonSituations":"PyTorch nn.Conv2d(stride=(2,1)) exported to ONNX; detection/segmentation models that downsample asymmetrically; hand-tuned inference graphs.","solutions":["Change the model to use symmetric strides (p1 == p2) and re-export","Insert reshape/pooling ops so a single-stride conv achieves the desired asymmetric downsampling","Patch candle-onnx to pass per-axis strides to candle's conv2d (which supports stride tuples)","Modify the ONNX graph to set strides=[s,s] with s equal on both axes"],"exampleFix":"// before (PyTorch): nn.Conv2d(..., stride=(2, 1))\n// after: nn.Conv2d(..., stride=2)  # then re-export to ONNX","handlingStrategy":"validation","validationCode":"for node in &model.graph.node {\n    if node.op_type == \"Conv\" {\n        if let Some(s) = node.attribute.iter().find(|a| a.name == \"strides\") {\n            if s.ints.len() == 2 && s.ints[0] != s.ints[1] {\n                panic!(\"node {}: asymmetric strides {:?} unsupported\", node.name, s.ints);\n            }\n        }\n    }\n}","typeGuard":"fn has_uniform_strides(attr: &Attribute) -> bool {\n    attr.name != \"strides\" || attr.ints.iter().all(|&s| s == attr.ints[0])\n}","tryCatchPattern":"match candle_onnx::simple_eval(&model, &inputs) {\n    Err(e) if e.to_string().contains(\"strides have to be the same\") => {\n        eprintln!(\"model needs symmetric conv strides: {e}\");\n    }\n    other => other?,\n}","preventionTips":["Avoid stride=(h,w) with h!=w in source models intended for candle-onnx","Lint ONNX graphs for asymmetric strides before inference","Fall back to onnxruntime for models needing asymmetric strides"],"tags":["onnx","conv2d","strides"],"backgroundTag":"unsupported-onnx-attribute","analyzedSha":"d5fee525bfde3273eb7c9b75fd2bc4937be867ca","analyzedAt":"2026-09-02T00:15:47.023Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}