Skip to content

Commit 25b3d63

Browse files
NXP backend: Update aot_neutron_compile.py example pipeline (#14142)
### Summary Updates example in `aot_neutron_compile.py` to reflect current state of NXP backend. RemoveIOQuantOpsPass call is moved to NeutronEdgePassManager. `export_to_edge()` is replaced by `to_edge_transform_and_lower()` call. ### Test plan AOT examples should run automatically in CI. You can manually test it using `backends/nxp/run_aot_example.sh` cc @digantdesai @JakeStevens @robert-kalmar @MartinPavella @roman-janik-nxp --------- Co-authored-by: Roman Janik <[email protected]>
1 parent b3f3111 commit 25b3d63

File tree

3 files changed

+45
-48
lines changed

3 files changed

+45
-48
lines changed

backends/nxp/edge_passes/neutron_edge_pass_manager.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
MoveTrailingAuxiliaryOperatorIntoSeparateQDQClusterPass,
1111
)
1212
from executorch.backends.nxp.edge_passes.neutron_edge_pass import NeutronEdgePass
13+
14+
from executorch.backends.nxp.edge_passes.remove_io_quant_ops_pass import (
15+
RemoveIOQuantOpsPass,
16+
)
1317
from executorch.exir import EdgeProgramManager
1418
from executorch.exir.program._program import (
1519
_get_updated_graph_signature,
@@ -24,7 +28,9 @@
2428

2529
class NeutronEdgePassManager(PassManager):
2630

27-
def __init__(self, passes: list[NeutronEdgePass] = None):
31+
def __init__(
32+
self, passes: list[NeutronEdgePass] = None, remove_io_quant_ops: bool = False
33+
):
2834
passes: list[NeutronEdgePass] = passes or [
2935
MoveLeadingAuxiliaryOperatorIntoSeparateQDQClusterPass(),
3036
MoveTrailingAuxiliaryOperatorIntoSeparateQDQClusterPass(),
@@ -35,6 +41,8 @@ def __init__(self, passes: list[NeutronEdgePass] = None):
3541
steps=10, # Empirical value. At most 10 cycles of passes will be run.
3642
)
3743

44+
self.remove_io_quant_ops = remove_io_quant_ops
45+
3846
def _transform_graph_module(self, module: nn.Module) -> PassResult:
3947
"""Apply the passes to a single graph module."""
4048
pass_result: PassResult = super().__call__(module)
@@ -78,12 +86,17 @@ def __call__(self, epm: EdgeProgramManager) -> EdgeProgramManager:
7886

7987
new_programs[name] = new_program
8088

81-
if len(new_programs) == 0:
82-
# No passes were run, return the old EdgeProgramManager.
83-
return epm
89+
result = epm
8490

85-
else:
86-
# Return a new EdgeProgramManager with the updated programs.
87-
return EdgeProgramManager(
91+
if len(new_programs) > 0:
92+
# Use a new EdgeProgramManager with the updated programs if any update was performed.
93+
result = EdgeProgramManager(
8894
new_programs, copy.deepcopy(epm._config_methods), epm.compile_config
8995
)
96+
97+
if self.remove_io_quant_ops:
98+
result = result.transform(
99+
[RemoveIOQuantOpsPass(edge_program_manager=result)]
100+
)
101+
102+
return result

backends/nxp/tests/executorch_pipeline.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,6 @@
1515
from executorch.backends.nxp.edge_passes.neutron_edge_pass_manager import (
1616
NeutronEdgePassManager,
1717
)
18-
from executorch.backends.nxp.edge_passes.remove_io_quant_ops_pass import (
19-
RemoveIOQuantOpsPass,
20-
)
2118
from executorch.backends.nxp.neutron_partitioner import NeutronPartitioner
2219
from executorch.backends.nxp.nxp_backend import generate_neutron_compile_spec
2320
from executorch.backends.nxp.quantizer.neutron_quantizer import NeutronQuantizer
@@ -115,7 +112,9 @@ def to_quantized_edge_program(
115112
edge_compile_config=edge_compile_config,
116113
)
117114

118-
edge_program_manager = NeutronEdgePassManager()(edge_program_manager)
115+
edge_program_manager = NeutronEdgePassManager(
116+
remove_io_quant_ops=remove_quant_io_ops
117+
)(edge_program_manager)
119118

120119
compile_spec = generate_neutron_compile_spec(
121120
target,
@@ -125,11 +124,6 @@ def to_quantized_edge_program(
125124
partitioner = NeutronPartitioner(compile_spec, custom_delegation_options)
126125
edge_program_manager = edge_program_manager.to_backend(partitioner)
127126

128-
if remove_quant_io_ops:
129-
edge_program_manager = edge_program_manager.transform(
130-
[RemoveIOQuantOpsPass(edge_program_manager=edge_program_manager)]
131-
)
132-
133127
return edge_program_manager
134128

135129

examples/nxp/aot_neutron_compile.py

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
import executorch.kernels.quantized # noqa F401
1616

1717
import torch
18-
from executorch.backends.nxp.edge_passes.remove_io_quant_ops_pass import (
19-
RemoveIOQuantOpsPass,
18+
from executorch.backends.nxp.edge_passes.neutron_edge_pass_manager import (
19+
NeutronEdgePassManager,
2020
)
2121
from executorch.backends.nxp.neutron_partitioner import NeutronPartitioner
2222
from executorch.backends.nxp.nxp_backend import generate_neutron_compile_spec
@@ -33,7 +33,6 @@
3333
from torchao.quantization.pt2e.quantize_pt2e import convert_pt2e, prepare_pt2e
3434

3535
from .experimental.cifar_net.cifar_net import CifarNet, test_cifarnet_model
36-
3736
from .models.mobilenet_v2 import MobilenetV2
3837

3938
FORMAT = "[%(levelname)s %(asctime)s %(filename)s:%(lineno)s] %(message)s"
@@ -228,7 +227,7 @@ def _get_batch_size(data):
228227

229228
module = exported_program.module()
230229

231-
# 4. Quantize if required
230+
# 3. Quantize if required
232231
if args.quantize:
233232
if calibration_inputs is None:
234233
logging.warning(
@@ -254,39 +253,30 @@ def _get_batch_size(data):
254253
quantized_str = "quantized " if args.quantize else ""
255254
print(f"\nAccuracy of the {quantized_str}`{args.model_name}`: {accuracy}\n")
256255

257-
# 5. Export to edge program
258-
partitioner_list = []
259-
if args.delegate is True:
260-
partitioner_list = [
261-
NeutronPartitioner(
262-
generate_neutron_compile_spec(
263-
args.target,
264-
args.neutron_converter_flavor,
265-
operators_not_to_delegate=args.operators_not_to_delegate,
266-
)
267-
)
268-
]
256+
# 4. Transform and lower
257+
258+
compile_spec = generate_neutron_compile_spec(
259+
args.target,
260+
operators_not_to_delegate=args.operators_not_to_delegate,
261+
neutron_converter_flavor=args.neutron_converter_flavor,
262+
)
263+
partitioners = [NeutronPartitioner(compile_spec)] if args.delegate else []
269264

270-
edge_program = to_edge_transform_and_lower(
265+
edge_program_manager = to_edge_transform_and_lower(
271266
export(module, example_inputs, strict=True),
272-
partitioner=partitioner_list,
273-
compile_config=EdgeCompileConfig(
274-
_check_ir_validity=False,
275-
),
267+
partitioner=partitioners,
268+
compile_config=EdgeCompileConfig(),
276269
)
277-
logging.debug(f"Exported graph:\n{edge_program.exported_program().graph}")
278270

279-
if args.remove_quant_io_ops:
280-
edge_program = edge_program.transform(
281-
[RemoveIOQuantOpsPass(edge_program_manager=edge_program)]
282-
)
283-
logging.debug(
284-
f"Exported graph (RemoveIOQuantOpsPass):\n{edge_program.exported_program().graph}"
285-
)
271+
edge_program_manager = NeutronEdgePassManager(
272+
remove_io_quant_ops=args.remove_quant_io_ops
273+
)(edge_program_manager)
274+
275+
logging.debug(f"Lowered graph:\n{edge_program_manager.exported_program().graph}")
286276

287-
# 6. Export to ExecuTorch program
277+
# 5. Export to ExecuTorch program
288278
try:
289-
exec_prog = edge_program.to_executorch(
279+
exec_prog = edge_program_manager.to_executorch(
290280
config=ExecutorchBackendConfig(extract_delegate_segments=False)
291281
)
292282
except RuntimeError as e:
@@ -306,7 +296,7 @@ def executorch_program_to_str(ep, verbose=False):
306296

307297
logging.debug(f"Executorch program:\n{executorch_program_to_str(exec_prog)}")
308298

309-
# 7. Serialize to *.pte
299+
# 6. Serialize to *.pte
310300
model_name = f"{args.model_name}" + (
311301
"_nxp_delegate" if args.delegate is True else ""
312302
)

0 commit comments

Comments
 (0)