Skip to content

Commit b60ea84

Browse files
committed
Update
[ghstack-poisoned]
2 parents 12c6c05 + ddf38f2 commit b60ea84

263 files changed

Lines changed: 12005 additions & 2632 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/scripts/test-cadence-xtensa.sh

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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+
# Build the Cadence Xtensa op-level gtest tests for the configured backend and
9+
# run them on the Instruction Set Simulator (xt-run).
10+
#
11+
# Requires the Xtensa toolchain env to already be set (run
12+
# .ci/scripts/setup-xtensa-tools.sh <backend> first): XTENSA_TOOLCHAIN,
13+
# TOOLCHAIN_VER, XTENSA_CORE, CADENCE_OPT_FLAG, and xt-clang/xt-run on PATH.
14+
#
15+
# Unlike build-cadence-xtensa.sh (the runner, built -fno-exceptions -fno-rtti),
16+
# the gtest tests need exceptions + RTTI, so those flags are NOT set here.
17+
18+
set -euo pipefail
19+
20+
: "${XTENSA_TOOLCHAIN:?run setup-xtensa-tools.sh first}"
21+
: "${TOOLCHAIN_VER:?run setup-xtensa-tools.sh first}"
22+
: "${XTENSA_CORE:?run setup-xtensa-tools.sh first}"
23+
: "${CADENCE_OPT_FLAG:?run setup-xtensa-tools.sh first}"
24+
25+
# Map the optimized-kernel flag to the backend dir + gtest target name.
26+
case "${CADENCE_OPT_FLAG}" in
27+
EXECUTORCH_NNLIB_OPT) TARGET_DIR=hifi ;;
28+
EXECUTORCH_VISION_OPT) TARGET_DIR=vision ;;
29+
EXECUTORCH_FUSION_G3_OPT) TARGET_DIR=fusion_g3 ;;
30+
*)
31+
echo "ERROR: unknown CADENCE_OPT_FLAG='${CADENCE_OPT_FLAG}'" >&2
32+
exit 1
33+
;;
34+
esac
35+
TEST_TARGET="cadence_${TARGET_DIR}_op_tests"
36+
TEST_ELF="cmake-out/backends/cadence/${TARGET_DIR}/operators/tests/${TEST_TARGET}"
37+
38+
NPROC=$(nproc)
39+
echo "=== building ${TEST_TARGET} for ${XTENSA_CORE} (${CADENCE_OPT_FLAG}) ==="
40+
xt-clang --version | head -1
41+
42+
rm -rf cmake-out
43+
cmake \
44+
-DCMAKE_TOOLCHAIN_FILE=./backends/cadence/cadence.cmake \
45+
-DCMAKE_INSTALL_PREFIX=cmake-out \
46+
-DCMAKE_BUILD_TYPE=Release \
47+
-DEXECUTORCH_BUILD_CADENCE=ON \
48+
"-D${CADENCE_OPT_FLAG}=ON" \
49+
-DEXECUTORCH_BUILD_PORTABLE_OPS=ON \
50+
-DEXECUTORCH_BUILD_CADENCE_OP_TESTS=ON \
51+
-DEXECUTORCH_BUILD_EXECUTOR_RUNNER=OFF \
52+
-DEXECUTORCH_BUILD_EXTENSION_RUNNER_UTIL=ON \
53+
-DEXECUTORCH_ENABLE_LOGGING=ON \
54+
-DEXECUTORCH_BUILD_PTHREADPOOL=OFF \
55+
-DEXECUTORCH_BUILD_CPUINFO=OFF \
56+
-DEXECUTORCH_USE_DL=OFF \
57+
-DEXECUTORCH_BUILD_KERNELS_LLM=OFF \
58+
-DEXECUTORCH_BUILD_DEVTOOLS=OFF \
59+
-DHAVE_FNMATCH_H=OFF \
60+
-DFLATCC_ALLOW_WERROR=OFF \
61+
-DPYTHON_EXECUTABLE="$(which python3)" \
62+
-Bcmake-out .
63+
64+
cmake --build cmake-out --target "${TEST_TARGET}" -j"${NPROC}"
65+
66+
if [[ ! -f "${TEST_ELF}" ]]; then
67+
echo "ERROR: ${TEST_ELF} was not produced" >&2
68+
exit 1
69+
fi
70+
71+
echo "=== running ${TEST_TARGET} on xt-run ==="
72+
LOG=$(mktemp)
73+
# --exit_with_target_code propagates gtest_main's exit code, so a failing test
74+
# fails this step; also assert on the gtest summary lines as a backstop.
75+
xt-run --turbo --exit_with_target_code "${TEST_ELF}" 2>&1 | tee "${LOG}"
76+
if grep -q "\[ FAILED \]" "${LOG}"; then
77+
echo "ERROR: gtest reported failures for ${TEST_TARGET}" >&2
78+
exit 1
79+
fi
80+
if ! grep -q "\[ PASSED \]" "${LOG}"; then
81+
echo "ERROR: ${TEST_TARGET} did not report a gtest PASSED summary" >&2
82+
exit 1
83+
fi
84+
echo "Cadence ${TARGET_DIR} op tests passed on ${XTENSA_CORE}."

.ci/scripts/wheel/pre_build_script.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,8 @@ if [[ "${EXECUTORCH_BUILD_VULKAN:-0}" != "0" \
122122
echo "${_glslc_prefix}/bin" >> "${GITHUB_PATH}"
123123
echo "glslc installed: $(command -v glslc)"
124124
fi
125+
else
126+
# This is the Vulkan equivalent of the Windows CUDA force-off above (#20527).
127+
export CMAKE_ARGS="${CMAKE_ARGS:-} -DEXECUTORCH_BUILD_VULKAN=OFF"
128+
echo "CMAKE_ARGS=${CMAKE_ARGS}" >> "${GITHUB_ENV}"
125129
fi

.ci/scripts/wheel/test_base.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Copyright (c) Meta Platforms, Inc. and affiliates.
22
# All rights reserved.
3+
# Copyright 2026 Arm Limited and/or its affiliates.
34
#
45
# This source code is licensed under the BSD-style license found in the
56
# LICENSE file in the root directory of this source tree.
@@ -40,6 +41,23 @@ class ModelTest:
4041
backend: Backend
4142

4243

44+
def test_cmsis_nn_install():
45+
import executorch.backends.cortex_m.library.cmsis_nn as cmsis_nn
46+
47+
buf_size = cmsis_nn.convolve_wrapper_buffer_size(
48+
cmsis_nn.Backend.MVE,
49+
cmsis_nn.DataType.A8W8,
50+
input_nhwc=[1, 8, 8, 16],
51+
filter_nhwc=[8, 3, 3, 16],
52+
output_nhwc=[1, 6, 6, 8],
53+
padding_hw=[0, 0],
54+
stride_hw=[1, 1],
55+
dilation_hw=[1, 1],
56+
)
57+
58+
assert buf_size == 576
59+
60+
4361
def run_tests(model_tests: List[ModelTest]) -> None:
4462
# Test that we can import the portable_lib module - verifies RPATH is correct
4563
print("Testing portable_lib import...")

.ci/scripts/wheel/test_linux.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python
22
# Copyright (c) Meta Platforms, Inc. and affiliates.
33
# All rights reserved.
4+
# Copyright 2026 Arm Limited and/or its affiliates.
45
#
56
# This source code is licensed under the BSD-style license found in the
67
# LICENSE file in the root directory of this source tree.
@@ -38,6 +39,8 @@
3839
else:
3940
print("⚠ VulkanBackend not registered (expected for the default wheel)")
4041

42+
test_base.test_cmsis_nn_install()
43+
4144
test_base.run_tests(
4245
model_tests=[
4346
test_base.ModelTest(

.ci/scripts/wheel/test_macos.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python
22
# Copyright (c) Meta Platforms, Inc. and affiliates.
33
# All rights reserved.
4+
# Copyright 2026 Arm Limited and/or its affiliates.
45
#
56
# This source code is licensed under the BSD-style license found in the
67
# LICENSE file in the root directory of this source tree.
@@ -9,6 +10,8 @@
910
from examples.models import Backend, Model
1011

1112
if __name__ == "__main__":
13+
test_base.test_cmsis_nn_install()
14+
1215
test_base.run_tests(
1316
model_tests=[
1417
test_base.ModelTest(

.ci/scripts/wheel/test_windows.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
#!/usr/bin/env python
22
# Copyright (c) Meta Platforms, Inc. and affiliates.
33
# All rights reserved.
4+
# Copyright 2026 Arm Limited and/or its affiliates.
45
#
56
# This source code is licensed under the BSD-style license found in the
67
# LICENSE file in the root directory of this source tree.
78

89
import platform
910
from typing import List
1011

12+
import test_base
13+
1114
import torch
1215
from executorch.backends.xnnpack.partition.xnnpack_partitioner import XnnpackPartitioner
1316
from executorch.examples.models import Backend, Model, MODEL_NAME_TO_MODEL
@@ -74,6 +77,8 @@ def run_tests(model_tests: List[ModelTest]) -> None:
7477
else:
7578
print("⚠ VulkanBackend not registered (expected for the default wheel)")
7679

80+
test_base.test_cmsis_nn_install()
81+
7782
run_tests(
7883
model_tests=[
7984
ModelTest(

.claude/skills/qualcomm/new_op_development.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class MyOpVisitor(NodeVisitor):
6666
- Static params: `weight = get_parameter(self.get_node(node.args[1]), self.edge_program)`
6767
- Scalar params → `AddScalarParam`; Array params → `AddTensorParam`
6868
- Data types: axis/dims=`UINT_32`, epsilon=`FLOAT_32`, booleans=`BOOL_8`
69-
- Int64 index tensors: use `.to(torch.int32)` in builder + add op to `I64_IN_OPS` in `_passes/i64_to_i32.py` for CPU fallback safety (see `op_gather.py` pattern)
69+
- Int64 index tensors: If the op **requires** int64 for PyTorch tracing validation (like `gather`, `scatter`), add to `I64_IN_OPS` in `i64_to_i32.py` + `.to(torch.int32)` in builder. If the op **accepts** int32 (like `index_select`), produce int32 directly via `dtype=torch.int32` — no `I64_IN_OPS` entry needed.
7070

7171
## Step 5: Register Builder (`builders/__init__.py`)
7272

@@ -237,7 +237,7 @@ class DecomposeMyOp(ExportPass):
237237
- **Multi-output ops**: Use `wrapper_idx=i` + `getitem` skip op
238238
- **Negative dims**: QNN needs positive → `dim = dim % len(shape)`
239239
- **QCOM_AXIS_ORDER**: `LayoutTransform` permutes NCHW→NHWC; remap axis with `.index(dim)`. `get_tensor()` auto-permutes data.
240-
- **Int64 indices**: Add to `I64_IN_OPS` in `i64_to_i32.py` + `.to(torch.int32)` in builder (see `op_gather.py`)
240+
- **Int64 indices**: Only add to `I64_IN_OPS` if the op **requires** int64 at tracing time (e.g., `gather`, `scatter`). If the op accepts int32 (e.g., `index_select`), produce int32 directly in the decomposition pass. Check PyTorch docs for actual dtype requirements.
241241
- **Recompose passes**: Detect primitive sequences and replace with single native op. Ref: `recompose_pixel_unshuffle.py`
242242
- **`partition/common_defs.py`**: Remove op from `to_be_implemented_operator` when adding support
243243
- **HTP doc bugs**: If runtime fails but docs say supported → test on-device always.

.github/workflows/_xtensa_test.yml

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Reusable: build + run the Cadence Xtensa op-level gtest tests for one core on
2+
# the Instruction Set Simulator (xt-run). Mirrors _xtensa_build.yml's native
3+
# OIDC + docker-run skeleton (running xt-run needs the same licensed toolchain),
4+
# then builds the gtest op-test ELF and runs it on the simulator. The runner
5+
# cross-compile and these op tests are separate build configs (the tests need
6+
# exceptions/RTTI that the runner build disables), so this is a self-contained
7+
# job rather than consuming the runner artifact.
8+
name: xtensa-test
9+
10+
on:
11+
workflow_call:
12+
inputs:
13+
backend:
14+
description: "Cadence backend to test (hifi4 | vision | fusion_g3)"
15+
required: true
16+
type: string
17+
ref:
18+
description: "Git ref to check out"
19+
required: false
20+
type: string
21+
default: ""
22+
23+
jobs:
24+
test:
25+
name: ${{ inputs.backend }}
26+
runs-on: linux.2xlarge
27+
environment: cadence
28+
permissions:
29+
id-token: write
30+
contents: read
31+
steps:
32+
- name: Checkout executorch
33+
uses: actions/checkout@v4
34+
with:
35+
submodules: recursive
36+
ref: ${{ inputs.ref }}
37+
38+
- name: Calculate docker image
39+
id: calculate-docker-image
40+
uses: pytorch/test-infra/.github/actions/calculate-docker-image@main
41+
with:
42+
docker-image-name: ci-image:executorch-ubuntu-22.04-clang12
43+
44+
- name: Pull docker image
45+
run: docker pull "${{ steps.calculate-docker-image.outputs.docker-image }}"
46+
47+
- name: Assume Cadence artifacts role (host OIDC)
48+
uses: aws-actions/configure-aws-credentials@v4
49+
with:
50+
role-to-assume: ${{ vars.CADENCE_CI_AWS_ROLE }}
51+
aws-region: ${{ vars.CADENCE_CI_AWS_REGION }}
52+
53+
- name: Build and run op tests on xt-run
54+
env:
55+
DOCKER_IMAGE: ${{ steps.calculate-docker-image.outputs.docker-image }}
56+
BACKEND: ${{ inputs.backend }}
57+
XTENSA_S3_BUCKET: ${{ vars.CADENCE_CI_S3_BUCKET }}
58+
shell: bash
59+
run: |
60+
set -eux
61+
# OIDC/role assumption already happened on the host above; pass the
62+
# resulting AWS creds and the store/backend into the CI image, where
63+
# the toolchain download + op-test build + xt-run happen.
64+
docker run --rm \
65+
-e BACKEND -e XTENSA_S3_BUCKET \
66+
-e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \
67+
-e AWS_DEFAULT_REGION -e AWS_REGION \
68+
-v "${GITHUB_WORKSPACE}:/work/executorch" -w /work/executorch \
69+
"${DOCKER_IMAGE}" \
70+
bash -c '
71+
set -exo pipefail
72+
eval "$(/opt/conda/bin/conda shell.bash hook)"
73+
conda activate "$(conda env list --json | jq -r ".envs | .[-1]")"
74+
./install_requirements.sh > /dev/null
75+
pip install --quiet awscli
76+
# hifi4/fusion_g3 optimized kernels need the foss-xtensa nnlib
77+
# sources, which are not vendored in executorch; the cadence
78+
# installer clones them. vision has no nnlib dependency.
79+
if [ "${BACKEND}" != "vision" ]; then
80+
backends/cadence/install_requirements.sh
81+
fi
82+
source .ci/scripts/setup-xtensa-tools.sh "${BACKEND}"
83+
.ci/scripts/test-cadence-xtensa.sh
84+
'

.github/workflows/build-cadence-runner.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,25 @@ jobs:
8787
backend: hifi4
8888
ref: ${{ (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && github.event.pull_request.head.sha || github.sha }}
8989

90+
# Op-level gtest tests on the Xtensa ISS, mirroring cpu-build -> cpu-test. The
91+
# op tests are a self-contained cross-compile (the gtests need exceptions and
92+
# RTTI that the runner build disables), so this does not consume hifi-build's
93+
# artifact; needs: hifi-build only to fail fast when the backend cannot build.
94+
hifi-op-test:
95+
needs: hifi-build
96+
if: >-
97+
github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' ||
98+
(github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) ||
99+
(github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository &&
100+
contains(github.event.pull_request.labels.*.name, 'CLA Signed') && contains(github.event.pull_request.labels.*.name, 'meta-exported'))
101+
permissions:
102+
id-token: write
103+
contents: read
104+
uses: ./.github/workflows/_xtensa_test.yml
105+
with:
106+
backend: hifi4
107+
ref: ${{ (github.event_name == 'pull_request' || github.event_name == 'pull_request_target') && github.event.pull_request.head.sha || github.sha }}
108+
90109
vision-build:
91110
if: >-
92111
github.event_name == 'push' || github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' ||

.github/workflows/cuda.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,40 @@ jobs:
213213
pip install gguf
214214
python -m pytest examples/models/gemma4_31b/quant/tests/ examples/models/gemma4_31b/tests/ --ignore=examples/models/gemma4_31b/tests/test_mlx_pipeline.py -v -o "addopts="
215215
216+
unittest-cuda-runtime:
217+
name: unittest-cuda-runtime
218+
needs: [changed-files, run-decision]
219+
if: |
220+
contains(needs.changed-files.outputs.changed-files, 'backends/cuda') ||
221+
contains(needs.changed-files.outputs.changed-files, 'backends/aoti') ||
222+
contains(needs.changed-files.outputs.changed-files, '.github/workflows/cuda.yml') ||
223+
contains(needs.changed-files.outputs.changed-files, '.ci/scripts/test-cuda-build.sh') ||
224+
contains(needs.changed-files.outputs.changed-files, '.ci/scripts/export_model_artifact.sh') ||
225+
contains(needs.changed-files.outputs.changed-files, '.ci/scripts/test_model_e2e.sh') ||
226+
needs.run-decision.outputs.is-full-run == 'true'
227+
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
228+
permissions:
229+
id-token: write
230+
contents: read
231+
with:
232+
timeout: 90
233+
runner: linux.g5.4xlarge.nvidia.gpu
234+
gpu-arch-type: cuda
235+
gpu-arch-version: "13.0"
236+
use-custom-docker-registry: false
237+
submodules: recursive
238+
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
239+
script: |
240+
set -eux
241+
bash ./install_executorch.sh
242+
conda install -y -c conda-forge 'libstdcxx-ng>=12'
243+
export LD_LIBRARY_PATH=/opt/conda/lib:$LD_LIBRARY_PATH
244+
245+
cmake --preset llm-release-cuda -DEXECUTORCH_BUILD_TESTS=ON
246+
cmake --build cmake-out --target test_cuda_allocator test_cuda_mutable_state -j$(nproc)
247+
ctest --test-dir cmake-out -R test_cuda_allocator --output-on-failure -V
248+
ctest --test-dir cmake-out -R test_cuda_mutable_state --output-on-failure -V
249+
216250
export-model-cuda-artifact:
217251
name: export-model-cuda-artifact
218252
# Skip this job if the pull request is from a fork (HuggingFace secrets are not available).

0 commit comments

Comments
 (0)