Skip to content

Commit cd380e7

Browse files
authored
Revert "Arm backend: Rerun duplicate-user fusion after TOSA lowering" (#21106)
Reverts #21041 This change breaks executorch/backends/arm/test:addmm test_addmm_u55_INT[basic] on Corstone-300: the model output is all zeros instead of the reference [[2,4],[6,8]]. Root cause: running FuseDuplicateUsersPass after InsertRescalePass. In the [basic] case x1 and x3 are value-identical, so FuseEqualPlaceholdersPass merges them into a single placeholder that feeds both the matmul operand and the bias/add path. After rescale insertion, that shared producer has multiple tosa.RESCALE users, and fusing them corrupts the quantized addmm data flow, zeroing the output. Bisected to the late FuseDuplicateUsersPass insertion specifically (reordering EnsureUniqueOutputNodesPass is not the cause). cc @digantdesai @freddan80 @per @zingo @oscarandersson8218 @mansnils @Sebastian-Larsson @robell @rascani
1 parent 37400d9 commit cd380e7

2 files changed

Lines changed: 1 addition & 52 deletions

File tree

backends/arm/_passes/arm_pass_manager.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -656,14 +656,9 @@ def _tosa_pipeline(
656656
SymbolicToTosaShapesPass(),
657657
InsertDynamicPaddingPass(),
658658
FuseConsecutiveConcatShapesPass(),
659-
# No-op removal can expose duplicate users and outputs, so run
660-
# FuseDuplicateUsersPass and EnsureUniqueOutputNodesPass afterward.
659+
EnsureUniqueOutputNodesPass(),
661660
RemoveNoopPass(),
662661
InsertRescalePass(),
663-
# Late TOSA transformations can introduce duplicate users after
664-
# the first FuseDuplicateUsersPass invocation.
665-
FuseDuplicateUsersPass(),
666-
EnsureUniqueOutputNodesPass(),
667662
]
668663
)
669664

backends/arm/test/passes/test_fuse_duplicate_users_pass.py

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,13 @@
88
import executorch.backends.arm.tosa.dialect # noqa: F401
99
import torch
1010
from executorch.backends.arm._passes import FuseDuplicateUsersPass
11-
from executorch.backends.arm._passes.arm_pass_manager import ArmPassManager
1211
from executorch.backends.arm.test import common
1312
from executorch.backends.arm.test.tester.test_pipeline import PassPipeline
14-
from executorch.backends.arm.tosa.compile_spec import TosaCompileSpec
1513
from executorch.backends.arm.tosa.specification import (
1614
TosaLoweringContext,
1715
TosaSpecification,
1816
)
19-
from executorch.exir import EdgeCompileConfig, to_edge
2017
from executorch.exir.dialects._ops import ops as exir_ops
21-
from torch.export import export
2218
from torch.fx import Graph, GraphModule
2319

2420
input_t = Tuple[torch.Tensor] # Input x
@@ -171,45 +167,3 @@ def test_fuse_duplicate_users_removes_identical_rescale_users():
171167
assert len(rescale_nodes) == 1
172168
output_node = result.graph_module.graph.output_node()
173169
assert output_node.args[0] == (rescale_nodes[0], rescale_nodes[0])
174-
175-
176-
class LateDuplicateUsers(torch.nn.Module):
177-
def __init__(self):
178-
super().__init__()
179-
self.register_buffer("first", torch.ones(2, 3))
180-
self.register_buffer("second", torch.ones(2, 3))
181-
182-
def forward(self, x):
183-
return x + self.first, x + self.second
184-
185-
186-
def test_fuse_duplicate_users_runs_after_tosa_transformations():
187-
exported_program = export(LateDuplicateUsers(), (torch.ones(2, 3),), strict=True)
188-
edge_program = to_edge(
189-
exported_program,
190-
compile_config=EdgeCompileConfig(_check_ir_validity=False),
191-
)
192-
edge_exported_program = edge_program.exported_program()
193-
194-
graph_module = ArmPassManager(
195-
TosaCompileSpec("TOSA-1.0+FP")
196-
).transform_to_backend_pipeline(
197-
edge_exported_program, edge_exported_program.graph_module
198-
)
199-
200-
add_nodes = [
201-
node
202-
for node in graph_module.graph.nodes
203-
if node.target == exir_ops.backend.tosa.ADD.default
204-
]
205-
identity_nodes = [
206-
node
207-
for node in graph_module.graph.nodes
208-
if node.target == exir_ops.backend.tosa.IDENTITY.default
209-
]
210-
211-
graph_module.graph.lint()
212-
assert len(add_nodes) == 1
213-
assert len(identity_nodes) == 2
214-
assert all(node.args[0] is add_nodes[0] for node in identity_nodes)
215-
assert graph_module.graph.output_node().args[0] == tuple(identity_nodes)

0 commit comments

Comments
 (0)