Skip to content

Commit 2d9e5b9

Browse files
Arm backend: Improve round lowering (pytorch#20379)
Quantized rounding was lowered through a decomposition. This change replaces round with a lookup table. This adds support for round on U55 cc @digantdesai @freddan80 @per @zingo @mansnils @Sebastian-Larsson @robell @rascani Signed-off-by: Oscar Andersson <oscar.andersson@arm.com>
1 parent 484f72c commit 2d9e5b9

6 files changed

Lines changed: 4 additions & 16 deletions

File tree

backends/arm/_passes/arm_pass_manager.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,6 @@ def transform_for_annotation_pipeline(self, graph_module: GraphModule):
677677
InsertInt32CastsAfterInt64PlaceholdersPass(tfa_pass=True),
678678
DecomposeEmbeddingPass(tfa_pass=True),
679679
DecomposeScaledDotProductAttentionPass(tfa_pass=True),
680-
DecomposeRoundPass(tfa_pass=True),
681680
DecomposeLogitPass(tfa_pass=True),
682681
PromoteBoolOperandsPass(tfa_pass=True),
683682
DecomposeSignPass(tfa_pass=True),

backends/arm/_passes/decompose_round_pass.py

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
from typing import Set, Type
77

8-
import torch
98
from executorch.backends.arm._passes import ArmOpTargetedPass
109
from executorch.exir.dialects._ops import ops as exir_ops
1110
from executorch.exir.dialects.edge._ops import EdgeOpOverload
@@ -33,16 +32,6 @@ def _get_round_decomposition_ops(op) -> tuple[Op, Op, Op, Op, Op, Op, Op]:
3332
exir_ops.edge.aten.ceil.default,
3433
exir_ops.edge.aten.where.self,
3534
)
36-
elif op == torch.ops.aten.round.default:
37-
return (
38-
torch.ops.aten.full.default,
39-
torch.ops.aten.ge.Tensor,
40-
torch.ops.aten.add.Scalar,
41-
torch.ops.aten.sub.Scalar,
42-
torch.ops.aten.floor.default,
43-
torch.ops.aten.ceil.default,
44-
torch.ops.aten.where.self,
45-
)
4635
raise RuntimeError(f"Can't get round decomposition ops for op {op}")
4736

4837

@@ -65,11 +54,10 @@ class DecomposeRoundPass(ArmOpTargetedPass):
6554

6655
target_ops = {
6756
exir_ops.edge.aten.round.default,
68-
torch.ops.aten.round.default,
6957
}
7058

7159
def call_operator(self, op, args, kwargs, meta, updated=False):
72-
if op not in self.target_ops or not self.allowed_to_transform(meta):
60+
if op not in self.target_ops or self._is_quantized_meta(meta):
7361
return super().call_operator(op, args, kwargs, meta, updated)
7462
x = args[0]
7563
input_dtype = x.node.meta["val"].dtype

backends/arm/_passes/insert_table_ops.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class TableOps:
5858
exir_ops.edge.aten.acos.default: torch.acos,
5959
exir_ops.edge.aten.tan.default: torch.tan,
6060
exir_ops.edge.aten.silu.default: torch.nn.functional.silu,
61+
exir_ops.edge.aten.round.default: torch.round,
6162
}
6263

6364
# Targets that must be treated explicitly

backends/arm/operator_support/tosa_profile_supported_op_lists.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@
128128
exir_ops.edge.aten.tan.default,
129129
exir_ops.edge.aten.silu.default,
130130
exir_ops.edge.aten.detach_copy.default,
131+
exir_ops.edge.aten.round.default,
131132
}
132133

133134

backends/arm/quantizer/quantization_annotator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,7 @@ def _get_fixed_qparams_qspec(
532532
torch.ops.aten.selu.default,
533533
torch.ops.aten.celu.default,
534534
torch.ops.aten.floor.default,
535+
torch.ops.aten.round.default,
535536
torch.ops.aten.log.default,
536537
torch.ops.aten.reciprocal.default,
537538
torch.ops.aten.rsqrt.default,

backends/arm/test/ops/test_round.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
from typing import Tuple
88

9-
import pytest
109
import torch
1110
from executorch.backends.arm.test import common
1211
from executorch.backends.arm.test.tester.test_pipeline import (
@@ -67,7 +66,6 @@ def test_round_tosa_INT(test_data: torch.Tensor):
6766

6867
@common.parametrize("test_data", test_data_suite)
6968
@common.XfailIfNoCorstone300
70-
@pytest.mark.xfail(reason="where.self not supported on U55")
7169
def test_round_u55_INT(test_data: torch.Tensor):
7270
pipeline = EthosU55PipelineINT[input_t1](
7371
Round(),

0 commit comments

Comments
 (0)