Skip to content

Commit 7059b27

Browse files
author
pytorchbot
committed
2024-11-18 nightly release (8526d0a)
1 parent c6936ba commit 7059b27

File tree

99 files changed

+828437
-1132
lines changed

Some content is hidden

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

99 files changed

+828437
-1132
lines changed

.ci/scripts/gather_test_models.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"resnet50": "linux.12xlarge",
2626
"llava": "linux.12xlarge",
2727
"llama3_2_vision_encoder": "linux.12xlarge",
28+
# "llama3_2_text_decoder": "linux.12xlarge", # TODO: re-enable test when Huy's change is in / model gets smaller.
2829
# This one causes timeout on smaller runner, the root cause is unclear (T161064121)
2930
"dl3": "linux.12xlarge",
3031
"emformer_join": "linux.12xlarge",

.ci/scripts/test_model.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ test_model() {
8787
bash examples/models/llava/install_requirements.sh
8888
STRICT="--no-strict"
8989
fi
90-
if [[ "$MODEL_NAME" == "llama3_2_vision_encoder" ]]; then
91-
# Install requirements for llama vision
90+
if [[ "$MODEL_NAME" == "llama3_2_vision_encoder" || "$MODEL_NAME" == "llama3_2_text_decoder" ]]; then
91+
# Install requirements for llama vision.
9292
bash examples/models/llama3_2_vision/install_requirements.sh
9393
fi
9494
# python3 -m examples.portable.scripts.export --model_name="llama2" should works too

.github/workflows/apple.yml

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,28 @@ on:
2020
- extension/benchmark/apple/**
2121
- extension/module/**
2222
workflow_dispatch:
23+
schedule:
24+
- cron: '0 10 * * *' # Runs daily at 2 AM PST
2325

2426
concurrency:
2527
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}-${{ github.event_name == 'workflow_dispatch' }}-${{ github.event_name == 'schedule' }}
2628
cancel-in-progress: true
2729

2830
jobs:
31+
set-version:
32+
runs-on: ubuntu-22.04
33+
outputs:
34+
version: ${{ steps.set_version.outputs.version }}
35+
steps:
36+
- name: Set VERSION variable
37+
id: set_version
38+
shell: bash
39+
run: |
40+
VERSION="0.4.0.$(TZ='PST8PDT' date +%Y%m%d)"
41+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
42+
2943
build-demo-ios:
3044
name: build-demo-ios
31-
# NB: Don't run this on fork PRs because they won't have access to the secret and would fail anyway
32-
if: ${{ !github.event.pull_request.head.repo.fork }}
3345
uses: pytorch/test-infra/.github/workflows/macos_job.yml@main
3446
secrets: inherit
3547
with:
@@ -41,6 +53,8 @@ jobs:
4153
secrets-env: BUILD_CERTIFICATE_BASE64 EXECUTORCH_DEMO_BUILD_PROVISION_PROFILE_BASE64 KEYCHAIN_PASSWORD
4254
upload-artifact: ios-apps
4355
script: |
56+
set -eux
57+
4458
BUILD_TOOL=cmake
4559
4660
.ci/scripts/setup-conda.sh
@@ -59,7 +73,7 @@ jobs:
5973
6074
# Build and test iOS Demo App
6175
PYTHON_EXECUTABLE=python ${CONDA_RUN} --no-capture-output \
62-
build/test_ios_ci.sh ${ARTIFACTS_DIR_NAME}
76+
build/test_ios_ci.sh "${ARTIFACTS_DIR_NAME}"
6377
6478
# Upload the test demo app to S3
6579
upload-demo-ios:
@@ -77,6 +91,7 @@ jobs:
7791
shell: bash
7892
working-directory: ${{ runner.temp }}/artifacts/
7993
run: |
94+
set -eux
8095
ls -lah ./
8196
8297
- name: Upload the artifacts to S3
@@ -114,6 +129,7 @@ jobs:
114129

115130
build-frameworks-ios:
116131
name: build-frameworks-ios
132+
needs: set-version
117133
uses: pytorch/test-infra/.github/workflows/macos_job.yml@main
118134
with:
119135
runner: macos-latest-xlarge
@@ -123,8 +139,10 @@ jobs:
123139
upload-artifact: executorch-frameworks-ios
124140
timeout: 90
125141
script: |
142+
set -eux
143+
126144
BUILD_TOOL=cmake
127-
VERSION="latest"
145+
VERSION="${{ needs.set-version.outputs.version }}"
128146
FRAMEWORKS=(
129147
"executorch"
130148
"backend_coreml"
@@ -173,13 +191,17 @@ jobs:
173191
174192
upload-frameworks-ios:
175193
runs-on: ubuntu-22.04
176-
needs: build-frameworks-ios
194+
needs: [build-frameworks-ios, set-version]
177195
timeout-minutes: 30
196+
environment: ${{ github.ref == 'refs/heads/main' && 'cherry-pick-bot' || '' }}
178197
permissions:
179198
id-token: write
180-
contents: read
199+
contents: write
181200
steps:
182201
- uses: actions/checkout@v3
202+
with:
203+
fetch-depth: 0
204+
token: ${{ secrets.GH_PYTORCHBOT_CHERRY_PICK_TOKEN || secrets.GITHUB_TOKEN }}
183205
- uses: actions/setup-python@v4
184206
with:
185207
python-version: '3.11'
@@ -196,15 +218,15 @@ jobs:
196218
name: executorch-frameworks-ios
197219
path: ${{ runner.temp }}/frameworks-ios/
198220
- name: Only push to S3 when running the workflow manually from main branch
199-
if: ${{ github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main' }}
221+
if: ${{ (github.event_name == 'schedule' || github.event_name == 'workflow_dispatch') && github.ref == 'refs/heads/main' }}
200222
shell: bash
201223
run: |
202-
set -eux
203224
echo "UPLOAD_ON_MAIN=1" >> "${GITHUB_ENV}"
204225
- name: Upload the artifact to ossci-ios S3 bucket
205226
shell: bash
206227
run: |
207228
set -eux
229+
VERSION="${{ needs.set-version.outputs.version }}"
208230
209231
pip install awscli==1.32.18
210232
@@ -215,14 +237,47 @@ jobs:
215237
216238
for FILENAME in "${RUNNER_TEMP}"/frameworks-ios/*.zip; do
217239
[ -e "${FILENAME}" ] || continue
218-
shasum -a 256 "${FILENAME}"
240+
FRAMEWORK_NAME=$(basename "${FILENAME}" | sed "s/-${VERSION}.zip//")
241+
CHECKSUM=$(shasum -a 256 "${FILENAME}" | cut -d ' ' -f1)
242+
echo "${FRAMEWORK_NAME} ${CHECKSUM}" >> "${RUNNER_TEMP}/checksums.txt"
219243
${AWS_CMD} "${FILENAME}" s3://ossci-ios/executorch/ --acl public-read
220244
done
245+
- name: Update SwiftPM
246+
shell: bash
247+
run: |
248+
set -eux
249+
VERSION="${{ needs.set-version.outputs.version }}"
250+
BRANCH="swiftpm-${VERSION}"
251+
252+
git checkout swiftpm
253+
254+
if git show-ref --verify --quiet refs/heads/${BRANCH}; then
255+
git checkout "${BRANCH}"
256+
else
257+
git checkout -b "${BRANCH}"
258+
fi
259+
260+
[[ -f Package.swift ]] || mv Package.swift.template Package.swift
261+
262+
sed -i "s/__VERSION__/${VERSION}/g" Package.swift
263+
264+
while read -r FRAMEWORK CHECKSUM; do
265+
sed -i "s/__SHA256_${FRAMEWORK}__/${CHECKSUM}/g" Package.swift
266+
done < "${RUNNER_TEMP}/checksums.txt"
267+
268+
if [[ "${UPLOAD_ON_MAIN:-0}" == "1" ]]; then
269+
git config --global user.name "PyTorch Bot"
270+
git config --global user.email "[email protected]"
271+
git add Package.swift
272+
git commit -am "${VERSION}"
273+
git push -f origin "${BRANCH}"
274+
else
275+
echo "Draft Package.swift:"
276+
cat Package.swift
277+
fi
221278
222279
build-benchmark-app:
223280
name: build-benchmark-app
224-
# NB: Don't run this on fork PRs because they won't have access to the secret and would fail anyway
225-
if: ${{ !github.event.pull_request.head.repo.fork }}
226281
uses: pytorch/test-infra/.github/workflows/macos_job.yml@main
227282
secrets: inherit
228283
with:
@@ -285,5 +340,5 @@ jobs:
285340
echo "::group::Build ExecuTorch benchmark app"
286341
mkdir -p extension/benchmark/apple/Benchmark/Models
287342
${CONDA_RUN} --no-capture-output \
288-
build/build_apple_llm_demo.sh ${ARTIFACTS_DIR_NAME}
343+
build/build_apple_llm_demo.sh "${ARTIFACTS_DIR_NAME}"
289344
echo "::endgroup::"

.github/workflows/trunk.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -411,8 +411,6 @@ jobs:
411411
pip install -U "huggingface_hub[cli]"
412412
huggingface-cli login --token $SECRET_EXECUTORCH_HF_TOKEN
413413
pip install accelerate sentencepiece
414-
# TODO(guangyang): Switch to use released transformers library after all required patches are included
415-
pip install "git+https://github.com/huggingface/transformers.git@6cc4dfe3f1e8d421c6d6351388e06e9b123cbfe1"
416414
pip list
417415
echo "::endgroup::"
418416

backends/arm/TARGETS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ python_library(
99
typing = True,
1010
deps = [
1111
":arm_backend",
12+
"//executorch/backends/arm/operator_support:operator_support",
1213
"//executorch/backends/arm/_passes:passes",
1314
"//executorch/exir:lib",
1415
],

backends/arm/arm_partitioner.py

Lines changed: 12 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -6,27 +6,27 @@
66
# pyre-unsafe
77

88
import logging
9-
import operator
109
import os
11-
from typing import Callable, cast, final, List, Optional, Tuple
10+
from typing import Callable, final, List, Optional, Tuple
1211

1312
import torch
1413
from executorch.backends.arm.arm_backend import ArmBackend # usort: skip
1514
from executorch.backends.arm._passes.tag_io_quant_pass import TagIOQuantPass
15+
from executorch.backends.arm.operator_support.tosa_supported_operators import (
16+
TOSASupportedOperators,
17+
)
18+
from executorch.backends.arm.tosa_specification import TosaSpecification
1619
from executorch.exir.backend.compile_spec_schema import CompileSpec
1720
from executorch.exir.backend.partitioner import (
1821
DelegationSpec,
1922
Partitioner,
2023
PartitionResult,
2124
)
2225
from executorch.exir.backend.utils import tag_constant_data
23-
from executorch.exir.dialects._ops import ops as exir_ops
2426
from executorch.exir.passes import PassManager
2527
from torch.export.exported_program import ExportedProgram
2628
from torch.fx.passes.infra.partitioner import CapabilityBasedPartitioner
2729

28-
from torch.fx.passes.operator_support import OperatorSupportBase
29-
3030
logger = logging.getLogger(__name__)
3131
logger.setLevel(logging.WARNING)
3232
TOSA_DBG_VERBOSE = os.environ.get("TOSA_DBG_VERBOSE") == "1"
@@ -35,71 +35,6 @@
3535
logger.setLevel(logging.INFO)
3636

3737

38-
class TOSASupportedOperators(OperatorSupportBase):
39-
def is_node_supported(self, submodules, node: torch.fx.Node) -> bool:
40-
supported = node.op == "call_function" and node.target in [
41-
exir_ops.edge.aten.add.Tensor,
42-
exir_ops.edge.aten.expand_copy.default,
43-
exir_ops.edge.aten.cat.default,
44-
exir_ops.edge.aten.bmm.default,
45-
exir_ops.edge.aten.permute_copy.default,
46-
exir_ops.edge.aten.hardtanh.default,
47-
exir_ops.edge.aten.convolution.default,
48-
exir_ops.edge.aten.div.Tensor,
49-
exir_ops.edge.aten.exp.default,
50-
exir_ops.edge.aten.log.default,
51-
exir_ops.edge.aten.linear.default,
52-
exir_ops.edge.aten.split_with_sizes_copy.default,
53-
exir_ops.edge.aten.full.default,
54-
exir_ops.edge.aten.mul.Tensor,
55-
exir_ops.edge.aten._native_batch_norm_legit_no_training.default,
56-
exir_ops.edge.aten.native_layer_norm.default,
57-
exir_ops.edge.aten.avg_pool2d.default,
58-
exir_ops.edge.aten.max_pool2d_with_indices.default,
59-
exir_ops.edge.aten.sigmoid.default,
60-
exir_ops.edge.aten.mm.default,
61-
exir_ops.edge.aten.repeat.default,
62-
exir_ops.edge.aten.reciprocal.default,
63-
exir_ops.edge.aten.relu.default,
64-
exir_ops.edge.aten.rsqrt.default,
65-
exir_ops.edge.aten._softmax.default,
66-
exir_ops.edge.aten.select_copy.int,
67-
exir_ops.edge.aten._log_softmax.default,
68-
exir_ops.edge.aten.slice_copy.Tensor,
69-
exir_ops.edge.aten.sub.Tensor,
70-
exir_ops.edge.aten.sum.dim_IntList,
71-
exir_ops.edge.aten.tanh.default,
72-
exir_ops.edge.aten.upsample_nearest2d.vec,
73-
exir_ops.edge.aten.view_copy.default,
74-
exir_ops.edge.aten.clone.default,
75-
exir_ops.edge.aten.mean.dim,
76-
exir_ops.edge.aten.var.correction,
77-
exir_ops.edge.aten.unsqueeze_copy.default,
78-
exir_ops.edge.aten.squeeze_copy.dims,
79-
operator.getitem,
80-
exir_ops.edge.quantized_decomposed.quantize_per_tensor.default,
81-
exir_ops.edge.quantized_decomposed.dequantize_per_tensor.default,
82-
]
83-
84-
supported &= self.is_node_supported_custom(node)
85-
86-
# Override partitioning based on pre partition passes
87-
if "arm_override_partition" in node.meta:
88-
supported = supported & node.meta["arm_override_partition"]
89-
node.meta.pop("arm_override_partition")
90-
91-
return supported
92-
93-
def is_node_supported_custom(self, node: torch.fx.Node) -> bool:
94-
if node.target == exir_ops.edge.aten.mean.dim:
95-
keep_dim = node.args[2] if len(node.args) > 2 else False
96-
return cast(bool, keep_dim)
97-
if node.target == exir_ops.edge.aten.var.correction:
98-
keep_dim = node.kwargs.get("keepdim", False)
99-
return cast(bool, keep_dim)
100-
return True
101-
102-
10338
@final
10439
class ArmPartitioner(Partitioner):
10540
def __init__(self, compile_spec: List[CompileSpec]) -> None:
@@ -111,6 +46,12 @@ def partition(self, exported_program: ExportedProgram) -> PartitionResult:
11146
logger.info("ArmPartitioner::partition")
11247
partition_tags = {}
11348

49+
tosa_spec = TosaSpecification.create_from_compilespecs(
50+
self.delegation_spec.compile_specs
51+
)
52+
53+
logger.info(f"Partitioning for {tosa_spec}")
54+
11455
for spec in self.delegation_spec.compile_specs:
11556
if spec.key == "quantize_io" and spec.value.decode() == "True":
11657
# Exclude IO quantization from the partition
@@ -123,7 +64,7 @@ def partition(self, exported_program: ExportedProgram) -> PartitionResult:
12364

12465
capability_partitioner = CapabilityBasedPartitioner(
12566
exported_program.graph_module,
126-
TOSASupportedOperators(),
67+
TOSASupportedOperators(tosa_spec),
12768
allows_single_node_partition=True,
12869
)
12970
partition_list = capability_partitioner.propose_partitions()
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
load("@fbcode_macros//build_defs:python_library.bzl", "python_library")
2+
3+
python_library(
4+
name = "operator_support",
5+
srcs = glob(["*.py"]),
6+
typing = True,
7+
deps = [
8+
"//executorch/backends/xnnpack/_passes:xnnpack_passes",
9+
"//executorch/exir:lib",
10+
"//executorch/backends/arm:tosa_specification"
11+
],
12+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright 2024 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+
# pyre-unsafe
7+
8+
from . import mean_dim_support, tosa_supported_operators, var_correction_support # noqa
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright 2024 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+
# pyre-unsafe
7+
8+
from typing import cast
9+
10+
import torch.fx as fx
11+
12+
from executorch.backends.arm.operator_support.tosa_supported_operators import (
13+
register_tosa_support_check,
14+
SupportedTOSAOperatorCheck,
15+
)
16+
from executorch.backends.arm.tosa_specification import TosaSpecification
17+
from executorch.exir.dialects._ops import ops as exir_ops
18+
19+
20+
@register_tosa_support_check
21+
class MeanDimSupported(SupportedTOSAOperatorCheck):
22+
targets = [exir_ops.edge.aten.mean.dim]
23+
24+
tosa_specs = [
25+
TosaSpecification.create_from_string("TOSA-0.80.0+BI"),
26+
TosaSpecification.create_from_string("TOSA-0.80.0+MI"),
27+
]
28+
29+
def is_node_supported(self, node: fx.Node, tosa_spec: TosaSpecification) -> bool:
30+
assert node.target in self.targets
31+
32+
keep_dim = node.args[2] if len(node.args) > 2 else False
33+
return cast(bool, keep_dim)

0 commit comments

Comments
 (0)