Skip to content

Commit fb3918e

Browse files
committed
[UPDATE] Update
[ghstack-poisoned]
2 parents 27fe88b + 83c84dc commit fb3918e

728 files changed

Lines changed: 56674 additions & 11740 deletions

File tree

Some content is hidden

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

.ci/docker/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ esac
102102
TORCH_VERSION=$(cat ci_commit_pins/pytorch.txt)
103103
BUILD_DOCS=1
104104

105-
if [[ "${GCC_VERSION:-}" == "11" && -z "${SKIP_PYTORCH:-}" ]]; then
105+
if [[ -n "${GCC_VERSION:-}" && -z "${SKIP_PYTORCH:-}" ]]; then
106106
PYTORCH_BUILD_MAX_JOBS=6
107107
fi
108108

.ci/scripts/bloaty-measure.sh

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/usr/bin/env bash
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
# All rights reserved.
4+
#
5+
# This source code is licensed under the BSD-style license found in the
6+
# LICENSE file in the root directory of this source tree.
7+
8+
# Usage: bash .ci/scripts/bloaty-measure.sh <job_name> <head_elf> <strip_tool>
9+
#
10+
# Runs bloaty against the head ELF, writes metadata.json + full.txt +
11+
# head_only.txt to artifacts-to-be-uploaded/, and appends a markdown table
12+
# to $GITHUB_STEP_SUMMARY.
13+
#
14+
# Best-effort: never exits non-zero — the size jobs that source this should
15+
# not fail because of a bloaty hiccup.
16+
17+
set -uo pipefail
18+
19+
job_name=$1
20+
head_elf=$2
21+
strip_tool=$3
22+
head_sha=${GITHUB_HEAD_SHA:-${GITHUB_SHA:-unknown}}
23+
24+
(
25+
# conda-forge bloaty depends on a newer libstdc++ than the ubuntu-22.04
26+
# docker images ship, so pull libstdcxx-ng into the same env and invoke
27+
# via `conda run` so library paths are set correctly.
28+
bloaty_env=/tmp/bloaty-conda-env
29+
if [[ ! -x "${bloaty_env}/bin/bloaty" ]]; then
30+
conda create -y -p "${bloaty_env}" -c conda-forge bloaty libstdcxx-ng || exit 1
31+
fi
32+
bloaty_cmd=("conda" "run" "--no-capture-output" "-p" "${bloaty_env}" "bloaty")
33+
"${bloaty_cmd[@]}" --version || exit 1
34+
35+
tmp_out=/tmp/bloaty-out
36+
rm -rf "${tmp_out}" && mkdir -p "${tmp_out}"
37+
BLOATY="${bloaty_cmd[*]}" python3 .github/scripts/bloaty_diff.py measure \
38+
--head "${head_elf}" \
39+
--job "${job_name}" \
40+
--binary-name size_test \
41+
--head-sha "${head_sha}" \
42+
--strip-tool "${strip_tool}" \
43+
--out "${tmp_out}" || exit 1
44+
mkdir -p artifacts-to-be-uploaded
45+
mv "${tmp_out}"/* artifacts-to-be-uploaded/
46+
) || echo "bloaty report failed; continuing"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash
2+
# Copyright (c) Qualcomm Innovation Center, Inc.
3+
# All rights reserved
4+
#
5+
# This source code is licensed under the BSD-style license found in the
6+
# LICENSE file in the root directory of this source tree.
7+
8+
set -eux
9+
10+
source "$(dirname "${BASH_SOURCE[0]}")/../../backends/qualcomm/scripts/install_qnn_sdk.sh"
11+
12+
setup_android_ndk
13+
install_qnn
14+
install_hexagon_sdk
15+
16+
bash backends/qualcomm/scripts/build.sh \
17+
--build_direct_mode 3 --soc_model SM8750 \
18+
--skip_x86_64 --skip_linux_android \
19+
--release
20+
21+
ARTIFACT="build-direct/backends/qualcomm/libqnn_executorch_backend.so"
22+
if [ ! -f "${ARTIFACT}" ]; then
23+
echo "ERROR: direct-mode build did not produce ${ARTIFACT}" >&2
24+
exit 1
25+
fi
26+
27+
MAX_SIZE_BYTES=$((200 * 1024))
28+
ARTIFACT_SIZE=$(stat -c%s "${ARTIFACT}")
29+
if [ "${ARTIFACT_SIZE}" -gt "${MAX_SIZE_BYTES}" ]; then
30+
echo "ERROR: ${ARTIFACT} is ${ARTIFACT_SIZE} bytes, exceeds ${MAX_SIZE_BYTES}-byte (200 KiB) limit" >&2
31+
exit 1
32+
fi
33+
echo "PASSED: direct-mode build produced ${ARTIFACT} (${ARTIFACT_SIZE} bytes, under ${MAX_SIZE_BYTES}-byte limit)"
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/bin/bash
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
# All rights reserved.
4+
#
5+
# This source code is licensed under the BSD-style license found in the
6+
# LICENSE file in the root directory of this source tree.
7+
8+
# Vendor Dawn (Tint) + SwiftShader for the WebGPU backend CI WITHOUT hosting a
9+
# private prebuilt:
10+
# * Dawn : Google's official nightly prebuilt, downloaded directly from
11+
# github.com/google/dawn/releases (pinned tag+rev+sha256) -- the same
12+
# "fetch a pinned upstream prebuilt" pattern used for other CI deps.
13+
# * SwiftShader : built from source at a pinned rev compatible with the Dawn
14+
# above (the ossci prebuilt is from 2020, too old for current Dawn). No S3.
15+
# Dawn (Chrome's WebGPU impl; its WGSL compiler Tint is the spec reference) on
16+
# SwiftShader gives a headless, deterministic, spec-faithful CLI backend.
17+
#
18+
# Exports Dawn_DIR / VK_ICD_FILENAMES / LD_LIBRARY_PATH for the cmake build+run.
19+
# Local/rig override: set DAWN_PREBUILT_DIR=<dir containing lib64/cmake/Dawn> to
20+
# skip the Dawn download.
21+
set -ex
22+
23+
# --- pinned versions (bump rev+sha together when upgrading Dawn) --------------
24+
DAWN_TAG="${DAWN_TAG:-v20260423.175430}"
25+
DAWN_REV="${DAWN_REV:-31e25af254ab572c77054edec4946d2244e184dd}"
26+
DAWN_SHA256="${DAWN_SHA256:-ac76fac090162dc1ecea5ed0f28a557bb8f49efc47faab01886105ace82b7b64}"
27+
# SwiftShader rev verified compatible with DAWN_REV (the old ossci prebuilt is
28+
# from 2020 and is incompatible with current Dawn -> no adapter / zero compute).
29+
SWIFTSHADER_REV="${SWIFTSHADER_REV:-9898204d91d6a60b6a08ad74fe4ac52a6913111b}"
30+
31+
_dawn_dir="${DAWN_PREBUILT_DIR:-/tmp/dawn-ci}"
32+
_ss_dir=/tmp/swiftshader
33+
34+
# --- toolchain prereqs --------------------------------------------------------
35+
# Dawn dlopens the system Vulkan loader at runtime (libvulkan1). And the
36+
# ubuntu-latest prebuilt is built with a bleeding-edge GCC: it references
37+
# libstdc++ symbols newer than ubuntu-22.04's default (e.g. _M_replace_cold,
38+
# GCC 13+), so the static .a won't link against the stock runtime. Pull a current
39+
# libstdc++ from the ubuntu-toolchain-r PPA when the symbol floor isn't met. All
40+
# of this is scoped to the WebGPU CI job; newer libstdc++ is backward-compatible.
41+
if command -v apt-get >/dev/null 2>&1; then
42+
_SUDO=""; command -v sudo >/dev/null 2>&1 && _SUDO="sudo"
43+
${_SUDO} apt-get update -y || true
44+
${_SUDO} apt-get install -y libvulkan1 software-properties-common || true
45+
if ! strings /usr/lib/x86_64-linux-gnu/libstdc++.so.6 2>/dev/null \
46+
| grep -q "GLIBCXX_3.4.32"; then
47+
${_SUDO} add-apt-repository -y ppa:ubuntu-toolchain-r/test || true
48+
${_SUDO} apt-get update -y || true
49+
${_SUDO} apt-get install -y libstdc++6 || true # newest GCC runtime
50+
fi
51+
fi
52+
53+
# The native binaries / pybind lib run INSIDE the CI conda env, whose libstdc++
54+
# predates GLIBCXX_3.4.32 (the Dawn prebuilt's floor) -- the same wall ssjia hit
55+
# for the vulkan op tests. Upgrade the conda runtime libstdc++ so the loaded
56+
# libstdc++.so.6 (conda's, not the system one) satisfies Dawn at run time.
57+
if command -v conda >/dev/null 2>&1; then
58+
conda install -y -c conda-forge "libstdcxx-ng>=14" || true
59+
fi
60+
61+
# --- Dawn: official prebuilt from GitHub (no S3) ------------------------------
62+
mkdir -p "${_dawn_dir}"
63+
if [[ ! -d "${_dawn_dir}/lib64/cmake/Dawn" ]]; then
64+
_dawn_tar="/tmp/Dawn-${DAWN_REV}-ubuntu-latest-Release.tar.gz"
65+
curl --silent --show-error --location --fail --retry 3 --retry-all-errors \
66+
--output "${_dawn_tar}" \
67+
"https://github.com/google/dawn/releases/download/${DAWN_TAG}/Dawn-${DAWN_REV}-ubuntu-latest-Release.tar.gz"
68+
echo "${DAWN_SHA256} ${_dawn_tar}" | sha256sum -c -
69+
# archive top dir is Dawn-<rev>-ubuntu-latest-Release/{lib64,include,bin}
70+
tar -C "${_dawn_dir}" --strip-components=1 -xzf "${_dawn_tar}"
71+
fi
72+
73+
# --- SwiftShader: build from source at a pinned rev (no S3) -------------------
74+
# The old ossci prebuilt (swiftshader-abe07b943, 2020) is incompatible with the
75+
# current Dawn; build a matching modern SwiftShader instead. Self-contained
76+
# cmake build (vendored LLVM); the ICD lands under build/<OS>/.
77+
if [[ ! -d "${_ss_dir}/build" ]]; then
78+
if [[ ! -d "${_ss_dir}/.git" ]]; then
79+
git clone https://github.com/google/swiftshader "${_ss_dir}"
80+
fi
81+
git -C "${_ss_dir}" checkout "${SWIFTSHADER_REV}"
82+
# vk_swiftshader's deps are vendored in-tree; tolerate unreachable
83+
# disabled-feature submodules (angle, test-only) failing to fetch.
84+
git -C "${_ss_dir}" submodule update --init --recursive || true
85+
cmake -S "${_ss_dir}" -B "${_ss_dir}/build" -DCMAKE_BUILD_TYPE=Release \
86+
-DSWIFTSHADER_BUILD_TESTS=OFF -DSWIFTSHADER_BUILD_PVR=OFF \
87+
-DSWIFTSHADER_BUILD_BENCHMARKS=OFF
88+
cmake --build "${_ss_dir}/build" --parallel "$(nproc)" --target vk_swiftshader
89+
fi
90+
_ss_icd="$(find "${_ss_dir}/build" -name vk_swiftshader_icd.json 2>/dev/null | head -1)"
91+
[[ -n "${_ss_icd}" ]] || { echo "ERROR: SwiftShader ICD not found after build" >&2; exit 1; }
92+
93+
_ss_libdir="$(dirname "${_ss_icd}")"
94+
export Dawn_DIR="${_dawn_dir}/lib64/cmake/Dawn"
95+
export VK_ICD_FILENAMES="${_ss_icd}"
96+
export LD_LIBRARY_PATH="${_ss_libdir}:${LD_LIBRARY_PATH:-}"
97+
export WEBGPU_USING_SWIFTSHADER=1

.ci/scripts/test_backend.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ if [[ "$FLOW" == *vulkan* ]]; then
5757
EXTRA_BUILD_ARGS+=" -DEXECUTORCH_BUILD_VULKAN=ON"
5858
fi
5959

60+
if [[ "$FLOW" == *webgpu* ]]; then
61+
# Dawn (Tint) + SwiftShader, the spec-faithful headless WebGPU backend.
62+
source .ci/scripts/setup-webgpu-linux-deps.sh
63+
64+
EXTRA_BUILD_ARGS+=" -DEXECUTORCH_BUILD_WEBGPU=ON -DDawn_DIR=$Dawn_DIR"
65+
fi
66+
6067
if [[ "$FLOW" == *arm* ]]; then
6168
if [[ "$SUITE" == "operators" ]]; then
6269
PYTEST_RETRY_ARGS=(--reruns 2 --reruns-delay 1)

.ci/scripts/test_cortex_m_e2e.sh

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,14 @@
1414
set -eu
1515

1616
MODEL=$1
17+
TARGET=${2:-cortex-m55}
1718
script_dir=$(realpath "$(dirname "${BASH_SOURCE[0]}")")
1819
et_root_dir=$(realpath "${script_dir}/../..")
1920

20-
# Quantization is the default for the cortex-m55 target; run.sh's
21+
# Quantization is the default for cortex-m targets; run.sh's
2122
# arg parser only recognizes --no_quantize, so we omit any explicit flag.
2223
export ARM_FVP_INSTALL_I_AGREE_TO_THE_CONTAINED_EULA=True
2324
bash "${et_root_dir}/examples/arm/run.sh" \
2425
--model_name="${MODEL}" \
25-
--target=cortex-m55 \
26+
--target="${TARGET}" \
2627
--bundleio

.ci/scripts/test_minimal_wheel.sh

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
#!/bin/bash
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
# All rights reserved.
4+
#
5+
# This source code is licensed under the BSD-style license found in the
6+
# LICENSE file in the root directory of this source tree.
7+
8+
set -euxo pipefail
9+
10+
PYTHON_EXECUTABLE="${PYTHON_EXECUTABLE:-python}"
11+
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
12+
BUILD_VENV="${REPO_ROOT}/.venv-minimal-build"
13+
TEST_VENV="${REPO_ROOT}/.venv-minimal-test"
14+
15+
rm -rf "${BUILD_VENV}" "${TEST_VENV}" "${REPO_ROOT}/dist" "${REPO_ROOT}/pip-out"
16+
17+
"${PYTHON_EXECUTABLE}" -m venv "${BUILD_VENV}"
18+
source "${BUILD_VENV}/bin/activate"
19+
python -m pip install --upgrade pip
20+
python -m pip install \
21+
"cmake>=3.24,<4.0.0" \
22+
"numpy>=2.0.0" \
23+
packaging \
24+
pyyaml \
25+
setuptools \
26+
wheel \
27+
zstd \
28+
certifi \
29+
torch \
30+
torchvision \
31+
--index-url https://download.pytorch.org/whl/cpu \
32+
--extra-index-url https://pypi.org/simple
33+
34+
(
35+
cd "${REPO_ROOT}"
36+
EXECUTORCH_BUILD_MINIMAL=1 python setup.py bdist_wheel
37+
)
38+
39+
WHEEL_FILE="$(find "${REPO_ROOT}/dist" -maxdepth 1 -name 'executorch-*.whl' | head -1)"
40+
test -n "${WHEEL_FILE}"
41+
42+
python - "${WHEEL_FILE}" <<'PY'
43+
import re
44+
import sys
45+
import zipfile
46+
47+
wheel_file = sys.argv[1]
48+
with zipfile.ZipFile(wheel_file) as wheel:
49+
names = wheel.namelist()
50+
metadata_name = next(
51+
(name for name in names if name.endswith(".dist-info/METADATA")), None
52+
)
53+
if metadata_name is None:
54+
raise AssertionError(f"{wheel_file} has no METADATA")
55+
metadata_text = wheel.read(metadata_name).decode("utf-8")
56+
57+
for forbidden in (
58+
"executorch/backends/",
59+
"executorch/examples/",
60+
"executorch/kernels/",
61+
"executorch/runtime/",
62+
"executorch/devtools/",
63+
"executorch/extension/pybindings/",
64+
):
65+
matches = [name for name in names if name.startswith(forbidden)]
66+
if matches:
67+
raise AssertionError(f"{wheel_file} unexpectedly contains {matches[:5]}")
68+
69+
extensions = [
70+
name
71+
for name in names
72+
if name.endswith((".so", ".dylib", ".dll", ".pyd")) and "flatc" not in name
73+
]
74+
if extensions:
75+
raise AssertionError(f"{wheel_file} unexpectedly contains extensions: {extensions}")
76+
77+
78+
def _dist_name(requirement):
79+
name = re.split(r"[ ;\[<>=!~(]", requirement.strip(), maxsplit=1)[0]
80+
return re.sub(r"[-_.]+", "-", name).lower()
81+
82+
83+
# Only the core (non-extra) Requires-Dist entries define what a plain
84+
# "pip install" pulls; ignore the optional extras (cortex_m, vgf, ...).
85+
declared = {
86+
_dist_name(line.split(":", 1)[1])
87+
for line in metadata_text.splitlines()
88+
if line.startswith("Requires-Dist:") and "extra==" not in line.replace(" ", "")
89+
}
90+
# The minimal wheel must declare EXACTLY this core set and nothing else -- the
91+
# same names as `keep` in setup.py:_minimal_dependencies(). Exact match catches
92+
# both a heavy full-wheel dep leaking in (coremltools, pandas, or a re-added
93+
# mpmath/torch) and a required dep going missing.
94+
expected = {
95+
"flatbuffers",
96+
"numpy",
97+
"packaging",
98+
"pyyaml",
99+
"ruamel-yaml",
100+
"sympy",
101+
"tabulate",
102+
"typing-extensions",
103+
}
104+
if declared != expected:
105+
raise AssertionError(
106+
f"{wheel_file} minimal core deps mismatch: "
107+
f"unexpected={sorted(declared - expected)} missing={sorted(expected - declared)}"
108+
)
109+
PY
110+
111+
deactivate
112+
113+
"${PYTHON_EXECUTABLE}" -m venv "${TEST_VENV}"
114+
source "${TEST_VENV}/bin/activate"
115+
python -m pip install --upgrade pip
116+
# torch and torchvision are needed to export a model but are intentionally not
117+
# declared as wheel dependencies (consumers are expected to bring their own).
118+
python -m pip install \
119+
"torch" \
120+
"torchvision" \
121+
--index-url https://download.pytorch.org/whl/cpu \
122+
--extra-index-url https://pypi.org/simple
123+
# Install the minimal wheel WITHOUT --no-deps so pip resolves its declared
124+
# dependencies, confirming the slim set is correct and resolvable. (That no heavy
125+
# deps sneak in is guaranteed by the METADATA exact-match check above, which
126+
# covers the wheel's direct Requires-Dist.)
127+
python -m pip install \
128+
"${WHEEL_FILE}" \
129+
--index-url https://download.pytorch.org/whl/cpu \
130+
--extra-index-url https://pypi.org/simple
131+
132+
# flatc is the only compiled artifact in the minimal wheel and the reason it is
133+
# platform specific. Confirm it ships, resolves through _get_flatc_path() (the
134+
# executorch.data.bin lookup added for this build mode), and actually runs.
135+
python - <<'PY'
136+
import subprocess
137+
138+
from executorch.exir._serialize._flatbuffer import _get_flatc_path
139+
140+
flatc_path = _get_flatc_path()
141+
print(f"flatc resolved to: {flatc_path}")
142+
subprocess.run([flatc_path, "--version"], check=True)
143+
PY
144+
145+
python - <<'PY'
146+
from pathlib import Path
147+
148+
import torch
149+
from torch.export import export
150+
from torchvision.models import mobilenet_v2
151+
152+
from executorch.exir import to_edge_transform_and_lower
153+
154+
model = mobilenet_v2(weights=None).eval()
155+
example_inputs = (torch.randn(1, 3, 224, 224),)
156+
157+
edge_program = to_edge_transform_and_lower(export(model, example_inputs))
158+
executorch_program = edge_program.to_executorch()
159+
160+
output_path = Path("mv2_minimal.pte")
161+
with output_path.open("wb") as output_file:
162+
executorch_program.write_to_file(output_file)
163+
164+
assert output_path.stat().st_size > 0
165+
PY

0 commit comments

Comments
 (0)