Skip to content

Commit adaaa8b

Browse files
authored
XNNPACK: Run recommended pre-partition transforms in AOT flow (pytorch#20446)
Wire get_transform_passes() into the XNNPACK example AOT compiler so official exports run the same recommended pre-partition graph transforms used by tests. Update XNNPACK docs and README snippets to show the optional transform_passes stage and clarify that it is recommended in general for XNNPACK before partitioning. cc @GregoryComer @digantdesai @cbilgin @freddan80 @per @zingo @oscarandersson8218 @Sebastian-Larsson @robell @rascani Signed-off-by: Måns Nilsson <mans.nilsson@arm.com>
1 parent a2ae4b3 commit adaaa8b

5 files changed

Lines changed: 23 additions & 0 deletions

File tree

‎backends/xnnpack/README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import torchvision.models as models
4646
from torch.export import export, ExportedProgram
4747
from torchvision.models.mobilenetv2 import MobileNet_V2_Weights
4848
from executorch.backends.xnnpack.partition.xnnpack_partitioner import XnnpackPartitioner
49+
from executorch.backends.xnnpack.utils.configs import get_transform_passes
4950
from executorch.exir import EdgeProgramManager, ExecutorchProgramManager, to_edge
5051
from executorch.exir.backend.backend_api import to_backend
5152

@@ -56,6 +57,8 @@ sample_inputs = (torch.randn(1, 3, 224, 224), )
5657
exported_program: ExportedProgram = export(mobilenet_v2, sample_inputs)
5758
edge: EdgeProgramManager = to_edge(exported_program)
5859

60+
# Optional in the generic API, but recommended for XNNPACK before partitioning.
61+
edge = edge.transform(get_transform_passes())
5962
edge = edge.to_backend(XnnpackPartitioner())
6063
```
6164

‎docs/source/backends/xnnpack/xnnpack-overview.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import torch
3232
import torchvision.models as models
3333
from torchvision.models.mobilenetv2 import MobileNet_V2_Weights
3434
from executorch.backends.xnnpack.partition.xnnpack_partitioner import XnnpackPartitioner
35+
from executorch.backends.xnnpack.utils.configs import get_transform_passes
3536
from executorch.exir import to_edge_transform_and_lower
3637

3738
mobilenet_v2 = models.mobilenetv2.mobilenet_v2(weights=MobileNet_V2_Weights.DEFAULT).eval()
@@ -40,12 +41,18 @@ sample_inputs = (torch.randn(1, 3, 224, 224), )
4041
et_program = to_edge_transform_and_lower(
4142
torch.export.export(mobilenet_v2, sample_inputs),
4243
partitioner=[XnnpackPartitioner()],
44+
transform_passes=get_transform_passes(),
4345
).to_executorch()
4446

4547
with open("mv2_xnnpack.pte", "wb") as file:
4648
et_program.write_to_file(file)
4749
```
4850

51+
The `transform_passes` stage is optional in the generic lowering API. For
52+
XNNPACK, `get_transform_passes()` is recommended in general because it runs
53+
pre-partition graph transforms that expose supported patterns to the
54+
partitioner.
55+
4956
See [Partitioner API](/backends/xnnpack/xnnpack-partitioner) for a reference on available partitioner options. <!-- @lint-ignore -->
5057

5158
----

‎docs/source/backends/xnnpack/xnnpack-quantization.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import torchvision.models as models
3131
from torchvision.models.mobilenetv2 import MobileNet_V2_Weights
3232
from executorch.backends.xnnpack.quantizer.xnnpack_quantizer import XNNPACKQuantizer, get_symmetric_quantization_config
3333
from executorch.backends.xnnpack.partition.xnnpack_partitioner import XnnpackPartitioner
34+
from executorch.backends.xnnpack.utils.configs import get_transform_passes
3435
from executorch.exir import to_edge_transform_and_lower
3536
from torchao.quantization.pt2e.quantize_pt2e import convert_pt2e, prepare_pt2e
3637

@@ -52,9 +53,15 @@ quantized_model = convert_pt2e(prepared_model) # (5)
5253
et_program = to_edge_transform_and_lower( # (6)
5354
torch.export.export(quantized_model, sample_inputs),
5455
partitioner=[XnnpackPartitioner()],
56+
transform_passes=get_transform_passes(),
5557
).to_executorch()
5658
```
5759

60+
The `transform_passes` stage is optional in the generic lowering API. For
61+
XNNPACK, `get_transform_passes()` is recommended in general because it runs
62+
pre-partition graph transforms that expose supported patterns to the
63+
partitioner.
64+
5865
See [PyTorch 2 Export Post Training Quantization](https://docs.pytorch.org/ao/main/tutorials_source/pt2e_quant_ptq.html) for more information.
5966

6067
### LLM quantization with quantize_

‎examples/xnnpack/README.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ examples/xnnpack
1818
## Delegating a Floating-point Model
1919

2020
The following command will produce a floating-point XNNPACK delegated model `mv2_xnnpack_fp32.pte` that can be run using XNNPACK's operators. It will also print out the lowered graph, showing what parts of the models have been lowered to XNNPACK via `executorch_call_delegate`.
21+
The compiler uses the optional pre-partition transform stage. For XNNPACK this
22+
is recommended in general because it exposes supported patterns to the
23+
partitioner before delegation decisions are made.
2124

2225
```bash
2326
# For MobileNet V2

‎examples/xnnpack/aot_compiler.py‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Copyright (c) Meta Platforms, Inc. and affiliates.
22
# All rights reserved.
3+
# Copyright 2026 Arm Limited and/or its affiliates.
34
#
45
# This source code is licensed under the BSD-style license found in the
56
# LICENSE file in the root directory of this source tree.
@@ -13,6 +14,7 @@
1314

1415
import torch
1516
from executorch.backends.xnnpack.partition.xnnpack_partitioner import XnnpackPartitioner
17+
from executorch.backends.xnnpack.utils.configs import get_transform_passes
1618
from executorch.exir import (
1719
EdgeCompileConfig,
1820
ExecutorchBackendConfig,
@@ -106,6 +108,7 @@
106108
edge = to_edge_transform_and_lower(
107109
ep,
108110
partitioner=[XnnpackPartitioner()],
111+
transform_passes=get_transform_passes(),
109112
compile_config=EdgeCompileConfig(
110113
_check_ir_validity=False if args.quantize else True,
111114
_skip_dim_order=True, # TODO(T182187531): enable dim order in xnnpack

0 commit comments

Comments
 (0)