Skip to content

Commit 4b8bced

Browse files
committed
Update base for Update on "Remove PATTERNLINT suppressions"
The linter these are suppressing was removed in D63859186. Differential Revision: [D65507718](https://our.internmc.facebook.com/intern/diff/D65507718/) [ghstack-poisoned]
2 parents c88bb55 + dc41596 commit 4b8bced

File tree

162 files changed

+4103
-924
lines changed

Some content is hidden

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

162 files changed

+4103
-924
lines changed

.ci/scripts/test_llama_runner_eager.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,12 @@ run_and_verify() {
4242
-d fp32 \
4343
--max_seq_length 32 \
4444
--temperature 0 \
45+
--show_tokens \
4546
--prompt "Once upon a time," > result.txt
4647

4748
# Verify result.txt
4849
RESULT=$(cat result.txt)
49-
EXPECTED_RESULT="there was a little girl"
50+
EXPECTED_RESULT="727, 471, 263, 2217, 7826, 4257, 365, 2354, 29889, 2296, 18012, 304, 1708, 5377, 297, 278, 6575, 845, 457, 29889, 3118, 2462, 29892, 1183, 4446, 263"
5051
if [[ "${RESULT}" == *"${EXPECTED_RESULT}"* ]]; then
5152
echo "Actual result: ${RESULT}"
5253
echo "Success"

.gitmodules

+3
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,6 @@
6464
[submodule "third-party/pybind11"]
6565
path = third-party/pybind11
6666
url = https://github.com/pybind/pybind11.git
67+
[submodule "third-party/ao"]
68+
path = third-party/ao
69+
url = https://github.com/pytorch/ao.git

CMakeLists.txt

+8-3
Original file line numberDiff line numberDiff line change
@@ -721,10 +721,15 @@ if(EXECUTORCH_BUILD_PYBIND)
721721
-fPIC
722722
-frtti
723723
-fexceptions
724-
# libtorch is built with the old ABI, so we need to do the same for any
725-
# .cpp files that include torch, c10, or ATen targets.
726-
-D_GLIBCXX_USE_CXX11_ABI=0
727724
)
725+
if(EXECUTORCH_DO_NOT_USE_CXX11_ABI)
726+
# libtorch is built with the old ABI, so we need to do the same for any
727+
# .cpp files that include torch, c10, or ATen targets. Note that PyTorch
728+
# nightly binary is built with _GLIBCXX_USE_CXX11_ABI set to 0 while its
729+
# CI build sets this to 1 (default)
730+
list(APPEND _pybind_compile_options -D_GLIBCXX_USE_CXX11_ABI=0)
731+
endif()
732+
728733
# util lib
729734
add_library(
730735
util ${CMAKE_CURRENT_SOURCE_DIR}/extension/evalue_util/print_evalue.cpp

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,11 @@ We recommend using the latest release tag from the
4343
See [CONTRIBUTING.md](CONTRIBUTING.md) for details about issues, PRs, code
4444
style, CI jobs, and other development topics.
4545

46+
To connect with us and other community members, we invite you to join PyTorch Slack community by filling out this [form](https://docs.google.com/forms/d/e/1FAIpQLSeADnUNW36fjKjYzyHDOzEB_abKQE9b6gqqW9NXse6O0MWh0A/viewform). Once you've joined, you can:
47+
* Head to the `#executorch-general` channel for general questions, discussion, and community support.
48+
* Join the `#executorch-contributors` channel if you're interested in contributing directly to project development.
49+
50+
4651
## Directory Structure
4752

4853
```

backends/arm/TARGETS

+12
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,18 @@ python_library(
7070
],
7171
)
7272

73+
python_library(
74+
name = "tosa_specification",
75+
srcs = [
76+
"tosa_specification.py",
77+
],
78+
typing = True,
79+
deps = [
80+
"fbsource//third-party/pypi/packaging:packaging",
81+
"//executorch/exir/backend:compile_spec_schema",
82+
],
83+
)
84+
7385
python_library(
7486
name = "tosa_utils",
7587
srcs = [

backends/arm/_passes/TARGETS

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ python_library(
77
deps = [
88
"//executorch/backends/arm:tosa_quant_utils",
99
"//executorch/backends/arm:tosa_utils",
10+
"//executorch/backends/xnnpack/_passes:xnnpack_passes",
1011
"//executorch/exir:lib",
1112
],
1213
)

backends/arm/_passes/annotate_channels_last_dim_order_pass.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
get_first_fake_tensor,
1515
insert_q_dq_pair,
1616
)
17-
from executorch.backends.arm.tosa_quant_utils import dq_op, q_op
17+
from executorch.backends.arm.tosa_quant_utils import dq_op, q_op, register_passable_op
1818
from executorch.backends.arm.tosa_utils import is_consumer_node_depthwise_conv2d
1919
from executorch.exir.dialects._ops import ops as exir_ops
2020
from executorch.exir.pass_base import ExportPass, PassResult
@@ -42,6 +42,9 @@ def _transpose_impl(*args, **kwargs):
4242
return args[0]
4343

4444

45+
register_passable_op(torch.ops.passthrough_to_tosa._transpose)
46+
47+
4548
class AnnotateChannelsLastDimOrder(ExportPass):
4649
"""
4750
Annotates each node with a tosa_dim_order. tosa_dim_order can be seen as a channels-last dim-order

backends/arm/_passes/arm_pass_manager.py

+2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from executorch.backends.arm._passes.decompose_layernorm_pass import (
2424
DecomposeLayerNormPass,
2525
)
26+
from executorch.backends.arm._passes.decompose_linear_pass import DecomposeLinearPass
2627
from executorch.backends.arm._passes.decompose_meandim_pass import DecomposeMeanDimPass
2728
from executorch.backends.arm._passes.decompose_softmaxes_pass import (
2829
DecomposeSoftmaxesPass,
@@ -74,6 +75,7 @@ def transform_to_backend_pipeline(
7475
self.add_pass(ConvertSplitToSlicePass())
7576
self.add_pass(Conv1dUnsqueezePass(exported_program))
7677
self.add_pass(DecomposeSoftmaxesPass())
78+
self.add_pass(DecomposeLinearPass())
7779
for spec in compile_spec:
7880
if spec.key == "permute_memory_format":
7981
memory_format = spec.value.decode()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Copyright 2024 Arm Limited and/or its affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
import numpy as np
8+
from executorch.backends.arm._passes.arm_pass_utils import (
9+
create_node,
10+
get_first_fake_tensor,
11+
)
12+
from executorch.backends.arm.tosa_quant_utils import dq_op, q_op
13+
from executorch.exir.dialects._ops import ops as exir_ops
14+
from executorch.exir.pass_base import ExportPass, PassResult
15+
16+
17+
class DecomposeLinearPass(ExportPass):
18+
"""
19+
This pass decomposes linear into a Conv2D with the required view operations.
20+
linear(x, weights, bias) becomes:
21+
x_reshaped = view(x)
22+
weights_reshaped = view(weights)
23+
conv2d = conv2d(x_reshaped, weights_reshaped, bias)
24+
output = view(conv2d)
25+
It also inserts q/dq pairs if the linear node was quantized.
26+
"""
27+
28+
def call(self, graph_module):
29+
for node in graph_module.graph.nodes:
30+
if node.op != "call_function":
31+
continue
32+
if node.target != exir_ops.edge.aten.linear.default:
33+
continue
34+
args = node.args
35+
input = args[0]
36+
weights = args[1]
37+
bias = args[2] if len(args) > 2 else None
38+
output_shape = get_first_fake_tensor(node).shape
39+
input_shape = get_first_fake_tensor(input).shape
40+
weights_shape = get_first_fake_tensor(weights).shape
41+
batches = int(np.prod(input_shape[:-1])) if len(input_shape) > 1 else 1
42+
# input has shape (..., Ci)
43+
input_reshaped_shape = [batches, input_shape[-1], 1, 1]
44+
# weights have shape (Co, Ci)
45+
weights_reshaped_shape = [weights_shape[0], weights_shape[1], 1, 1]
46+
47+
with graph_module.graph.inserting_before(node):
48+
quantize = input.op == "call_function" and input.target == dq_op
49+
q_params = input.args[1:] if quantize else None
50+
# Reshape input to 4D with shape (N, Ci, 1, 1)
51+
input_reshaped = create_node(
52+
graph=graph_module.graph,
53+
op_target=exir_ops.edge.aten.view_copy.default,
54+
args=(input, input_reshaped_shape),
55+
kwargs={},
56+
quantize=quantize,
57+
q_params=q_params,
58+
)
59+
60+
quantize = weights.op == "call_function" and weights.target == dq_op
61+
q_params = weights.args[1:] if quantize else None
62+
# Reshape weights to 4D with shape (Co, Ci, 1, 1)
63+
weights_reshaped = create_node(
64+
graph=graph_module.graph,
65+
op_target=exir_ops.edge.aten.view_copy.default,
66+
args=(weights, weights_reshaped_shape),
67+
kwargs={},
68+
quantize=quantize,
69+
q_params=q_params,
70+
)
71+
72+
consumer_node = list(node.users)[0]
73+
quantize = (
74+
consumer_node.op == "call_function" and consumer_node.target == q_op
75+
)
76+
q_params = consumer_node.args[1:] if quantize else None
77+
conv = create_node(
78+
graph=graph_module.graph,
79+
op_target=exir_ops.edge.aten.convolution.default,
80+
args=(
81+
input_reshaped,
82+
weights_reshaped,
83+
bias,
84+
[1, 1], # strides
85+
[0, 0], # padding
86+
[1, 1], # dilation
87+
False, # transposed
88+
[0, 0], # output padding
89+
1, # groups
90+
),
91+
kwargs={},
92+
quantize=quantize,
93+
q_params=q_params,
94+
)
95+
96+
with graph_module.graph.inserting_after(conv):
97+
# Reshape output to same rank as original input with shape (..., Co)
98+
# No need to insert q/dq pair as Conv2D node above has inserted them if
99+
# required.
100+
output = create_node(
101+
graph=graph_module.graph,
102+
op_target=exir_ops.edge.aten.view_copy.default,
103+
args=(conv, list(output_shape)),
104+
kwargs={},
105+
)
106+
107+
node.replace_all_uses_with(output)
108+
graph_module.graph.erase_node(node)
109+
graph_module.graph.eliminate_dead_code()
110+
graph_module.recompile()
111+
graph_module = super().call(graph_module).graph_module
112+
return PassResult(graph_module, True)

backends/arm/_passes/insert_squeeze_after_sum_pass.py

+1-13
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@
88

99
import torch
1010
import torch.fx
11-
from executorch.backends.arm._passes.arm_pass_utils import create_node, insert_q_dq_pair
12-
13-
from executorch.backends.arm.tosa_quant_utils import get_quant_node_args, is_quant_node
11+
from executorch.backends.arm._passes.arm_pass_utils import create_node
1412
from executorch.exir.dialects._ops import ops as exir_ops
1513
from executorch.exir.pass_base import ExportPass, PassResult
1614

@@ -28,8 +26,6 @@ class InsertSqueezeAfterSumPass(ExportPass):
2826
sum(dims, keep_dim = False)
2927
After pass:
3028
sum(dims, keep_dim = True)
31-
(q)
32-
(dq)
3329
squeeze(dim = dims)
3430
"""
3531

@@ -45,12 +41,6 @@ def call(self, graph_module: torch.fx.GraphModule):
4541
continue
4642

4743
dim_list = cast(list[int], sum_node.args[1])
48-
quantized = is_quant_node(sum_node)
49-
if quantized:
50-
qparams = get_quant_node_args(sum_node.all_input_nodes[0])
51-
qparams = qparams + (torch.int8,)
52-
else:
53-
qparams = None
5444

5545
# Add keep_dim = True arg to sum node.
5646
sum_node.args = sum_node.args[0:2] + (True,)
@@ -61,8 +51,6 @@ def call(self, graph_module: torch.fx.GraphModule):
6151
)
6252
sum_node.replace_all_uses_with(squeeze_node)
6353
squeeze_node.args = (sum_node, dim_list)
64-
if quantized:
65-
sum_node = insert_q_dq_pair(graph_module.graph, sum_node, qparams)
6654
graph_module.graph.eliminate_dead_code()
6755
graph_module.recompile()
6856
graph_module = super().call(graph_module).graph_module

backends/arm/_passes/size_adjust_conv2d_pass.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from typing import cast, Optional
1010

1111
import torch.fx
12-
from executorch.backends.arm.tosa_quant_utils import is_quant_node
12+
from executorch.backends.arm.tosa_quant_utils import is_node_quantized
1313
from executorch.exir.dialects._ops import ops as exir_ops
1414
from executorch.exir.pass_base import ExportPass, PassResult
1515
from torch._ops import OpOverload
@@ -113,7 +113,7 @@ def call(self, graph_module: torch.fx.GraphModule):
113113
slice_node = graph.create_node(
114114
"call_function", self.slice_op, (last_node,) + args
115115
)
116-
if is_quant_node(last_node):
116+
if is_node_quantized(last_node):
117117
q_params = last_node.args[1:]
118118
dq_node = insert_q_dq_pair(
119119
graph_module.graph, slice_node, q_params

0 commit comments

Comments
 (0)