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
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions