Skip to content

Commit 1feb56c

Browse files
authored
Zephyr: Move CI testing to a script (pytorch#19542)
Moves CI testing from yaml to .ci/scripts/test_zephyr.sh and create a table of readme and target combinations to run instead of having mv2 tests hard coded. This will make it easier to add more sample and tests in the future as the test flow is more generic. Signed-off-by: Zingo Andersen <Zingo.Andersen@arm.com>
1 parent 6745047 commit 1feb56c

5 files changed

Lines changed: 274 additions & 164 deletions

File tree

.ci/scripts/test_zephyr.sh

Lines changed: 178 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,178 @@
1+
#!/usr/bin/env bash
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
# All rights reserved.
4+
# Copyright 2026 Arm Limited and/or its affiliates.
5+
#
6+
# This source code is licensed under the BSD-style license found in the
7+
# LICENSE file in the root directory of this source tree.
8+
9+
set -euo pipefail
10+
11+
SCRIPT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")")"
12+
EXECUTORCH_PROJ_ROOT="$(realpath "${SCRIPT_DIR}/../..")"
13+
ZEPHYR_README_PATH="zephyr/README.md"
14+
15+
ZEPHYR_SAMPLES_README_PATH="zephyr/samples/hello-executorch/README.md"
16+
TARGETS_ARG="${TARGET_LIST:-}"
17+
18+
usage() {
19+
cat <<EOF
20+
Usage: $0 [options]
21+
22+
Options:
23+
--zephyr-samples-readme-path <path> README containing test_<TARGET>* command blocks
24+
--targets <list> Comma-separated target list, e.g. ethos-u55,cortex-m55,ethos-u85
25+
-h, --help Show this help
26+
EOF
27+
}
28+
29+
while [[ $# -gt 0 ]]; do
30+
case "$1" in
31+
--targets)
32+
TARGETS_ARG="$2"
33+
shift 2
34+
;;
35+
--zephyr-samples-readme-path)
36+
ZEPHYR_SAMPLES_README_PATH="$2"
37+
shift 2
38+
;;
39+
-h|--help)
40+
usage
41+
exit 0
42+
;;
43+
*)
44+
echo "ERROR: Unknown argument: $1" >&2
45+
usage >&2
46+
exit 1
47+
;;
48+
esac
49+
done
50+
51+
if [[ -z "${TARGETS_ARG}" ]]; then
52+
echo "ERROR: --targets or TARGET_LIST must be set" >&2
53+
usage >&2
54+
exit 1
55+
fi
56+
57+
IFS=',' read -r -a TARGETS <<< "${TARGETS_ARG}"
58+
59+
export EXECUTORCH_PROJ_ROOT
60+
61+
cd "${EXECUTORCH_PROJ_ROOT}"
62+
63+
# Source utility scripts.
64+
. .ci/scripts/utils.sh
65+
. .ci/scripts/zephyr-utils.sh
66+
67+
run_target_test_blocks_from_readme() {
68+
local readme_path="$1"
69+
local target="$2"
70+
local resolved_readme_path marker markers
71+
72+
resolved_readme_path="$(_utils_path_from_root "${readme_path}")"
73+
markers="$(awk -v target="${target}" '
74+
{
75+
line = $0
76+
while (match(line, /<!--[[:space:]]*RUN[[:space:]]+[^>]*-->/)) {
77+
marker = substr(line, RSTART, RLENGTH)
78+
if (index(marker, "<!-- RUN test_" target) == 1) {
79+
print marker
80+
}
81+
line = substr(line, RSTART + RLENGTH)
82+
}
83+
}
84+
' "${resolved_readme_path}")"
85+
86+
if [[ -z "${markers}" ]]; then
87+
echo "ERROR: No test blocks matching <!-- RUN test_${target}* --> in ${readme_path}" >&2
88+
return 1
89+
fi
90+
91+
while IFS= read -r marker; do
92+
echo "---- ${target} ${marker} ----"
93+
run_command_block_from_readme "${readme_path}" "${marker}"
94+
done <<< "${markers}"
95+
}
96+
97+
# Check that zephyr/README.md and zephyr/executorch.yaml are in sync.
98+
verify_zephyr_readme
99+
100+
# Based on instructions in zephyr/README.md and the selected sample README.
101+
run_command_block_from_readme "${ZEPHYR_README_PATH}" "<!-- RUN install_reqs -->"
102+
103+
# Make sure to backup the zephyr_scratch folder if it exists to allow for local
104+
# testing that does not lose code/data.
105+
if [[ -d "zephyr_scratch" ]]; then
106+
mv "zephyr_scratch" "zephyr_scratch.backup.$(date +%Y%m%d%H%M%S)"
107+
fi
108+
mkdir -p zephyr_scratch/
109+
110+
cd zephyr_scratch
111+
export ZEPHYR_PROJ_ROOT="$(realpath "$(pwd)")"
112+
113+
echo "---- Zephyr SDK ----"
114+
# Use ZephyrSDK if on the disk (e.g. setup in the docker)
115+
# Check for a zephyr-sdk-0.17.4 directory and make a symlink if found in parent directories
116+
if sdk_dir=$(find ../../.. -maxdepth 4 -type d -name 'zephyr-sdk-0.17.4' -print -quit) && [ -n "${sdk_dir}" ]; then
117+
echo "---- Found pre downloaded Zephyr SDK in ${sdk_dir} ----"
118+
ln -s "${sdk_dir}" .
119+
fi
120+
121+
# Download and setup Zephyr SDK 0.17.4 if not already present
122+
if [ ! -d "zephyr-sdk-0.17.4" ]; then
123+
echo "---- Downloading Zephyr SDK ----"
124+
wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.17.4/zephyr-sdk-0.17.4_linux-x86_64.tar.xz
125+
tar -xf zephyr-sdk-0.17.4_linux-x86_64.tar.xz
126+
rm -f zephyr-sdk-0.17.4_linux-x86_64.tar.xz*
127+
fi
128+
129+
./zephyr-sdk-0.17.4/setup.sh -c -t arm-zephyr-eabi
130+
export ZEPHYR_SDK_INSTALL_DIR=$(realpath ./zephyr-sdk-0.17.4)
131+
132+
cd ${ZEPHYR_PROJ_ROOT}
133+
134+
run_command_block_from_readme "${ZEPHYR_README_PATH}" "<!-- RUN west_init -->"
135+
136+
cp "${EXECUTORCH_PROJ_ROOT}/zephyr/executorch.yaml" zephyr/submanifests/
137+
138+
run_command_block_from_readme "${ZEPHYR_README_PATH}" "<!-- RUN west_config -->"
139+
140+
# Switch to executorch in this PR e.g. replace modules/lib/executorch with the
141+
# root folder of this repo instead of doing a re-checkout and figuring out the
142+
# correct commit hash.
143+
rm -Rf modules/lib/executorch
144+
ln -s "${EXECUTORCH_PROJ_ROOT}" modules/lib/executorch
145+
146+
# Setup git local user for Executorch git to allow
147+
# modules/lib/executorch/examples/arm/setup.sh to run inside CI later.
148+
if ! git config --get user.name >/dev/null 2>&1; then
149+
git config --global user.name "Github Executorch"
150+
fi
151+
if ! git config --get user.email >/dev/null 2>&1; then
152+
git config --global user.email "github_executorch@arm.com"
153+
fi
154+
155+
run_command_block_from_readme "${ZEPHYR_README_PATH}" "<!-- RUN install_executorch -->"
156+
run_command_block_from_readme "${ZEPHYR_README_PATH}" "<!-- RUN install_arm_tools -->"
157+
158+
for TARGET in "${TARGETS[@]}"; do
159+
TARGET="$(echo "${TARGET}" | xargs)"
160+
161+
echo "---- ${TARGET} ----"
162+
rm -Rf build
163+
164+
if [[ ${TARGET} == "ethos-u55" || ${TARGET} == "cortex-m55" ]]; then
165+
BOARD="corstone300"
166+
elif [[ ${TARGET} == "ethos-u85" ]]; then
167+
BOARD="corstone320"
168+
else
169+
echo "Fail unsupported target selection ${TARGET}"
170+
exit 1
171+
fi
172+
173+
echo "---- ${TARGET} Board ${BOARD} FVP setup ----"
174+
run_command_block_from_readme "${ZEPHYR_SAMPLES_README_PATH}" "<!-- RUN setup_${BOARD} -->"
175+
176+
# Run all blocks that match <!-- RUN test_${target}* -->
177+
run_target_test_blocks_from_readme "${ZEPHYR_SAMPLES_README_PATH}" "${TARGET}"
178+
done

.github/workflows/trunk.yml

Lines changed: 9 additions & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,12 @@ jobs:
6262
uses: pytorch/test-infra/.github/workflows/linux_job.yml@main
6363
strategy:
6464
matrix:
65-
target: [ethos-u55, cortex-m55, ethos-u85]
65+
include:
66+
- { readme: zephyr/samples/hello-executorch/README.md, target: ethos-u55 }
67+
- { readme: zephyr/samples/hello-executorch/README.md, target: cortex-m55 }
68+
- { readme: zephyr/samples/hello-executorch/README.md, target: ethos-u85 }
69+
- { readme: zephyr/samples/mv2-ethosu/README.md, target: ethos-u55 }
70+
- { readme: zephyr/samples/mv2-ethosu/README.md, target: ethos-u85 }
6671
fail-fast: false
6772
with:
6873
runner: linux.2xlarge
@@ -79,143 +84,9 @@ jobs:
7984
# Test zephyr backend
8085
set -e
8186
82-
# Support comma-separated TARGET_LIST or ${{ matrix.target }} list, e.g., TARGET_LIST="ethos-u55,cortex-m55,ethos-u85"
83-
if [ -z "${TARGET_LIST:-}" ]; then
84-
IFS=',' read -r -a TARGETS <<< "${{ matrix.target }}"
85-
else
86-
IFS=',' read -r -a TARGETS <<< "${TARGET_LIST}"
87-
fi
88-
89-
export EXECUTORCH_PROJ_ROOT=$(realpath $(pwd))
90-
ZEPHYR_README_PATH="zephyr/README.md"
91-
ZEPHYR_SAMPLES_README_PATH="zephyr/samples/hello-executorch/README.md"
92-
93-
# Source utility scripts
94-
. .ci/scripts/utils.sh
95-
. .ci/scripts/zephyr-utils.sh
96-
97-
# check that zephyr/README.md and zephyr/executorch.yaml are in sync
98-
verify_zephyr_readme
99-
100-
# Based on instructions in zephyr/README.md and zephyr/samples/hello-executorch/README.md
101-
102-
run_command_block_from_readme "${ZEPHYR_README_PATH}" "<!-- RUN install_reqs -->"
103-
104-
# Make sure to backup the zephyr_scratch folder if it exists to allow for local
105-
# testing that does not lose code/data
106-
if [ -d "zephyr_scratch" ]; then
107-
mv "zephyr_scratch" "zephyr_scratch.backup.$(date +%Y%m%d%H%M%S)"
108-
fi
109-
mkdir -p zephyr_scratch/
110-
111-
cd zephyr_scratch
112-
export ZEPHYR_PROJ_ROOT=$(realpath $(pwd))
113-
114-
echo "---- Zephyr SDK ----"
115-
# Use ZephyrSDK if on the disk (e.g. setup in the docker)
116-
# Check for a zephyr-sdk-0.17.4 directory and make a symlink if found in parent directories
117-
if sdk_dir=$(find ../../.. -maxdepth 4 -type d -name 'zephyr-sdk-0.17.4' -print -quit) && [ -n "${sdk_dir}" ]; then
118-
echo "---- Found pre downloaded Zephyr SDK in ${sdk_dir} ----"
119-
ln -s "${sdk_dir}" .
120-
fi
121-
122-
# Download and setup Zephyr SDK 0.17.4 if not already present
123-
if [ ! -d "zephyr-sdk-0.17.4" ]; then
124-
echo "---- Downloading Zephyr SDK ----"
125-
wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.17.4/zephyr-sdk-0.17.4_linux-x86_64.tar.xz
126-
tar -xf zephyr-sdk-0.17.4_linux-x86_64.tar.xz
127-
rm -f zephyr-sdk-0.17.4_linux-x86_64.tar.xz*
128-
fi
129-
130-
./zephyr-sdk-0.17.4/setup.sh -c -t arm-zephyr-eabi
131-
export ZEPHYR_SDK_INSTALL_DIR=$(realpath ./zephyr-sdk-0.17.4)
132-
133-
cd ${ZEPHYR_PROJ_ROOT}
134-
135-
run_command_block_from_readme "${ZEPHYR_README_PATH}" "<!-- RUN west_init -->"
136-
137-
cp ${EXECUTORCH_PROJ_ROOT}/zephyr/executorch.yaml zephyr/submanifests/
138-
139-
run_command_block_from_readme "${ZEPHYR_README_PATH}" "<!-- RUN west_config -->"
140-
141-
# Switch to executorch in this PR e.g. replace modules/lib/executorch with the root folder of this repo
142-
# instead of doing a re-checkout and figure out the correct commit hash etc
143-
rm -Rf modules/lib/executorch
144-
ln -s ${EXECUTORCH_PROJ_ROOT} modules/lib/executorch
145-
146-
# Setup git local user for Executorch git to allows modules/lib/executorch/examples/arm/setup.sh be run inside CI later
147-
# Configure git user only if not already set
148-
if ! git config --get user.name >/dev/null 2>&1; then
149-
git config --global user.name "Github Executorch"
150-
fi
151-
if ! git config --get user.email >/dev/null 2>&1; then
152-
git config --global user.email "github_executorch@arm.com"
153-
fi
154-
155-
run_command_block_from_readme "${ZEPHYR_README_PATH}" "<!-- RUN install_executorch -->"
156-
157-
run_command_block_from_readme "${ZEPHYR_README_PATH}" "<!-- RUN install_arm_tools -->"
158-
159-
for TARGET in "${TARGETS[@]}"; do
160-
TARGET="$(echo "$TARGET" | xargs)" # trim whitespace
161-
162-
echo "---- ${TARGET} ----"
163-
rm -Rf build
164-
165-
if [[ ${TARGET} == "ethos-u55" || ${TARGET} == "cortex-m55" ]]; then
166-
BOARD="corstone300"
167-
elif [[ ${TARGET} == "ethos-u85" ]]; then
168-
BOARD="corstone320"
169-
else
170-
echo "Fail unsupport target selection ${TARGET}"
171-
exit 1
172-
fi
173-
174-
echo "---- ${TARGET} Board ${BOARD} FVP setup ----"
175-
run_command_block_from_readme "${ZEPHYR_SAMPLES_README_PATH}" "<!-- RUN setup_${BOARD}_fvp -->"
176-
177-
echo "---- ${TARGET} Create PTE ----"
178-
run_command_block_from_readme "${ZEPHYR_SAMPLES_README_PATH}" "<!-- RUN test_${TARGET}_generate_pte -->"
179-
180-
echo "---- ${TARGET} Build and run ----"
181-
run_command_block_from_readme "${ZEPHYR_SAMPLES_README_PATH}" "<!-- RUN test_${TARGET}_build_and_run -->"
182-
done
183-
184-
# MV2 Ethos-U sample (NPU targets only — skips cortex-m55)
185-
MV2_README_PATH="zephyr/samples/mv2-ethosu/README.md"
186-
187-
for TARGET in "${TARGETS[@]}"; do
188-
TARGET="$(echo "$TARGET" | xargs)"
189-
190-
if [[ ${TARGET} == "cortex-m55" ]]; then
191-
echo "---- Skipping MV2 for ${TARGET} (NPU-only sample) ----"
192-
continue
193-
fi
194-
195-
if [[ ${TARGET} == "ethos-u55" ]]; then
196-
BOARD="corstone300"
197-
elif [[ ${TARGET} == "ethos-u85" ]]; then
198-
BOARD="corstone320"
199-
else
200-
echo "Fail unsupported target selection ${TARGET}"
201-
exit 1
202-
fi
203-
204-
echo "---- MV2 ${TARGET} ----"
205-
rm -Rf build
206-
207-
echo "---- MV2 ${TARGET} Board ${BOARD} FVP setup ----"
208-
run_command_block_from_readme "${ZEPHYR_SAMPLES_README_PATH}" "<!-- RUN setup_${BOARD}_fvp -->"
209-
210-
echo "---- MV2 ${TARGET} Create PTE ----"
211-
run_command_block_from_readme "${MV2_README_PATH}" "<!-- RUN test_mv2_${TARGET}_generate_pte -->"
212-
213-
# Build only — FVP cycle-accurate simulation of MV2 is too slow
214-
# for the CI timeout. Corstone-300 also lacks enough ISRAM for
215-
# the runtime pools. The build step still catches link regressions.
216-
echo "---- MV2 ${TARGET} Build only ----"
217-
run_command_block_from_readme "${MV2_README_PATH}" "<!-- RUN test_mv2_${TARGET}_build -->"
218-
done
87+
.ci/scripts/test_zephyr.sh \
88+
--targets "${TARGET_LIST:-${{ matrix.target }}}" \
89+
--zephyr-samples-readme-path "${{ matrix.readme }}"
21990
22091
test-models-linux-aarch64:
22192
name: test-models-linux-aarch64

0 commit comments

Comments
 (0)