pytorch / pytorch/executorch

QNN Avg and Max pool with ceil_mode=True appear to have incorrect outputs

Open
#13,612 3 comments 0 reactions 4 assignees View on GitHub

@winskuo-quic is already working on this.

Since Aug 25, 2025.

backend tester module: qnn
Dominant language
Python
Stars
5k
Forks
1.2k
Avg merge
2d 10h
Merged PRs (30d)
581

Description

🐛 Describe the bug

When running avg and max pool operators with ceil_mode=True, many output elements are zero. There appears to be an error in the computation.

Example output:

Eager: tensor([[[[ 0.2050, -0.1577,  0.7572],
          [-0.1823,  0.8233, -0.7934],
          [ 0.6227, -0.0854, -1.4602]],

         [[-0.0229, -0.0853,  0.0022],
          [-0.0799,  0.1280, -0.8410],
          [ 0.0817, -0.0908, -0.5292]]]])
QNN: tensor([[[[ 0.2048, -0.1576,  0.0000],
          [-0.1823,  0.8232,  0.0000],
          [ 0.0000,  0.0000,  0.0000]],

         [[-0.0229, -0.0851,  0.0000],
          [-0.0798,  0.1281,  0.0000],
          [ 0.0000,  0.0000,  0.0000]]]])

Repro:

import torch

from executorch.backends.qualcomm.utils.utils import (
    generate_htp_compiler_spec,
    generate_qnn_executorch_compiler_spec,
    get_soc_to_chipset_map,
)
from executorch.backends.qualcomm.utils.utils import QcomChipset
from executorch.backends.qualcomm.utils.utils import (
    to_edge_transform_and_lower_to_qnn,
)
from executorch.exir import ExecutorchBackendConfig
from executorch.runtime import Runtime
from typing import Optional, Tuple, List, Union

class Model(torch.nn.Module):
    def __init__(self):
        super().__init__()
        self.pool = torch.nn.AvgPool2d(3, ceil_mode=True)

    def forward(self, x):
        return self.pool(x)

inputs = (torch.randn(1,2,7,7),)
model = Model()

# HTP Compiler Configuration
backend_options = generate_htp_compiler_spec(
    use_fp16=True,
)

# QNN Compiler Spec
compile_spec = generate_qnn_executorch_compiler_spec(
    soc_model=QcomChipset.SM8650,  # Your target SoC
    backend_options=backend_options,
)


# Lower to QNN backend
delegated_program = to_edge_transform_and_lower_to_qnn(
    model,
    inputs,
    compile_spec
)

# Export to ExecuTorch format
executorch_program = delegated_program.to_executorch(
    config=ExecutorchBackendConfig(extract_delegate_segments=False)
)

runtime = Runtime.get()
program = runtime.load_program(executorch_program.buffer)
method = program.load_method("forward")
output: List[torch.Tensor] = method.execute([*inputs])

print(f"Eager: {model(*inputs)}")
print(f"QNN: {output[0]}")
Versions

Commit 335de46fa76866a76599def5e34296f0ee5f6106

cc @cccclai @cbilgin

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.