Skip to content

Commit ce377b7

Browse files
Unify pipeline workflow, use to_edge_transform_and_lower() in executorch_pipeline.py, fix edge pass manager usage
1 parent c7e04e4 commit ce377b7

File tree

3 files changed

+27
-95
lines changed

3 files changed

+27
-95
lines changed

backends/nxp/edge_passes/neutron_edge_pass_manager.py

Lines changed: 1 addition & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -3,34 +3,17 @@
33
# This source code is licensed under the BSD-style license found in the
44
# LICENSE file in the root directory of this source tree.
55

6-
import copy
7-
86
from executorch.backends.nxp.edge_passes.move_auxiliary_operator_into_separate_qdq_cluster_pass import (
97
MoveLeadingAuxiliaryOperatorIntoSeparateQDQClusterPass,
108
MoveTrailingAuxiliaryOperatorIntoSeparateQDQClusterPass,
119
)
1210
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-
)
17-
from executorch.exir import EdgeProgramManager
18-
from executorch.exir.program._program import (
19-
_get_updated_graph_signature,
20-
_get_updated_range_constraints,
21-
)
22-
23-
from torch import nn
24-
from torch.export import ExportedProgram
25-
from torch.fx.passes.infra.pass_base import PassResult
2611
from torch.fx.passes.infra.pass_manager import PassManager
2712

2813

2914
class NeutronEdgePassManager(PassManager):
3015

31-
def __init__(
32-
self, passes: list[NeutronEdgePass] = None, remove_io_quant_ops: bool = False
33-
):
16+
def __init__(self, passes: list[NeutronEdgePass] = None):
3417
passes: list[NeutronEdgePass] = passes or [
3518
MoveLeadingAuxiliaryOperatorIntoSeparateQDQClusterPass(),
3619
MoveTrailingAuxiliaryOperatorIntoSeparateQDQClusterPass(),
@@ -40,63 +23,3 @@ def __init__(
4023
passes,
4124
steps=10, # Empirical value. At most 10 cycles of passes will be run.
4225
)
43-
44-
self.remove_io_quant_ops = remove_io_quant_ops
45-
46-
def _transform_graph_module(self, module: nn.Module) -> PassResult:
47-
"""Apply the passes to a single graph module."""
48-
pass_result: PassResult = super().__call__(module)
49-
50-
graph_module = pass_result.graph_module
51-
graph_module.graph.eliminate_dead_code()
52-
graph_module.recompile()
53-
54-
return pass_result
55-
56-
def __call__(self, epm: EdgeProgramManager) -> EdgeProgramManager:
57-
"""Apply the passes to all graph modules in the edge program."""
58-
new_programs: dict[str, ExportedProgram] = {}
59-
60-
for name, program in epm._edge_programs.items():
61-
pass_result = self._transform_graph_module(program.graph_module)
62-
63-
if pass_result.modified:
64-
# Create a new exported program.
65-
new_program = ExportedProgram(
66-
root=pass_result.graph_module,
67-
graph=pass_result.graph_module.graph,
68-
graph_signature=_get_updated_graph_signature(
69-
program.graph_signature, pass_result.graph_module
70-
),
71-
state_dict=program.state_dict,
72-
range_constraints=_get_updated_range_constraints(
73-
pass_result.graph_module
74-
),
75-
module_call_graph=copy.deepcopy(program._module_call_graph),
76-
example_inputs=program.example_inputs,
77-
constants=program.constants,
78-
verifiers=[program.verifier],
79-
)
80-
new_program.graph_module.meta.update(program.graph_module.meta)
81-
new_program.graph_module.meta.update(pass_result.graph_module.meta)
82-
83-
else:
84-
# Keep the old exported program.
85-
new_program = program
86-
87-
new_programs[name] = new_program
88-
89-
result = epm
90-
91-
if len(new_programs) > 0:
92-
# Use a new EdgeProgramManager with the updated programs if any update was performed.
93-
result = EdgeProgramManager(
94-
new_programs, copy.deepcopy(epm._config_methods), epm.compile_config
95-
)
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: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
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+
)
1821
from executorch.backends.nxp.neutron_partitioner import NeutronPartitioner
1922
from executorch.backends.nxp.nxp_backend import generate_neutron_compile_spec
2023
from executorch.backends.nxp.quantizer.neutron_quantizer import NeutronQuantizer
@@ -23,9 +26,10 @@
2326
EdgeProgramManager,
2427
ExecutorchBackendConfig,
2528
ExecutorchProgramManager,
29+
to_edge_transform_and_lower,
2630
)
27-
from executorch.extension.export_util.utils import export_to_edge
2831
from torch import nn
32+
from torch.export import export
2933
from torchao.quantization.pt2e.quantize_pt2e import convert_pt2e, prepare_pt2e
3034

3135

@@ -105,24 +109,24 @@ def to_quantized_edge_program(
105109
calibration_inputs,
106110
)
107111

108-
edge_compile_config = EdgeCompileConfig(_check_ir_validity=False)
109-
edge_program_manager = export_to_edge(
110-
exir_program_aten__module_quant,
111-
example_input,
112-
edge_compile_config=edge_compile_config,
113-
)
114-
115-
edge_program_manager = NeutronEdgePassManager(
116-
remove_io_quant_ops=remove_quant_io_ops
117-
)(edge_program_manager)
118-
119112
compile_spec = generate_neutron_compile_spec(
120113
target,
121114
operators_not_to_delegate=operators_not_to_delegate,
122115
neutron_converter_flavor=neutron_converter_flavor,
123116
)
124-
partitioner = NeutronPartitioner(compile_spec, custom_delegation_options)
125-
edge_program_manager = edge_program_manager.to_backend(partitioner)
117+
partitioners = [NeutronPartitioner(compile_spec, custom_delegation_options)]
118+
119+
edge_program_manager = to_edge_transform_and_lower(
120+
export(exir_program_aten__module_quant, example_input, strict=True),
121+
transform_passes=NeutronEdgePassManager(),
122+
partitioner=partitioners,
123+
compile_config=EdgeCompileConfig(_check_ir_validity=False),
124+
)
125+
126+
if remove_quant_io_ops:
127+
edge_program_manager = edge_program_manager.transform(
128+
[RemoveIOQuantOpsPass(edge_program_manager=edge_program_manager)]
129+
)
126130

127131
return edge_program_manager
128132

examples/nxp/aot_neutron_compile.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@
1818
from executorch.backends.nxp.edge_passes.neutron_edge_pass_manager import (
1919
NeutronEdgePassManager,
2020
)
21+
from executorch.backends.nxp.edge_passes.remove_io_quant_ops_pass import (
22+
RemoveIOQuantOpsPass,
23+
)
2124
from executorch.backends.nxp.neutron_partitioner import NeutronPartitioner
2225
from executorch.backends.nxp.nxp_backend import generate_neutron_compile_spec
2326
from executorch.backends.nxp.quantizer.neutron_quantizer import NeutronQuantizer
@@ -273,13 +276,15 @@ def _get_batch_size(data):
273276

274277
edge_program_manager = to_edge_transform_and_lower(
275278
export(module, example_inputs, strict=True),
279+
transform_passes=NeutronEdgePassManager(),
276280
partitioner=partitioners,
277281
compile_config=EdgeCompileConfig(),
278282
)
279283

280-
edge_program_manager = NeutronEdgePassManager(
281-
remove_io_quant_ops=args.remove_quant_io_ops
282-
)(edge_program_manager)
284+
if args.remove_quant_io_ops:
285+
edge_program_manager = edge_program_manager.transform(
286+
[RemoveIOQuantOpsPass(edge_program_manager=edge_program_manager)]
287+
)
283288

284289
logging.debug(f"Lowered graph:\n{edge_program_manager.exported_program().graph}")
285290

0 commit comments

Comments
 (0)