huggingface/candle · error

only 2d MaxPool is supported, strides {strides:?}

Error message

only 2d MaxPool is supported, strides {strides:?}

What it means

Raised by the ONNX MaxPool evaluator when a 'strides' attribute is present but does not have exactly two entries. Valid strides are None (stride 1) or a pair [s1, s2] passed to max_pool2d_with_stride; any other length (1D/3D pooling) bails.

Source

Thrown at candle-onnx/src/eval.rs:504

                        bail!("MaxPool with dilation != 1, {dilations:?}")
                    }
                }
                if let Some(d) = pads {
                    if d.iter().any(|&v| v != 0) {
                        bail!("MaxPool with pads != 0, {pads:?}")
                    }
                }
                let xs = get(&node.input[0])?;
                let (k1, k2) = match kernel_shape {
                    [k1, k2] => (*k1 as usize, *k2 as usize),
                    _ => bail!("only 2d MaxPool is supported, kernel shape {kernel_shape:?}"),
                };
                let ys = match strides {
                    None => xs.max_pool2d((k1, k2))?,
                    Some([s1, s2]) => {
                        xs.max_pool2d_with_stride((k1, k2), (*s1 as usize, *s2 as usize))?
                    }
                    Some(strides) => bail!("only 2d MaxPool is supported, strides {strides:?}"),
                };
                values.insert(node.output[0].clone(), ys);
            }
            "AveragePool" => {
                // https://github.com/onnx/onnx/blob/main/docs/Operators.md#AveragePool
                let dilations = get_attr_opt::<[i64]>(node, "dilations")?;
                let kernel_shape = get_attr::<[i64]>(node, "kernel_shape")?;
                let pads = get_attr_opt::<[i64]>(node, "pads")?;
                let strides = get_attr_opt::<[i64]>(node, "strides")?;
                let auto_pad = get_attr_opt::<str>(node, "auto_pad")?;
                match auto_pad {
                    None | Some("NOTSET") => (),
                    Some(s) => bail!("unsupported auto_pad {s}"),
                };
                if let Some(d) = dilations {
                    if d.iter().any(|&v| v != 1) {
                        bail!("AvgPool with dilation != 1, {dilations:?}")
                    }

View on GitHub (pinned to d5fee525bf)

Solutions

  1. Ensure the MaxPool node uses 2D strides (two entries) matching the 2D kernel
  2. Drop the strides attribute if stride 1 is acceptable

Example fix

# before
strides: [2]
# after
strides: [1, 2]
Defensive patterns

Strategy: validation

Validate before calling

fn ensure_2d_strides(strides: Option<&[i64]>) -> Result<(), String> {
    match strides {
        Some(s) if s.len() != 2 => Err(format!("strides {:?} not 2d", s)),
        _ => Ok(()),
    }
}

Type guard

fn strides_supported(s: Option<&[i64]>) -> bool { s.map_or(true, |s| s.len() == 2) }

Try / catch

match simple_eval(&model, inputs) {
    Ok(v) => v,
    Err(e) if e.to_string().contains("only 2d MaxPool is supported, strides") => {
        eprintln!("use two-element strides: {}", e); Default::default()
    }
    Err(e) => return Err(e.into()),
}

Prevention

When it happens

Trigger: MaxPool node with strides attribute of length != 2, e.g. [2] or [2, 2, 2].

Common situations: 1-D/3-D pooling models, same as kernel-rank mismatch; converters emitting per-axis strides for 1-D pooling.

Related errors


AI-assisted analysis of huggingface/candle@d5fee525bf (2026-09-02). Data as JSON: /api/errors/d3a5b20abc9b820b. Report an issue: GitHub.