Skip to content

Commit 76d8597

Browse files
committed
Pytest Refactor - Passes
1 parent 0f02e85 commit 76d8597

19 files changed

Lines changed: 5476 additions & 76 deletions

backends/qualcomm/_passes/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from .annotate_quant_attrs import AnnotateQuantAttrs
99
from .annotate_stack import AnnotateStack
1010
from .annotate_unbind import AnnotateUnbind
11+
from .build_quant_io import BuildQuantIo
1112
from .canonicalize_conv import CanonicalizeConv
1213
from .convert_bmm_to_matmul import ConvertBmmToMatmul
1314
from .convert_linear_to_conv2d import ConvertLinearToConv2d
@@ -73,6 +74,7 @@
7374
AnnotateQuantAttrs,
7475
AnnotateStack,
7576
AnnotateUnbind,
77+
BuildQuantIo,
7678
CanonicalizeConv,
7779
ConvertBmmToMatmul,
7880
ConvertLinearToConv2d,

backends/qualcomm/_passes/annotate_avg_pool1d.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class AnnotateAvgPool1D(ExportPass):
2727
torch.avg_pool1d,
2828
torch.ops.aten.adaptive_avg_pool1d.default,
2929
torch.adaptive_avg_pool1d,
30+
torch.nn.modules.pooling.AvgPool1d,
3031
]
3132

3233
def __init__(self, edge_program: torch.export.ExportedProgram):

backends/qualcomm/_passes/annotate_stack.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,14 @@ class AnnotateStack(ExportPass):
1818
generated after quantization process.
1919
"""
2020

21-
decomp_ops = [torch.ops.aten.stack.default]
21+
_SOURCE_OPS = [torch.stack, torch.ops.aten.stack.default, "stack"]
2222

2323
def __init__(self, edge_program: torch.export.ExportedProgram):
2424
super(AnnotateStack, self).__init__()
2525
self.edge_program = edge_program
2626

2727
def _annotate_stack(self, graph_module: torch.fx.GraphModule):
28-
partitions = get_source_partitions(
29-
graph_module.graph, [torch.stack, torch.ops.aten.stack.default, "stack"]
30-
)
28+
partitions = get_source_partitions(graph_module.graph, self._SOURCE_OPS)
3129
for src_partitions in partitions.values():
3230
for src_partition in src_partitions:
3331
output = src_partition.output_nodes[0]

backends/qualcomm/_passes/annotate_unbind.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,14 @@ class AnnotateUnbind(ExportPass):
1818
generated after quantization process.
1919
"""
2020

21-
decomp_ops = [torch.ops.aten.unbind.int]
21+
_SOURCE_OPS = [torch.unbind, torch.ops.aten.unbind.int, "unbind"]
2222

2323
def __init__(self, edge_program: torch.export.ExportedProgram):
2424
super(AnnotateUnbind, self).__init__()
2525
self.edge_program = edge_program
2626

2727
def _annotate_unbind(self, graph_module: torch.fx.GraphModule):
28-
partitions = get_source_partitions(
29-
graph_module.graph, [torch.unbind, torch.ops.aten.unbind.int, "unbind"]
30-
)
28+
partitions = get_source_partitions(graph_module.graph, self._SOURCE_OPS)
3129
for src_partitions in partitions.values():
3230
for src_partition in src_partitions:
3331
if src_partition.input_nodes[0].target in dq_ops:

backends/qualcomm/_passes/decompose_any.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
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+
import re
8+
79
import torch
810
from executorch.exir import to_edge
911
from executorch.exir.pass_base import ExportPass, PassResult
@@ -33,13 +35,13 @@ class DecomposeAny(ExportPass):
3335
Decompose for math equivalent op.
3436
"""
3537

36-
def __init__(self, quantization_capture=False) -> None:
38+
def __init__(self) -> None:
3739
super().__init__()
3840

3941
def call(self, graph_module: torch.fx.GraphModule) -> PassResult:
4042
graph = graph_module.graph
4143
for node in graph.nodes:
42-
if "any.dim" in str(node.target):
44+
if re.search(r"any\.(dim|default)", str(node.target)):
4345
dim = node.args[1] if len(node.args) > 1 else None
4446
keepdim = node.args[2] if len(node.args) > 2 else False
4547
model = Any(dim, keepdim)

backends/qualcomm/_passes/decompose_expm1.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ def __init__(self) -> None:
2222
def call(self, graph_module: torch.fx.GraphModule) -> PassResult:
2323
graph = graph_module.graph
2424
for node in graph.nodes:
25-
if node.target == torch.ops.aten.special_expm1.default:
25+
if node.target in {
26+
torch.ops.aten.special_expm1.default,
27+
torch.ops.aten.expm1.default,
28+
}:
2629
input_node = node.args[0]
2730
with graph_module.graph.inserting_after(input_node):
2831
exp_op = torch.ops.aten.exp.default

backends/qualcomm/_passes/decompose_maxpool3d.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,19 @@ def call(self, graph_module: torch.fx.GraphModule) -> PassResult:
9494
dilation *= 3
9595

9696
ceil_mode = node.args[5] if num_args > 5 else False
97-
return_indices = node.args[6] if num_args > 6 else False
97+
# since the indices output might not be connected
98+
# only traverse getitem user and check if any of them referring to the indices
99+
return_indices = (
100+
any(user.args[1] == 1 for user in node.users)
101+
if len(node.meta["val"]) > 1
102+
else False
103+
)
98104
if return_indices:
99105
warnings.warn(
100-
"[QNN Delegate Op Builder]: The case return_indices=True is not be support, fallback",
106+
"[QNN Delegate Op Builder]: The case return_indices=True is not supported, fallback",
101107
stacklevel=1,
102108
)
103-
return
109+
continue
104110

105111
model = ModelMaxPool3D(
106112
filter_size, stride, padding, dilation, return_indices, ceil_mode

backends/qualcomm/_passes/decompose_pad.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ class DecomposePad(ExportPass):
2929

3030
_PAD_TARGETS = {
3131
torch.ops.aten.pad.default,
32-
exir_ops.edge.aten.pad.default,
3332
}
3433

3534
_PAD_OPS = {

backends/qualcomm/_passes/decompose_var.py

Lines changed: 7 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,9 @@
55
# LICENSE file in the root directory of this source tree.
66

77
import torch
8-
from executorch.exir.dialects._ops import ops as exir_ops
9-
from executorch.exir.dialects.edge._ops import EdgeOpOverload
108
from executorch.exir.pass_base import ExportPass, PassResult
11-
from torchao.quantization.pt2e.utils import get_new_attr_name_with_prefix
129

13-
from .utils import copy_meta, create_const_node
10+
from .utils import copy_meta
1411

1512

1613
class DecomposeVar(ExportPass):
@@ -29,17 +26,12 @@ def __init__(self):
2926
self.var_targets = {
3027
torch.ops.aten.var.correction,
3128
torch.ops.aten.var.dim,
32-
exir_ops.edge.aten.var.correction,
33-
exir_ops.edge.aten.var.dim,
3429
}
3530

3631
def _get_correction(self, node):
3732
"""Extract the correction factor from node args based on op variant."""
3833
target = node.target
39-
if target in (
40-
torch.ops.aten.var.correction,
41-
exir_ops.edge.aten.var.correction,
42-
):
34+
if target in {torch.ops.aten.var.correction}:
4335
# var.correction(Tensor self, int[1]? dim=None, *, Scalar? correction=None, bool keepdim=False)
4436
# correction is a kwarg, but in the graph it may appear in kwargs
4537
correction = node.kwargs.get("correction", None)
@@ -54,10 +46,7 @@ def _get_correction(self, node):
5446
def _get_dim_and_keepdim(self, node):
5547
"""Extract dim and keepdim from node args based on op variant."""
5648
target = node.target
57-
if target in (
58-
torch.ops.aten.var.correction,
59-
exir_ops.edge.aten.var.correction,
60-
):
49+
if target in {torch.ops.aten.var.correction}:
6150
# var.correction(Tensor self, int[1]? dim=None, *, Scalar? correction=None, bool keepdim=False)
6251
dim = node.args[1] if len(node.args) > 1 else None
6352
keepdim = node.kwargs.get("keepdim", False)
@@ -70,31 +59,18 @@ def _get_dim_and_keepdim(self, node):
7059

7160
def call(self, graph_module: torch.fx.GraphModule):
7261
graph = graph_module.graph
73-
const_cache = {}
7462

7563
for node in list(graph.nodes):
7664
if node.op == "call_function" and node.target in self.var_targets:
7765
x_node = node.args[0]
78-
is_edge = isinstance(node.target, EdgeOpOverload)
7966
meta = node.meta
8067

8168
correction = self._get_correction(node)
8269
dim, keepdim = self._get_dim_and_keepdim(node)
8370

84-
mean_op = (
85-
exir_ops.edge.aten.mean.dim if is_edge else torch.ops.aten.mean.dim
86-
)
87-
sub_op = (
88-
exir_ops.edge.aten.sub.Tensor
89-
if is_edge
90-
else torch.ops.aten.sub.Tensor
91-
)
92-
mul_op = (
93-
exir_ops.edge.aten.mul.Tensor
94-
if is_edge
95-
else torch.ops.aten.mul.Tensor
96-
)
97-
71+
mean_op = torch.ops.aten.mean.dim
72+
sub_op = torch.ops.aten.sub.Tensor
73+
mul_op = torch.ops.aten.mul.Tensor
9874
# Handle dim=None: reduce over all dimensions
9975
input_shape = node.args[0].meta["val"].shape
10076
if dim is None:
@@ -148,22 +124,8 @@ def call(self, graph_module: torch.fx.GraphModule):
148124
# Guard against division by zero (e.g. single-element dim with correction=1).
149125
# Using inf matches the native PyTorch behavior where 0 * inf → nan.
150126
scale = float("inf") if denom == 0 else float(n) / denom
151-
152-
if is_edge:
153-
cache_key = ("_var_scale_", scale)
154-
if cache_key not in const_cache:
155-
attr_name = get_new_attr_name_with_prefix(
156-
"_var_scale_const_"
157-
)(graph_module)
158-
const_cache[cache_key] = create_const_node(
159-
graph, graph_module, attr_name, scale, node
160-
)
161-
scale_node = const_cache[cache_key]
162-
else:
163-
scale_node = scale
164-
165127
result_node = graph.create_node(
166-
"call_function", mul_op, (var_node, scale_node)
128+
"call_function", mul_op, (var_node, scale)
167129
)
168130
result_node.meta = copy_meta(meta)
169131
else:

backends/qualcomm/_passes/qnn_pass_manager.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,8 @@ def get_default_pass_activations(cls):
129129
(DecomposeAny, True),
130130
(DecomposeAtan2, True),
131131
(DecomposeColIm, True),
132-
(DecomposeCDist, True),
133132
(DecomposeDiagonal, True),
134133
(DecomposeDivMode, True),
135-
(DecomposeFill, True),
136134
(DecomposeHyperbolicVariants, True),
137135
(DecomposeLogVariants, True),
138136
(DecomposeMaxPool3d, True),
@@ -141,7 +139,6 @@ def get_default_pass_activations(cls):
141139
(DecomposeRemainder, True),
142140
(DecomposeTan, True),
143141
(DecomposeTrunc, True),
144-
(DecomposeVar, True),
145142
(ExpandBroadcastTensorShape, True),
146143
(FixedLinearKeepDim, True),
147144
(FoldQDQ, True),
@@ -205,7 +202,6 @@ def get_export_passes(
205202
passes = [
206203
DecomposeBinaryAlpha,
207204
DecomposeCDist,
208-
DecomposePad,
209205
DecomposeScaledDotProductAttention,
210206
DecomposeRoll,
211207
DecomposeSelectScatter,
@@ -288,19 +284,16 @@ def get_passes_dependency_for_capture_program(cls):
288284
DecomposeAny: [RemoveRedundancy],
289285
DecomposeAtan2: [RemoveRedundancy],
290286
DecomposeColIm: [FoldQDQ],
291-
DecomposeCDist: [RemoveRedundancy],
292287
DecomposeDiagonal: [RemoveRedundancy],
293288
DecomposeDivMode: [RemoveRedundancy],
294289
DecomposeFill: [RemoveRedundancy],
295290
DecomposeHyperbolicVariants: [RemoveRedundancy],
296-
DecomposeLinalgVectorNorm: [RemoveRedundancy],
297291
DecomposeLogVariants: [RemoveRedundancy],
298292
DecomposeMaxPool3d: [RemoveRedundancy],
299293
DecomposePad: [RemoveRedundancy],
300294
DecomposeRemainder: [RemoveRedundancy],
301295
DecomposeTan: [RemoveRedundancy],
302296
DecomposeTrunc: [RemoveRedundancy],
303-
DecomposeVar: [RemoveRedundancy],
304297
ExpandBroadcastTensorShape: [FoldQDQ],
305298
FixedLinearKeepDim: [FoldQDQ],
306299
FoldQDQ: [AnnotateQuantAttrs, AnnotateStack, AnnotateUnbind],
@@ -474,8 +467,6 @@ def transform_for_preprocess_pipeline(
474467
insert_permute=True,
475468
)
476469
self._transform(exported_program.graph_module)
477-
# Update inputs_to_buffers and buffers_to_mutate in graph signature for mutable buffer
478-
# Since I/O will be inserted Q/DQ, it results in failed to mapping output node names and buffer
479470
exported_program._graph_signature = _get_updated_graph_signature(
480471
exported_program.graph_signature,
481472
exported_program.graph_module,

0 commit comments

Comments
 (0)