Skip to content

Commit 1e17e28

Browse files
Remove deprecated XNNPACK capture utilities and migrate tests (#18134) (#18134)
Summary: Delete capture_graph_for_xnnpack() and get_xnnpack_capture_config() which were only used in test files and relied on the deprecated exir.capture API. Migrate test_xnnpack_utils.py to use inline to_edge(export(...)) calls. Remove the deprecated exports from xnnpack/__init__.py. Differential Revision: D95605468
1 parent 12fe317 commit 1e17e28

6 files changed

Lines changed: 64 additions & 94 deletions

File tree

backends/xnnpack/__init__.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,17 @@
1212

1313
# Exposed Configs in XNNPACK Package
1414
from .utils.configs import (
15-
get_xnnpack_capture_config,
1615
get_xnnpack_edge_compile_config,
1716
get_xnnpack_executorch_backend_config,
1817
)
1918

20-
# Easy util functions
21-
from .utils.utils import capture_graph_for_xnnpack
22-
2319
# XNNPACK Backend
2420
from .xnnpack_preprocess import XnnpackBackend
2521

2622
__all__ = [
2723
"XnnpackDynamicallyQuantizedPartitioner",
2824
"XnnpackPartitioner",
2925
"XnnpackBackend",
30-
"capture_graph_for_xnnpack",
31-
"get_xnnpack_capture_config",
3226
"get_xnnpack_edge_compile_config",
3327
"get_xnnpack_executorch_backend_config",
3428
]

backends/xnnpack/test/test_xnnpack_utils.py

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010

1111
import torch
1212
import torch.nn.functional as F
13-
from executorch import exir
14-
1513
from executorch.backends.xnnpack.partition.xnnpack_partitioner import (
1614
XnnpackDynamicallyQuantizedPartitioner,
1715
XnnpackPartitioner,
@@ -25,7 +23,6 @@
2523
get_xnnpack_edge_compile_config,
2624
get_xnnpack_executorch_backend_config,
2725
)
28-
from executorch.backends.xnnpack.utils.utils import capture_graph_for_xnnpack
2926

3027
# import the xnnpack backend implementation
3128
from executorch.backends.xnnpack.xnnpack_preprocess import XnnpackBackend
@@ -35,7 +32,7 @@
3532
from executorch.devtools.bundled_program.serialize import (
3633
serialize_from_bundled_program_to_flatbuffer,
3734
)
38-
from executorch.exir import ExecutorchProgram, ExirExportedProgram
35+
from executorch.exir import EdgeProgramManager, to_edge
3936
from executorch.exir.backend.backend_api import to_backend, validation_disabled
4037

4138
from executorch.exir.passes.spec_prop_pass import SpecPropPass
@@ -157,6 +154,14 @@ def assert_outputs_equal(self, model_output, ref_output):
157154
torch.allclose(model_output[0], ref_output, atol=1e-03, rtol=1e-03)
158155
)
159156

157+
def _capture_graph_for_xnnpack(
158+
self, module: torch.nn.Module, sample_inputs: Tuple[torch.Tensor]
159+
) -> EdgeProgramManager:
160+
return to_edge(
161+
export(module, sample_inputs, strict=True),
162+
compile_config=get_xnnpack_edge_compile_config(),
163+
).transform(*get_transform_passes())
164+
160165
def lower_module_and_test_output(
161166
self,
162167
module: Any,
@@ -167,15 +172,15 @@ def lower_module_and_test_output(
167172
# TODO: remove this after we migrate to use long term flow
168173
quantizer_api_test: bool = False,
169174
dump_bundled_program: bool = False, # for debugging, dump the generated bundled program file
170-
) -> ExirExportedProgram:
175+
) -> EdgeProgramManager:
171176
"""
172177
Helper testing function that takes a torch.nn.Module and lowers it to XNNPACK with
173178
the given sample inputs. It then runs the lowered module and compares its
174179
outputs with the outputs of the eager module.
175180
"""
176181

177182
if quantizer_api_test:
178-
assert isinstance(module, ExirExportedProgram)
183+
assert isinstance(module, EdgeProgramManager)
179184
edge_program = module
180185
else:
181186

@@ -187,7 +192,9 @@ def __init__(self):
187192
def forward(self, *args):
188193
return self.one_module(*args)
189194

190-
edge_program = capture_graph_for_xnnpack(WrappedModule(), sample_inputs)
195+
edge_program = self._capture_graph_for_xnnpack(
196+
WrappedModule(), sample_inputs
197+
)
191198

192199
partitioner = None
193200
if quantized:
@@ -201,35 +208,32 @@ def forward(self, *args):
201208
if use_partitioner:
202209
with validation_disabled():
203210
delegated_program = edge_program
204-
delegated_program.exported_program = to_backend(
205-
edge_program.exported_program, partitioner
211+
delegated_program._edge_programs["forward"] = to_backend(
212+
edge_program.exported_program(), partitioner
206213
)
207214

208-
executorch_program: ExecutorchProgram = delegated_program.to_executorch(
215+
executorch_program = delegated_program.to_executorch(
209216
get_xnnpack_executorch_backend_config([SpecPropPass()]),
210217
)
211218
else:
212-
delegated_program = to_backend(
213-
"XnnpackBackend", edge_program.exported_program, []
219+
delegated_module = to_backend(
220+
"XnnpackBackend", edge_program.exported_program(), []
214221
)
215222

216-
exported_program: ExirExportedProgram = capture_graph_for_xnnpack(
217-
delegated_program, sample_inputs
223+
exported_program = self._capture_graph_for_xnnpack(
224+
delegated_module, sample_inputs
218225
)
219-
executorch_program: ExecutorchProgram = exported_program.to_executorch(
226+
executorch_program = exported_program.to_executorch(
220227
get_xnnpack_executorch_backend_config(),
221228
)
222229

223-
# print("Graph Module with delegate:")
224-
# delegated_module.print_readable()
225-
226230
# Assert the backend name is xnnpack
227231
self.assertEqual(
228-
executorch_program.program.execution_plan[0].delegates[0].id,
232+
executorch_program.executorch_program.execution_plan[0].delegates[0].id,
229233
XnnpackBackend.__name__,
230234
)
231235

232-
ref_output = delegated_program(*sample_inputs)
236+
ref_output = delegated_program.exported_program().module()(*sample_inputs)
233237
if dump_bundled_program:
234238
save_bundled_program(
235239
representative_inputs=sample_inputs,
@@ -325,14 +329,9 @@ def quantize_and_test_model_with_quantizer(
325329
prepared = prepare_pt2e(m, quantizer)
326330
converted = convert_pt2e(prepared)
327331

328-
captured_program = exir.capture(
329-
converted,
330-
example_inputs,
331-
config=exir.CaptureConfig(enable_aot=True, _unlift=True),
332-
)
333-
334-
edge_program = captured_program.to_edge(
335-
get_xnnpack_edge_compile_config()
332+
edge_program = to_edge(
333+
export(converted, example_inputs, strict=True),
334+
compile_config=get_xnnpack_edge_compile_config(),
336335
).transform(*get_transform_passes())
337336
delegated_module = self.lower_module_and_test_output(
338337
module=edge_program,
@@ -350,7 +349,7 @@ def quantize_and_test_model_with_quantizer(
350349
}
351350
for op in supported_ops:
352351
FileCheck().check_count(op, 0, exactly=True).run(
353-
delegated_module.exported_program.graph_module.code
352+
delegated_module.exported_program().graph_module.code
354353
)
355354

356355
def _test_xnnpack_dqlinear(
@@ -398,12 +397,14 @@ def _test_xnnpack_dqlinear(
398397
prepared_linear,
399398
)
400399

401-
captured_dqlinear = capture_graph_for_xnnpack(converted_linear, example_inputs)
400+
captured_dqlinear = self._capture_graph_for_xnnpack(
401+
converted_linear, example_inputs
402+
)
402403

403-
captured_dqlinear.exported_program.graph_module.graph.print_tabular()
404+
captured_dqlinear.exported_program().graph_module.graph.print_tabular()
404405

405406
lowered_module = to_backend(
406-
"XnnpackBackend", captured_dqlinear.exported_program, []
407+
"XnnpackBackend", captured_dqlinear.exported_program(), []
407408
)
408409

409410
class CompositeModule(torch.nn.Module):
@@ -417,19 +418,19 @@ def forward(self, x):
417418
composite_model = CompositeModule()
418419
composite_model(*example_inputs)
419420

420-
exported_program: ExirExportedProgram = capture_graph_for_xnnpack(
421+
exported_program = self._capture_graph_for_xnnpack(
421422
composite_model, example_inputs
422423
)
423-
executorch_program: ExecutorchProgram = exported_program.to_executorch(
424+
executorch_program = exported_program.to_executorch(
424425
get_xnnpack_executorch_backend_config(),
425426
)
426427

427428
self.assertEqual(
428-
executorch_program.program.execution_plan[0].delegates[0].id,
429+
executorch_program.executorch_program.execution_plan[0].delegates[0].id,
429430
XnnpackBackend.__name__,
430431
)
431432

432-
ref_output = captured_dqlinear(*example_inputs)
433+
ref_output = captured_dqlinear.exported_program().module()(*example_inputs)
433434
ref_output = composite_model(*example_inputs)
434435
print("ref_output:", ref_output)
435436

backends/xnnpack/utils/configs.py

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
# This source code is licensed under the BSD-style license found in the
55
# LICENSE file in the root directory of this source tree.
66

7-
from typing import List, Optional
7+
from typing import List
88

99
import executorch.exir as exir
10-
from executorch.exir import CaptureConfig
1110
from executorch.exir.pass_manager import PassType
1211

1312

@@ -33,17 +32,3 @@ def get_xnnpack_executorch_backend_config(
3332
passes=additional_passes,
3433
extract_delegate_segments=True,
3534
)
36-
37-
38-
def get_xnnpack_capture_config(
39-
dynamic_shape=False,
40-
enable_aot: Optional[bool] = None,
41-
unlift: Optional[bool] = None,
42-
):
43-
if enable_aot is None:
44-
return CaptureConfig(enable_dynamic_shape=dynamic_shape)
45-
else:
46-
unlift = unlift if unlift is not None else enable_aot
47-
return CaptureConfig(
48-
enable_dynamic_shape=dynamic_shape, enable_aot=enable_aot, _unlift=unlift
49-
)

backends/xnnpack/utils/utils.py

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,8 @@
66

77
from typing import Any, cast, Optional, Tuple
88

9-
import executorch.exir as exir
109
import torch
1110

12-
from executorch.backends.xnnpack.utils.configs import (
13-
get_transform_passes,
14-
get_xnnpack_capture_config,
15-
get_xnnpack_edge_compile_config,
16-
)
1711
from executorch.exir import ExportedProgram
1812
from executorch.exir.dialects._ops import ops as exir_ops
1913

@@ -28,24 +22,6 @@
2822
from torchao.quantization.pt2e.utils import _is_conv_node, _is_conv_transpose_node
2923

3024

31-
### XNNPACK Capture ###
32-
def capture_graph_for_xnnpack(
33-
module: torch.nn.Module,
34-
inputs: Tuple[torch.Tensor],
35-
enable_aot: Optional[bool] = None,
36-
unlift: Optional[bool] = None,
37-
) -> exir.ExirExportedProgram:
38-
return (
39-
exir.capture(
40-
module,
41-
inputs,
42-
get_xnnpack_capture_config(enable_aot=enable_aot, unlift=unlift),
43-
)
44-
.to_edge(get_xnnpack_edge_compile_config())
45-
.transform(*get_transform_passes())
46-
)
47-
48-
4925
### XNNPACK Utils ###
5026
PERM_NCHW_TO_NHWC = [0, 2, 3, 1]
5127
PERM_NHWC_TO_NCHW = [0, 3, 1, 2]

devtools/size_analysis_tool/size_analysis_tool.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,14 @@ def _get_delegate_blob_data(
5656
return delegate_blob_data
5757

5858

59-
def _get_nested_model_data(
59+
def _get_nested_model_data( # noqa: C901
6060
graph_module: torch.fx.GraphModule,
6161
delegate_deserializers: Optional[
6262
Dict[str, Callable[[bytes], Dict[str, Any]]]
6363
] = None,
6464
tensor_data: Optional[List[Dict[str, Any]]] = None,
6565
delegate_blob_data: Optional[List[Dict[str, Any]]] = None,
66+
exported_program: Optional["ExportedProgram"] = None,
6667
) -> Tuple[List[Dict[str, Any]], List[Dict[str, Any]]]:
6768
if tensor_data is None:
6869
tensor_data = []
@@ -71,7 +72,20 @@ def _get_nested_model_data(
7172
delegate_blob_data = []
7273

7374
for node in graph_module.graph.nodes:
74-
if node.op == "get_attr":
75+
if node.op == "placeholder" and exported_program is not None:
76+
sig = exported_program.graph_signature
77+
fqn = None
78+
if node.name in getattr(sig, "inputs_to_parameters", {}):
79+
fqn = sig.inputs_to_parameters[node.name]
80+
elif node.name in getattr(sig, "inputs_to_buffers", {}):
81+
fqn = sig.inputs_to_buffers[node.name]
82+
83+
if fqn is not None:
84+
tensor = exported_program.state_dict.get(fqn)
85+
if isinstance(tensor, torch.Tensor):
86+
tensor_data.append(_get_tensor_data(node, tensor))
87+
88+
elif node.op == "get_attr":
7589
node_attr = getattr(node.graph.owning_module, node.target)
7690
if isinstance(node_attr, torch.Tensor):
7791
tensor_data.append(_get_tensor_data(node, node_attr))
@@ -105,7 +119,7 @@ def generate_model_size_information(
105119
"""
106120

107121
tensor_and_delegate_blob_data = _get_nested_model_data(
108-
model.graph_module, delegate_deserializers
122+
model.graph_module, delegate_deserializers, exported_program=model
109123
)
110124

111125
for data_list in tensor_and_delegate_blob_data:

devtools/size_analysis_tool/size_analysis_tool_test.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@
1111
XnnpackFloatingPointPartitioner,
1212
)
1313
from executorch.backends.xnnpack.utils.configs import (
14+
get_xnnpack_edge_compile_config,
1415
get_xnnpack_executorch_backend_config,
1516
)
16-
from executorch.backends.xnnpack.utils.utils import capture_graph_for_xnnpack
1717

1818
from executorch.devtools.size_analysis_tool.size_analysis_tool import (
1919
generate_model_size_information,
2020
)
21-
from executorch.exir.backend.backend_api import to_backend, validation_disabled
21+
from executorch.exir import to_edge
2222
from executorch.exir.passes.spec_prop_pass import SpecPropPass
23+
from torch.export import export
2324

2425

2526
class SizeAnalysisToolTest(unittest.TestCase):
@@ -52,21 +53,20 @@ def forward(self, x):
5253

5354
test_input = torch.ones(size=(4, 7, 5, 6), dtype=torch.float)
5455

55-
edge_program = capture_graph_for_xnnpack(mm, (test_input,))
56+
edge_program = to_edge(
57+
export(mm, (test_input,), strict=True),
58+
compile_config=get_xnnpack_edge_compile_config(),
59+
)
5660
partitioner = XnnpackFloatingPointPartitioner()
5761

58-
with validation_disabled():
59-
delegated_program = edge_program
60-
delegated_program.exported_program = to_backend(
61-
edge_program.exported_program, partitioner
62-
)
62+
delegated_program = edge_program.to_backend(partitioner)
6363

6464
program = delegated_program.to_executorch(
6565
get_xnnpack_executorch_backend_config([SpecPropPass()]),
6666
)
6767

6868
size_information = generate_model_size_information(
69-
model=program,
69+
model=program.exported_program(),
7070
delegate_deserializers=None,
7171
flatbuffer=program.buffer,
7272
)

0 commit comments

Comments
 (0)