Skip to content

Commit 7feef67

Browse files
authored
Merge branch 'pytorch:main' into op-floor-div
2 parents a726363 + 7395999 commit 7feef67

File tree

131 files changed

+7362
-539
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

131 files changed

+7362
-539
lines changed

.ci/scripts/setup-samsung-linux-deps.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ download_ai_lite_core() {
1313
API_BASE="https://soc-developer.semiconductor.samsung.com/api/v1/resource/ai-litecore/download"
1414
API_KEY=$SAMSUNG_AI_LITECORE_KEY
1515

16-
VERSION="0.5"
16+
VERSION="0.7"
1717
OS_NAME="Ubuntu 22.04"
1818
OUT_FILE="/tmp/exynos-ai-litecore-v${VERSION}.tar.gz"
1919
TARGET_PATH="/tmp/exynos_ai_lite_core"
@@ -62,7 +62,7 @@ install_enn_backend() {
6262
export PYTHONPATH=${PYTHONPATH:-}:${EXECUTORCH_ROOT}/..
6363
}
6464

65-
AI_LITE_CORE_VERSION=0.5.0
65+
AI_LITE_CORE_VERSION=0.7.0
6666

6767
download_ai_lite_core ${AI_LITE_CORE_VERSION}
6868
install_enn_backend

.ci/scripts/test_ios_ci.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ say() {
3636

3737
say "Cloning the Demo App"
3838

39+
git config --global http.postBuffer 524288000
3940
git clone --depth 1 https://github.com/meta-pytorch/executorch-examples.git
4041

4142
say "Installing CoreML Backend Requirements"

.github/workflows/pull.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -935,6 +935,12 @@ jobs:
935935
python -m executorch.examples.samsung.aot_compiler --model_name=$model -c E9955
936936
done
937937
938+
# Test quant models
939+
model_scripts="deeplab_v3 edsr inception_v3 inception_v4 mobilenet_v2 mobilenet_v3 resnet18 resnet50 vit wav2letter"
940+
for m_script in $model_scripts; do
941+
python -m executorch.examples.samsung.scripts.${m_script} -c e9955 -p A8W8
942+
done
943+
938944
# Test ops
939945
python -m unittest discover -s backends/samsung/test/ops -p "test_*.py"
940946

.github/workflows/trunk.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ jobs:
346346
elif [[ ${{ matrix.os}} == "zephyr-preset" ]]; then
347347
setup_script_args="--target-toolchain zephyr"
348348
toolchain_prefix=arm-zephyr-eabi-
349-
threshold="135168" # 132 KiB
349+
threshold="135240" # 132 KiB
350350
toolchain_cmake=examples/zephyr/x86_64-linux-arm-zephyr-eabi-gcc.cmake
351351
else
352352
echo "Fail unsupport OS selection ${{ matrix.os }}"

backends/arm/_passes/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from .convert_to_clamp import ConvertToClampPass # noqa
2828
from .decompose_acosh_pass import DecomposeAcoshPass # noqa
2929
from .decompose_adaptive_avg_pool2d_pass import DecomposeAdaptiveAvgPool2dPass # noqa
30+
from .decompose_add_sub_alpha_pass import DecomposeAddSubAlphaPass # noqa
3031
from .decompose_addmm_pass import DecomposeAddmmPass # noqa
3132
from .decompose_asin_and_acos_pass import DecomposeAsinAndAcosPass # noqa
3233
from .decompose_asinh_pass import DecomposeAsinhPass # noqa

backends/arm/_passes/arm_pass_manager.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
DecomposeAcoshPass,
3737
DecomposeAdaptiveAvgPool2dPass,
3838
DecomposeAddmmPass,
39+
DecomposeAddSubAlphaPass,
3940
DecomposeAsinAndAcosPass,
4041
DecomposeAsinhPass,
4142
DecomposeAtanhPass,
@@ -264,6 +265,7 @@ def _tosa_FP_pipeline(self, exported_program: ExportedProgram) -> GraphModule:
264265
)
265266
self.add_pass(DecomposeNotEqualPass())
266267
self.add_pass(DecomposeDivPass())
268+
self.add_pass(DecomposeAddSubAlphaPass())
267269
self.add_pass(DecomposeSoftmaxPass())
268270
self.add_pass(DecomposeGeluPass())
269271
self.add_pass(ConvertFullLikeToFullPass())
@@ -337,6 +339,7 @@ def transform_for_annotation_pipeline(self, graph_module: GraphModule):
337339
self.add_pass(DecomposeAddmmPass())
338340
self.add_pass(DecomposeFloorDividePass())
339341
self.add_pass(DecomposeDivTensorModePass())
342+
self.add_pass(DecomposeAddSubAlphaPass())
340343
self.add_pass(ReplaceScalarWithTensorArgPassTOSABI())
341344
self.add_pass(ScalarsToAttributePass())
342345
self.add_pass(DecomposeGroupNormPass())
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Copyright 2025 Arm Limited and/or its affiliates.
2+
#
3+
# This source code is licensed under the BSD-style license found in the
4+
# LICENSE file in the root directory of this source tree.
5+
6+
from __future__ import annotations
7+
8+
import numbers
9+
from typing import Set, Type
10+
11+
import torch
12+
from executorch.backends.arm._passes import ArmPass
13+
from executorch.exir.dialects._ops import ops as exir_ops
14+
from executorch.exir.pass_base import ExportPass
15+
16+
17+
_ADD_OPS = (
18+
exir_ops.edge.aten.add.Tensor,
19+
torch.ops.aten.add.Tensor,
20+
)
21+
22+
_SUB_OPS = (
23+
exir_ops.edge.aten.sub.Tensor,
24+
torch.ops.aten.sub.Tensor,
25+
)
26+
27+
28+
def _get_ops(op):
29+
if op in _ADD_OPS:
30+
if op is exir_ops.edge.aten.add.Tensor:
31+
return (
32+
exir_ops.edge.aten.mul.Tensor,
33+
exir_ops.edge.aten.full.default,
34+
exir_ops.edge.aten.add.Tensor,
35+
)
36+
return (
37+
torch.ops.aten.mul.Tensor,
38+
torch.ops.aten.full.default,
39+
torch.ops.aten.add.Tensor,
40+
)
41+
if op in _SUB_OPS:
42+
if op is exir_ops.edge.aten.sub.Tensor:
43+
return (
44+
exir_ops.edge.aten.mul.Tensor,
45+
exir_ops.edge.aten.full.default,
46+
exir_ops.edge.aten.sub.Tensor,
47+
)
48+
return (
49+
torch.ops.aten.mul.Tensor,
50+
torch.ops.aten.full.default,
51+
torch.ops.aten.sub.Tensor,
52+
)
53+
raise RuntimeError(f"Unsupported operator {op}")
54+
55+
56+
def _should_decompose(alpha) -> bool:
57+
if isinstance(alpha, numbers.Number):
58+
return alpha != 1
59+
return False
60+
61+
62+
class DecomposeAddSubAlphaPass(ArmPass):
63+
"""Rewrite add/sub with alpha into a mul followed by add/sub."""
64+
65+
_passes_required_after: Set[Type[ExportPass]] = set()
66+
67+
def call_operator(self, op, args, kwargs, meta, updated: bool | None = False):
68+
if op not in _ADD_OPS + _SUB_OPS:
69+
return super().call_operator(op, args, kwargs, meta, updated)
70+
71+
alpha = kwargs.get("alpha", 1)
72+
if not _should_decompose(alpha):
73+
return super().call_operator(op, args, kwargs, meta, updated)
74+
75+
mul_op, full_op, binary_op = _get_ops(op)
76+
lhs, rhs = args
77+
78+
alpha_full = super().call_operator(
79+
full_op, ((1,), float(alpha)), {}, meta, updated=True
80+
)
81+
scaled_rhs = super().call_operator(
82+
mul_op,
83+
(rhs, alpha_full),
84+
{},
85+
meta,
86+
updated=True,
87+
)
88+
return super().call_operator(
89+
binary_op,
90+
(lhs, scaled_rhs),
91+
{},
92+
meta,
93+
updated=True,
94+
)

backends/arm/test/ops/test_add.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def forward(self, x: torch.Tensor, y: torch.Tensor):
7878

7979
class Add3(torch.nn.Module):
8080
def forward(self, x: torch.Tensor, y: torch.Tensor):
81-
return x + y
81+
return torch.add(x, y, alpha=1.5)
8282

8383
test_data: list[input_t2] = {
8484
"3d_randn_diff_rank": lambda: (torch.randn(1, 4, 5), torch.randn(4, 1)),

backends/arm/test/ops/test_sub.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ def forward(self, x: torch.Tensor, y: torch.Tensor):
7979
return x - y
8080

8181

82+
class SubAlpha(torch.nn.Module):
83+
def forward(self, x: torch.Tensor, y: torch.Tensor):
84+
return torch.sub(x, y, alpha=5)
85+
86+
8287
class SubTan(torch.nn.Module):
8388

8489
def forward(self, x: torch.Tensor, y: torch.Tensor):
@@ -115,6 +120,18 @@ def test_sub_tensor_tosa_FP_2(test_data: Tuple[torch.Tensor, torch.Tensor]):
115120
pipeline.run()
116121

117122

123+
@common.parametrize("test_data", sub_tan_test_data)
124+
def test_sub_tensor_tosa_FP_alpha(test_data: Tuple[torch.Tensor, torch.Tensor]):
125+
"""Test Two-Operand Subtraction with alpha (TOSA FP)"""
126+
pipeline = TosaPipelineFP[input_t2](
127+
SubAlpha(),
128+
test_data(),
129+
aten_op,
130+
exir_op,
131+
)
132+
pipeline.run()
133+
134+
118135
@common.parametrize("test_data", sub_test_data)
119136
def test_sub_tensor_tosa_INT(test_data):
120137
"""Test Subtraction (TOSA INT)"""
@@ -138,6 +155,15 @@ def test_sub_tensor_tosa_INT_3(test_data: Tuple[torch.Tensor, torch.Tensor]):
138155
pipeline.run()
139156

140157

158+
@common.parametrize("test_data", sub_tan_test_data)
159+
def test_sub_tensor_tosa_INT_alpha(test_data: Tuple[torch.Tensor, torch.Tensor]):
160+
"""Test Two-Operand Subtraction with alpha (TOSA INT)"""
161+
pipeline = TosaPipelineINT[input_t2](
162+
SubAlpha(), test_data(), aten_op, exir_op, qtol=0
163+
)
164+
pipeline.run()
165+
166+
141167
@common.parametrize("test_data", sub_test_data)
142168
@common.XfailIfNoCorstone300
143169
def test_sub_tensor_u55_INT(test_data):

0 commit comments

Comments
 (0)