Skip to content

Quantized Conv1d with even kernel + padding="same" produces incorrect XNNPACK output #20558

Description

@JakeStevens

🐛 Describe the bug

A statically-quantized nn.Conv1d with an even kernel_size and padding="same" lowers without error but produces numerically wrong results on the XNNPACK delegate. Odd kernels are fine. This is independent of the constant_pad_nd-fold work — I verified it reproduces with byte-identical error on the commit before any of that code.

import torch
from torch.export import export
from executorch.exir import to_edge_transform_and_lower
from executorch.backends.xnnpack.partition.xnnpack_partitioner import XnnpackPartitioner
from executorch.backends.xnnpack.quantizer.xnnpack_quantizer import (
    XNNPACKQuantizer, get_symmetric_quantization_config,
)
from executorch.extension.pybindings.portable_lib import _load_for_executorch_from_buffer
from torchao.quantization.pt2e.quantize_pt2e import convert_pt2e, prepare_pt2e

def run(kernel_size):
    class M(torch.nn.Module):
        def __init__(self):
            super().__init__()
            self.conv = torch.nn.Conv1d(2, 4, kernel_size=kernel_size, padding="same")
        def forward(self, x):
            return self.conv(x)

    ex = (torch.randn(1, 2, 16),)
    model = export(M().eval(), ex).module()
    q = XNNPACKQuantizer().set_global(get_symmetric_quantization_config())
    m = prepare_pt2e(model, q); m(*ex); m = convert_pt2e(m)
    prog = to_edge_transform_and_lower(export(m, ex), partitioner=[XnnpackPartitioner()]).to_executorch()
    et = _load_for_executorch_from_buffer(prog.buffer)
    diff = (et([*ex])[0] - m(*ex)).abs().max().item()
    print(f"kernel_size={kernel_size}: max abs diff = {diff:.5f}")

run(3)  # odd  -> 0.00000  (correct, quant noise only)
run(4)  # even -> ~1.4     (WRONG)

Observed: kernel_size=3 → 0.00000; kernel_size=4 → ~1.4 max abs diff vs the quantized reference.
Expected: even-kernel diff comparable to odd (small quant noise).

Versions

Mainline

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions