Unsupported node types fail to lower with “KeyError”
@winskuo-quic is already working on this.
Since Aug 25, 2025.
- Dominant language
- Python
- Stars
- 5k
- Forks
- 1.2k
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 581
Description
🐛 Describe the bug
When the QNN practitioner encounters a node that it does not have a visitor for, it fails with an internal error. Ideally, the partitioner should just not partition any unknown nodes without error, in order to allow them to fall back to the ExecuTorch portable library or another fallback backend.
Here are the operators that I've seen fail in this manner:
aten._adaptive_avg_pool3d.default, aten.adaptive_max_pool2d.default, aten.avg_pool3d.default, aten.div.Tensor_mode, aten.index_select.default, aten.log10.default, aten.log1p.default, aten.log2.default, aten.flip.default, aten.max_pool3d_with_indices.default, aten.median.default, aten.median.dim, aten.round.decimals, aten.le.Scalar, aten.trunc.default.
To clarify, QNN does not need implementations for these. We just want to be able to partially delegate models containing these operators.
I've included a small example model, along with the current stack trace. The current behavior is that the lowering process errors out. The expected behavior is that the partitioning process (via to_edge_transform_and_lower) completes without error and does not partition the unsupported nodes.
Example model:
class Model(torch.nn.Module):
def __init__(
self,
output_size=(5, 5),
return_indices=False,
):
super().__init__()
self.adaptive_maxpool = torch.nn.AdaptiveMaxPool2d(
output_size=output_size,
return_indices=return_indices,
)
def forward(self, x):
return self.adaptive_maxpool(x)
Example stack trace:
2025-08-22T03:10:31.0328184Z tester.to_edge_transform_and_lower(generate_etrecord=True)
2025-08-22T03:10:31.0329014Z File "/pytorch/executorch/src/executorch/backends/test/harness/tester.py", line 220, in to_edge_transform_and_lower
...
2025-08-22T03:10:31.0348091Z File "/opt/conda/envs/py_3.10/lib/python3.10/site-packages/torch/fx/passes/infra/partitioner.py", line 226, in propose_partitions
2025-08-22T03:10:31.0348951Z if self._is_node_supported(node) and node not in assignment:
2025-08-22T03:10:31.0349808Z File "/opt/conda/envs/py_3.10/lib/python3.10/site-packages/torch/fx/passes/infra/partitioner.py", line 87, in _is_node_supported
2025-08-22T03:10:31.0350642Z return self.operator_support.is_node_supported(
2025-08-22T03:10:31.0351458Z File "/pytorch/executorch/src/executorch/backends/qualcomm/partition/qnn_partitioner.py", line 100, in is_node_supported
2025-08-22T03:10:31.0352355Z op_wrapper = self.node_visitors[node.target.__name__].define_node(
2025-08-22T03:10:31.0352836Z KeyError: 'aten.adaptive_max_pool2d.default'
With the QNN AOT bits set up and executorch installation run with QNN, you can also repro with
python -m executorch.backends.test.suite.runner -m operators --filter test_adaptive_maxpool2d_dtype_float32_qnn
Versions
Commit 335de46fa76866a76599def5e34296f0ee5f6106
cc @cccclai @cbilgin
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.