Skip to content

Commit 462751c

Browse files
author
pytorchbot
committed
2024-10-15 nightly release (7ba7990)
1 parent 4267559 commit 462751c

File tree

38 files changed

+792
-120
lines changed

38 files changed

+792
-120
lines changed

.github/workflows/android-perf.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ jobs:
205205
206206
# Let's see how expensive this job is, we might want to tone it down by running it periodically
207207
benchmark-on-device:
208+
if: always()
208209
permissions:
209210
id-token: write
210211
contents: read

.github/workflows/android.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ jobs:
8080
# Reuse the script that install Android on ET Docker image
8181
sudo -E bash .ci/docker/common/install_android.sh
8282
83+
# After https://github.com/ReactiveCircus/android-emulator-runner/releases/tag/v2.33.0 release,
84+
# it seems that we need to chown the Android setup to the current user instead of root to
85+
# avoid permission issue
86+
sudo chown -R "${USER}" /opt/android
87+
8388
- name: Gradle cache
8489
uses: gradle/actions/setup-gradle@v3
8590

.github/workflows/apple-perf.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,7 @@ jobs:
279279
path: ${{ runner.temp }}/artifacts/
280280

281281
benchmark-on-device:
282+
if: always()
282283
needs:
283284
- set-parameters
284285
- upload-benchmark-app

.lintrunner.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ command = [
151151
'lintrunner_adapters',
152152
'run',
153153
'grep_linter',
154-
'--pattern= Executorch\W+',
154+
# Exclude "ExecuTorch" pattern within URLs
155+
'--pattern= Executorch(?!\\W*(://|\\.[a-z]{2,}))\\W+',
155156
'--linter-name=ExecuTorchCapitalization',
156157
'--error-name=Incorrect capitalization for ExecuTorch',
157158
"""--error-description=

backends/cadence/aot/TARGETS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ python_library(
4343
"//executorch/backends/transforms:decompose_sdpa",
4444
"//executorch/backends/transforms:remove_clone_ops",
4545
"//executorch/exir:lib",
46+
"//executorch/devtools:lib",
4647
],
4748
)
4849

backends/cadence/aot/compiler.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# pyre-strict
88

99
import logging
10+
from pathlib import Path
1011
from typing import Optional
1112

1213
import torch
@@ -29,7 +30,13 @@
2930
DecomposeScaledDotProductAttention,
3031
)
3132
from executorch.backends.transforms.remove_clone_ops import RemoveCloneOpsTransform
32-
from executorch.exir import EdgeCompileConfig, EdgeProgramManager, to_edge
33+
from executorch.devtools import generate_etrecord
34+
from executorch.exir import (
35+
EdgeCompileConfig,
36+
EdgeProgramManager,
37+
ExecutorchProgramManager,
38+
to_edge,
39+
)
3340
from torch.ao.quantization.pt2e.export_utils import model_is_exported
3441
from torch.ao.quantization.quantize_pt2e import convert_pt2e, prepare_pt2e
3542

@@ -197,11 +204,12 @@ def export_to_edge(
197204
# Export the model and lower it to an EdgeProgramManager (in edge IR), and
198205
# apply passes specific to Cadence DSP execution. Return both to print the
199206
# differences.
200-
def export_to_cadence(
207+
def export_to_cadence_edge_executorch(
201208
model: torch.nn.Module,
202209
inputs: tuple[object, ...],
203210
dump_graphs: bool = False,
204-
) -> EdgeProgramManager:
211+
output_dir: Optional[str] = None,
212+
) -> ExecutorchProgramManager:
205213
edge_prog_manager = export_to_edge(model, inputs)
206214

207215
# Run a couple required passes for quant/dequant ops
@@ -225,4 +233,29 @@ def export_to_cadence(
225233
cadence_prog_manager.exported_program().graph_module,
226234
)
227235

228-
return cadence_prog_manager
236+
# Get executorch program after Cadence specific passes
237+
exec_prog: ExecutorchProgramManager = cadence_prog_manager.to_executorch()
238+
if output_dir:
239+
_gen_etrecord(edge_prog_manager, exec_prog, Path(output_dir))
240+
else:
241+
logging.warning("No output directory provided, skipping ETRecord generation")
242+
243+
return exec_prog
244+
245+
246+
def _gen_etrecord(
247+
edge_program: EdgeProgramManager,
248+
et_program: ExecutorchProgramManager,
249+
output_dir: Path,
250+
) -> None:
251+
etrec_path = output_dir / "etrecord.bin"
252+
try:
253+
generate_etrecord(
254+
et_record=etrec_path,
255+
edge_dialect_program=edge_program,
256+
executorch_program=et_program,
257+
)
258+
logging.info(f"Generated ETRecord at {etrec_path}")
259+
except Exception:
260+
# Any errors here shouldn't block the rest of the flow
261+
logging.exception("Encountered exception while generating ETRecord")

backends/cadence/aot/export_example.py

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,52 @@
99
import logging
1010
import tempfile
1111

12+
import torch
13+
1214
from executorch.backends.cadence.aot.ops_registrations import * # noqa
1315
from typing import Any, Tuple
1416

1517
from executorch.backends.cadence.aot.compiler import (
1618
convert_pt2,
17-
export_to_cadence,
19+
export_to_cadence_edge_executorch,
1820
fuse_pt2,
1921
)
22+
2023
from executorch.backends.cadence.aot.quantizer.quantizer import CadenceQuantizer
2124
from executorch.backends.cadence.runtime import runtime
2225
from executorch.backends.cadence.runtime.executor import BundledProgramManager
2326
from executorch.exir import ExecutorchProgramManager
2427
from torch import nn
28+
from torch.ao.quantization.observer import HistogramObserver, MinMaxObserver
29+
from torch.ao.quantization.quantizer.xnnpack_quantizer_utils import (
30+
QuantizationConfig,
31+
QuantizationSpec,
32+
)
2533

2634
from .utils import save_bpte_program, save_pte_program
2735

2836

2937
FORMAT = "[%(levelname)s %(asctime)s %(filename)s:%(lineno)s] %(message)s"
3038
logging.basicConfig(level=logging.INFO, format=FORMAT)
3139

40+
act_qspec = QuantizationSpec(
41+
dtype=torch.int8,
42+
quant_min=-128,
43+
quant_max=127,
44+
qscheme=torch.per_tensor_affine,
45+
is_dynamic=False,
46+
observer_or_fake_quant_ctr=HistogramObserver.with_args(eps=2**-12),
47+
)
48+
49+
wgt_qspec = QuantizationSpec(
50+
dtype=torch.int8,
51+
quant_min=-128,
52+
quant_max=127,
53+
qscheme=torch.per_tensor_affine,
54+
is_dynamic=False,
55+
observer_or_fake_quant_ctr=MinMaxObserver,
56+
)
57+
3258

3359
def export_model(
3460
model: nn.Module,
@@ -39,8 +65,15 @@ def export_model(
3965
working_dir = tempfile.mkdtemp(dir="/tmp")
4066
logging.debug(f"Created work directory {working_dir}")
4167

68+
qconfig = QuantizationConfig(
69+
act_qspec,
70+
act_qspec,
71+
wgt_qspec,
72+
None,
73+
)
74+
4275
# Instantiate the quantizer
43-
quantizer = CadenceQuantizer()
76+
quantizer = CadenceQuantizer(qconfig)
4477

4578
# Convert the model
4679
converted_model = convert_pt2(model, example_inputs, quantizer)
@@ -53,10 +86,9 @@ def export_model(
5386
quantized_model = fuse_pt2(converted_model, quantizer)
5487

5588
# Get edge program after Cadence specific passes
56-
cadence_prog_manager = export_to_cadence(quantized_model, example_inputs)
57-
58-
# Get executorch program after Cadence specific passes
59-
exec_prog: ExecutorchProgramManager = cadence_prog_manager.to_executorch()
89+
exec_prog: ExecutorchProgramManager = export_to_cadence_edge_executorch(
90+
quantized_model, example_inputs, working_dir
91+
)
6092

6193
logging.info("Final exported graph:\n")
6294
exec_prog.exported_program().graph_module.graph.print_tabular()

backends/cadence/aot/quantizer/quantizer.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,20 @@ def get_supported_operators(cls) -> List[OperatorConfig]:
141141

142142

143143
class CadenceQuantizer(ComposableQuantizer):
144-
def __init__(self) -> None:
145-
static_qconfig = QuantizationConfig(
146-
act_qspec,
147-
act_qspec,
148-
wgt_qspec,
149-
None,
144+
def __init__(
145+
self, quantization_config: Optional[QuantizationConfig] = None
146+
) -> None:
147+
static_qconfig = (
148+
QuantizationConfig(
149+
act_qspec,
150+
act_qspec,
151+
wgt_qspec,
152+
None,
153+
)
154+
if not quantization_config
155+
else quantization_config
150156
)
157+
151158
super().__init__(
152159
[
153160
CadenceAtenQuantizer(AddmmPattern(), static_qconfig),

backends/cadence/build_cadence_runner.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ main() {
2525
-DCMAKE_BUILD_TYPE=Release \
2626
-DEXECUTORCH_BUILD_DEVTOOLS=ON \
2727
-DEXECUTORCH_ENABLE_EVENT_TRACER=ON \
28+
-DEXECUTORCH_ENABLE_LOGGING=ON \
2829
-Bcmake-out .
2930
cmake --build cmake-out --target install --config Release -j16
3031

@@ -35,6 +36,7 @@ main() {
3536
cmake -DCMAKE_PREFIX_PATH="${cmake_prefix_path}" \
3637
-DCMAKE_BUILD_TYPE=Release \
3738
-DEXECUTORCH_CADENCE_CPU_RUNNER=ON \
39+
-DEXECUTORCH_ENABLE_LOGGING=ON \
3840
-B"${build_dir}" \
3941
"${example_dir}"
4042
cmake --build "${build_dir}" --config Release -j16

backends/cadence/reference/operators/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ set(_aten_ops__srcs
2727
"${EXECUTORCH_ROOT}/kernels/portable/cpu/util/activation_ops_util.cpp"
2828
"${EXECUTORCH_ROOT}/kernels/portable/cpu/util/copy_ops_util.cpp"
2929
"${EXECUTORCH_ROOT}/kernels/portable/cpu/util/broadcast_util.cpp"
30+
"${EXECUTORCH_ROOT}/kernels/portable/cpu/util/dtype_util.cpp"
3031
"${EXECUTORCH_ROOT}/kernels/portable/cpu/util/index_util.cpp"
3132
"${EXECUTORCH_ROOT}/kernels/portable/cpu/util/kernel_ops_util.cpp"
3233
"${EXECUTORCH_ROOT}/kernels/portable/cpu/util/matmul_ops_util.cpp"

0 commit comments

Comments
 (0)