Skip to content

Commit bf2f52b

Browse files
psiddhGithub Executorchdigantdesai
authored
Summary: Add MCU model script to validate and run the models (#13439)
Test Plan: See pre-requisite section in the script a. examples/arm/run_mcu_models_fvp.sh --target=ethos-u85-128 // To run all models b. examples/arm/run_mcu_models_fvp.sh --target=ethos-u85-128 --models=edsr // To run specific model ════════════════════════════════════════════════════════════════ 🏁 MCU MODEL VALIDATION SUMMARY - TARGET: ethos-u85-128 ════════════════════════════════════════════════════════════════ mv2 : ✅ Passed mv3 : ✅ Passed lstm : ✅ Passed resnet18 : ✅ Passed --------- Co-authored-by: Github Executorch <[email protected]> Co-authored-by: Digant Desai <[email protected]>
1 parent d757709 commit bf2f52b

File tree

1 file changed

+292
-0
lines changed

1 file changed

+292
-0
lines changed

examples/arm/run_mcu_models_fvp.sh

Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
#!/usr/bin/env bash
2+
# Copyright (c) Meta Platforms, Inc. and affiliates.
3+
# All rights reserved.
4+
#
5+
# Copyright 2023-2025 Arm Limited and/or its affiliates.
6+
#
7+
# This source code is licensed under the BSD-style license found in the
8+
# LICENSE file in the root directory of this source tree.
9+
10+
# Prerequisite steps: (run the following commands before running this script)
11+
# 1. Setup your environment for Arm FVP
12+
# a. Setup Conda environment / venv
13+
# b. ./install_executorch.sh --clean ; ./install_executorch.sh --editable;
14+
# c. examples/arm/setup.sh --i-agree-to-the-contained-eula;
15+
# d. source examples/arm/ethos-u-scratch/setup_path.sh
16+
# 2. bash examples/selective_build/test_selective_build.sh cmake
17+
18+
set -u
19+
20+
# Valid targets for MCU model validation
21+
VALID_TARGETS=(
22+
"ethos-u55-32"
23+
"ethos-u55-64"
24+
"ethos-u55-128"
25+
"ethos-u55-256"
26+
"ethos-u85-128"
27+
"ethos-u85-256"
28+
"ethos-u85-512"
29+
"ethos-u85-1024"
30+
"ethos-u85-2048"
31+
)
32+
33+
# Default models for MCU validation with portable kernels
34+
DEFAULT_MODELS=(mv2 mv3 lstm resnet18)
35+
# Available models (on FVP)
36+
AVAILABLE_MODELS=(mv2 mv3 lstm resnet18)
37+
# Add the following models if you want to enable them later (atm they are not working on FVP)
38+
# edsr w2l ic3 ic4 resnet50
39+
40+
# Variables
41+
TARGET=""
42+
MODELS=()
43+
PASSED_MODELS=()
44+
FAILED_MODELS=()
45+
46+
# Function to validate target
47+
validate_target() {
48+
local target=$1
49+
for valid_target in "${VALID_TARGETS[@]}"; do
50+
if [[ "$target" == "$valid_target" ]]; then
51+
return 0
52+
fi
53+
done
54+
return 1
55+
}
56+
57+
# Function to validate models
58+
validate_models() {
59+
local invalid_models=()
60+
for model in "${MODELS[@]}"; do
61+
if [[ ! " ${AVAILABLE_MODELS[*]} " =~ " $model " ]]; then
62+
invalid_models+=("$model")
63+
fi
64+
done
65+
66+
if [[ ${#invalid_models[@]} -gt 0 ]]; then
67+
echo "❌ Error: Invalid model(s): ${invalid_models[*]}"
68+
echo "Available models: ${AVAILABLE_MODELS[*]}"
69+
return 1
70+
fi
71+
return 0
72+
}
73+
74+
# Function to show usage
75+
show_usage() {
76+
echo "Usage: $0 --target=<target> [--models=<model1,model2,...>]"
77+
echo ""
78+
echo "MCU Model Validation without delegation"
79+
echo ""
80+
echo "Required arguments:"
81+
echo " --target=<target> Target platform for validation"
82+
echo ""
83+
echo "Optional arguments:"
84+
echo " --models=<models> Comma-separated list of models to test"
85+
echo " (overrides default model list)"
86+
echo ""
87+
echo "Valid targets:"
88+
printf ' %s\n' "${VALID_TARGETS[@]}"
89+
echo ""
90+
echo "Available models:"
91+
printf ' %s\n' "${AVAILABLE_MODELS[@]}"
92+
echo ""
93+
echo "Examples:"
94+
echo " $0 --target=ethos-u85-128"
95+
echo " $0 --target=ethos-u55-128 --models=mv2,mv3,resnet18"
96+
echo ""
97+
echo "Default behavior:"
98+
echo " - Uses all available models: ${DEFAULT_MODELS[*]}"
99+
echo " - Runs with portable kernels (no delegation)"
100+
}
101+
102+
# Function to display summary
103+
show_summary() {
104+
local total_models=${#MODELS[@]}
105+
106+
echo ""
107+
echo "════════════════════════════════════════════════════════════════"
108+
echo "🏁 MCU MODEL VALIDATION SUMMARY - TARGET: $TARGET"
109+
echo "════════════════════════════════════════════════════════════════"
110+
echo ""
111+
112+
# Show individual results
113+
for model in "${MODELS[@]}"; do
114+
if [[ " ${PASSED_MODELS[*]} " =~ " $model " ]]; then
115+
printf "%-12s : ✅ Passed\n" "$model"
116+
elif [[ " ${FAILED_MODELS[*]} " =~ " $model " ]]; then
117+
printf "%-12s : ❌ Failed\n" "$model"
118+
else
119+
printf "%-12s : ⏭️ Skipped\n" "$model"
120+
fi
121+
done
122+
123+
echo ""
124+
echo "────────────────────────────────────────────────────────────────"
125+
126+
# Show statistics
127+
local passed_count=${#PASSED_MODELS[@]}
128+
local failed_count=${#FAILED_MODELS[@]}
129+
local success_rate=$((passed_count * 100 / total_models))
130+
131+
echo "📊 STATISTICS:"
132+
echo " Total Models : $total_models"
133+
echo " ✅ Passed : $passed_count"
134+
echo " ❌ Failed : $failed_count"
135+
echo " 📈 Success Rate : $success_rate%"
136+
echo ""
137+
138+
# Show model selection info
139+
if [[ ${#MODELS[@]} -eq ${#DEFAULT_MODELS[@]} ]] && [[ "${MODELS[*]}" == "${DEFAULT_MODELS[*]}" ]]; then
140+
echo "📋 Model Selection: Default (all available models)"
141+
else
142+
echo "📋 Model Selection: Custom (${MODELS[*]})"
143+
fi
144+
echo ""
145+
146+
# Overall result
147+
if [[ $failed_count -eq 0 ]]; then
148+
echo "🎉 OVERALL RESULT: ALL TESTS PASSED!"
149+
echo "🔧 Mode: Portable Kernels (No Delegation)"
150+
else
151+
echo "⚠️ OVERALL RESULT: $failed_count/$total_models TESTS FAILED"
152+
echo "🔧 Mode: Portable Kernels (No Delegation)"
153+
echo ""
154+
echo "🔍 Failed models: ${FAILED_MODELS[*]}"
155+
fi
156+
157+
echo "════════════════════════════════════════════════════════════════"
158+
echo ""
159+
}
160+
161+
# Parse command line arguments
162+
while [[ $# -gt 0 ]]; do
163+
case $1 in
164+
--target=*)
165+
TARGET="${1#*=}"
166+
shift
167+
;;
168+
--models=*)
169+
IFS=',' read -ra MODELS <<< "${1#*=}"
170+
shift
171+
;;
172+
-h|--help)
173+
show_usage
174+
exit 0
175+
;;
176+
*)
177+
echo "❌ Error: Unknown argument '$1'"
178+
echo ""
179+
show_usage
180+
exit 1
181+
;;
182+
esac
183+
done
184+
185+
# Check if target is provided
186+
if [[ -z "$TARGET" ]]; then
187+
echo "❌ Error: --target argument is required"
188+
echo ""
189+
show_usage
190+
exit 1
191+
fi
192+
193+
# Validate target
194+
if ! validate_target "$TARGET"; then
195+
echo "❌ Error: Invalid target '$TARGET'"
196+
echo ""
197+
show_usage
198+
exit 1
199+
fi
200+
201+
# Use default models if none specified
202+
if [[ ${#MODELS[@]} -eq 0 ]]; then
203+
MODELS=("${DEFAULT_MODELS[@]}")
204+
fi
205+
206+
# Validate models
207+
if ! validate_models; then
208+
exit 1
209+
fi
210+
211+
# Remove duplicates from models array
212+
IFS=" " read -r -a MODELS <<< "$(printf '%s\n' "${MODELS[@]}" | sort -u | tr '\n' ' ')"
213+
214+
echo "🎯 MCU Model Validation - Target: $TARGET"
215+
echo "📋 Processing models: ${MODELS[*]}"
216+
echo "🔧 Mode: Portable Kernels (No Delegation)"
217+
echo ""
218+
219+
echo "🔨 Building ExecuteTorch libraries (one-time setup)..."
220+
if ! backends/arm/scripts/build_executorch.sh; then
221+
echo "❌ Failed to build ExecuteTorch libraries"
222+
exit 1
223+
fi
224+
echo "✅ ExecuteTorch libraries built successfully"
225+
echo ""
226+
227+
# Process each model
228+
for model in "${MODELS[@]}"; do
229+
echo "=== 🚀 Processing $model for $TARGET ==="
230+
231+
# Track if this model succeeds
232+
MODEL_SUCCESS=true
233+
234+
# Step 1: Create directory
235+
echo "📁 Creating directory arm_test/$model"
236+
mkdir -p "arm_test/$model"
237+
238+
# Step 2: AOT compilation (quantized, no delegation = portable kernels)
239+
echo "⚙️ AOT compilation for $model"
240+
if ! python3 -m examples.arm.aot_arm_compiler \
241+
-m "$model" \
242+
--target="$TARGET" \
243+
--quantize \
244+
--output="arm_test/$model"; then
245+
echo "❌ AOT compilation failed for $model"
246+
MODEL_SUCCESS=false
247+
fi
248+
249+
# Step 3: Build executor runner (only if AOT succeeded)
250+
if [[ "$MODEL_SUCCESS" == true ]]; then
251+
echo "🔨 Building executor runner for $model"
252+
if ! backends/arm/scripts/build_executor_runner.sh \
253+
--pte="arm_test/$model/${model}_arm_${TARGET}.pte" \
254+
--target="$TARGET" \
255+
--output="arm_test/$model"; then
256+
echo "❌ Executor runner build failed for $model"
257+
MODEL_SUCCESS=false
258+
fi
259+
fi
260+
261+
# Step 4: Run on FVP (only if build succeeded)
262+
if [[ "$MODEL_SUCCESS" == true ]]; then
263+
echo "🏃 Running $model on FVP with portable kernels"
264+
if ! backends/arm/scripts/run_fvp.sh \
265+
--elf="arm_test/$model/arm_executor_runner" \
266+
--target="$TARGET"; then
267+
echo "❌ FVP execution failed for $model"
268+
MODEL_SUCCESS=false
269+
fi
270+
fi
271+
272+
# Record result
273+
if [[ "$MODEL_SUCCESS" == true ]]; then
274+
echo "$model completed successfully"
275+
PASSED_MODELS+=("$model")
276+
else
277+
echo "$model failed"
278+
FAILED_MODELS+=("$model")
279+
fi
280+
281+
echo ""
282+
done
283+
284+
# Show comprehensive summary
285+
show_summary
286+
287+
# Exit with appropriate code for CI
288+
if [[ ${#FAILED_MODELS[@]} -eq 0 ]]; then
289+
exit 0 # Success
290+
else
291+
exit 1 # Failure
292+
fi

0 commit comments

Comments
 (0)