Skip to content

Commit dc6a956

Browse files
authored
Arm backend: Add support for DevTools BundleIO (#8680)
Add support for input and output testing using BundleIO in devtools. Can be tested with: run.sh --model_name=add --target=ethos-u85-128 --bundleio aot_arm_compiler.py changes --bundleio - Will generate a bundle .bpte file with input and reference output data --model_name - now also support .pt/.pth files e.g. a torch.save():ed model --model_input - If supplied will overried the model input data supply a torch.save():ed data --intermediates - Will now save model.pth, input_xx.pt and output_ref_xx.pt files so testing can be reproduced arm_executor_runner.cpp - can be build with ET_BUNDLE_IO to enable a .bpte and a input/output_ref testing flow test_model.py script uses bundleio test_arm_baremetal.sh script now tests models with BundleIO so output is compared to ref output Change-Id: I25b9ecc0adbf697d1d8cadc5d67ffd32f8c93db6 Signed-off-by: Zingo Andersen <[email protected]>
1 parent b5344c1 commit dc6a956

File tree

9 files changed

+562
-174
lines changed

9 files changed

+562
-174
lines changed

backends/arm/scripts/build_executorch.sh

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,17 @@ et_root_dir=$(realpath ${et_root_dir})
1616
toolchain_cmake=${script_dir}/../../../examples/arm/ethos-u-setup/arm-none-eabi-gcc.cmake
1717
toolchain_cmake=$(realpath ${toolchain_cmake})
1818

19-
20-
2119
et_build_root="${et_root_dir}/arm_test"
2220
build_type="Release"
21+
build_devtools=false
2322
build_with_etdump=false
2423

25-
2624
help() {
2725
echo "Usage: $(basename $0) [options]"
2826
echo "Options:"
2927
echo " --et_build_root=<FOLDER> Build output root folder to use, defaults to ${et_build_root}"
3028
echo " --build_type=<TYPE> Build with Release, Debug or RelWithDebInfo, default is ${build_type}"
29+
echo " --devtools Build Devtools libs"
3130
echo " --etdump Adds Devtools etdump support to track timing, etdump area will be base64 encoded in the log"
3231
exit 0
3332
}
@@ -37,32 +36,33 @@ for arg in "$@"; do
3736
-h|--help) help ;;
3837
--et_build_root=*) et_build_root="${arg#*=}";;
3938
--build_type=*) build_type="${arg#*=}";;
39+
--devtools) build_devtools=true ;;
4040
--etdump) build_with_etdump=true ;;
4141
*)
4242
;;
4343
esac
4444
done
4545

4646
et_build_dir="${et_build_root}/cmake-out"
47+
48+
# Used for flatcc host excutable if Devtools is used
4749
et_build_host_dir=${et_build_root}/cmake-out-host-tools
4850

4951
set -x
5052
cd "${et_root_dir}"
5153

52-
build_with_etdump_flags=""
5354
if [ "$build_with_etdump" = true ] ; then
5455
( set +x ;
5556
echo "--------------------------------------------------------------------------------" ;
56-
echo "Build ExecuTorch Libraries host flatcc bin ${build_type} into ${et_build_host_dir} - ${et_build_host_dir}/bin/flatcc" ;
57+
echo "Build ExecuTorch Libraries host flatcc bin ${build_type} into ${et_build_host_dir}/bin/flatcc" ;
5758
echo "--------------------------------------------------------------------------------" )
5859

59-
6060
# Build host flatcc bin
6161
# This is a way to work around that the flatcc executable get build for target (e.g. Arm) later
6262
# and get replaced. flatcc is a tool used on the host for etdump and BundleIO handling.
6363
# The way to solve this is to generate it once for the host, then copy it to ${et_build_host_dir}/bin
6464
# and later point that out with -DFLATCC_EXECUTABLE=${et_build_host_dir}/bin/flatcc later.
65-
mkdir -p ${et_build_host_dir}
65+
6666
cmake \
6767
-DCMAKE_INSTALL_PREFIX=${et_build_host_dir} \
6868
-DCMAKE_BUILD_TYPE=${build_type} \
@@ -79,25 +79,39 @@ if [ "$build_with_etdump" = true ] ; then
7979
-B"${et_build_host_dir}" \
8080
"${et_root_dir}"
8181

82-
# Copy host flatcc excutable to it's saved when we build for target (Arm) later
82+
# third-party/flatcc/bin/flatcc gets build already in the in the cmake config step above
83+
# so there is no cmake building step done
84+
85+
# Copy host flatcc excutable so it's saved when we build for target (Arm) later
86+
et_build_host_dir=$(realpath ${et_build_host_dir})
8387
mkdir -p ${et_build_host_dir}/bin
8488
cp third-party/flatcc/bin/flatcc ${et_build_host_dir}/bin
85-
86-
# Add DevTools flags use in the Target build below
87-
build_with_etdump_flags="-DEXECUTORCH_BUILD_DEVTOOLS=ON \
88-
-DEXECUTORCH_ENABLE_EVENT_TRACER=ON \
89-
-DEXECUTORCH_SEPARATE_FLATCC_HOST_PROJECT=OFF \
90-
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=OFF \
91-
-DFLATCC_ALLOW_WERROR=OFF \
92-
-DFLATCC_EXECUTABLE=${et_build_host_dir}/bin/flatcc "
93-
echo "build_with_etdump_flags=$build_with_etdump_flags"
9489
fi
9590

9691
( set +x ;
9792
echo "--------------------------------------------------------------------------------" ;
9893
echo "Build ExecuTorch target libs ${build_type} into '${et_build_dir}'" ;
9994
echo "--------------------------------------------------------------------------------" )
10095

96+
build_devtools_flags=" -DEXECUTORCH_BUILD_DEVTOOLS=OFF "
97+
if [ "$build_devtools" = true ] ; then
98+
build_devtools_flags=" -DEXECUTORCH_BUILD_DEVTOOLS=ON "
99+
fi
100+
101+
build_with_etdump_flags=" -DEXECUTORCH_ENABLE_EVENT_TRACER=OFF "
102+
if [ "$build_with_etdump" = true ] ; then
103+
# Add DevTools flags use in the Target build below
104+
build_with_etdump_flags="-DEXECUTORCH_BUILD_DEVTOOLS=ON \
105+
-DEXECUTORCH_ENABLE_EVENT_TRACER=ON \
106+
-DEXECUTORCH_SEPARATE_FLATCC_HOST_PROJECT=OFF \
107+
-DEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=OFF \
108+
-DFLATCC_ALLOW_WERROR=OFF \
109+
-DFLATCC_EXECUTABLE=${et_build_host_dir}/bin/flatcc "
110+
fi
111+
112+
echo "Building with Devtools: ${build_devtools_flags} ${build_with_etdump_flags}"
113+
114+
101115
# Build
102116
cmake \
103117
-DCMAKE_INSTALL_PREFIX=${et_build_dir} \
@@ -108,6 +122,7 @@ cmake \
108122
-DEXECUTORCH_BUILD_KERNELS_QUANTIZED=ON \
109123
-DEXECUTORCH_BUILD_EXTENSION_RUNNER_UTIL=ON \
110124
-DEXECUTORCH_ENABLE_LOGGING=ON \
125+
${build_devtools_flags} \
111126
${build_with_etdump_flags} \
112127
-DFLATC_EXECUTABLE="$(which flatc)" \
113128
-B"${et_build_dir}" \

backends/arm/scripts/build_executorch_runner.sh

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@ pte_file=""
1515
target="ethos-u55-128"
1616
build_type="Release"
1717
system_config=""
18+
bundleio=false
1819
build_with_etdump=false
1920
extra_build_flags=""
2021
output_folder_set=false
2122
output_folder="."
2223
et_build_root="${et_root_dir}/arm_test"
2324
ethosu_tools_dir=${et_root_dir}/examples/arm/ethos-u-scratch
2425

26+
build_bundleio_flags=" -DET_BUNDLE_IO=OFF "
27+
build_with_etdump_flags=" -DEXECUTORCH_ENABLE_EVENT_TRACER=OFF "
28+
2529
help() {
2630
echo "Usage: $(basename $0) [options]"
2731
echo "Options:"
@@ -30,6 +34,7 @@ help() {
3034
echo " --build_type=<TYPE> Build with Release, Debug or RelWithDebInfo, default is ${build_type}"
3135
echo " --system_config=<CONFIG> System configuration to select from the Vela configuration file (see vela.ini). Default: Ethos_U55_High_End_Embedded for EthosU55 targets, Ethos_U85_SYS_DRAM_Mid for EthosU85 targets."
3236
echo " NOTE: If given, this option must match the given target. This option also sets timing adapter values customized for specific hardware, see ./executor_runner/CMakeLists.txt."
37+
echo " --bundleio Support both pte and Bundle IO bpte using Devtools BundelIO with Input/RefOutput included"
3338
echo " --etdump Adds Devtools etdump support to track timing, etdump area will be base64 encoded in the log"
3439
echo " --extra_build_flags=<FLAGS> Extra flags to pass to cmake like -DET_ARM_BAREMETAL_METHOD_ALLOCATOR_POOL_SIZE=60000 Default: none "
3540
echo " --output=<FOLDER> Output folder Default: <MODEL>/<MODEL>_<TARGET INFO>.pte"
@@ -45,6 +50,7 @@ for arg in "$@"; do
4550
--target=*) target="${arg#*=}";;
4651
--build_type=*) build_type="${arg#*=}";;
4752
--system_config=*) system_config="${arg#*=}";;
53+
--bundleio) bundleio=true ;;
4854
--etdump) build_with_etdump=true ;;
4955
--extra_build_flags=*) extra_build_flags="${arg#*=}";;
5056
--output=*) output_folder="${arg#*=}" ; output_folder_set=true ;;
@@ -64,9 +70,8 @@ et_build_dir=${et_build_root}/cmake-out
6470
et_build_dir=$(realpath ${et_build_dir})
6571

6672
if [ "$output_folder_set" = false ] ; then
67-
pte_folder=$(cd -- "$( dirname -- "${pte_file}" )" &> /dev/null && pwd)
68-
pte_short_name=$(basename -- "${pte_file}" ".pte")
69-
output_folder="$pte_folder/$pte_short_name"
73+
# remove file ending
74+
output_folder=${pte_file%.*}
7075
fi
7176

7277
if [[ ${system_config} == "" ]]
@@ -86,28 +91,32 @@ else
8691
target_cpu=cortex-m85
8792
fi
8893
echo "--------------------------------------------------------------------------------"
89-
echo "Build Arm Baremetal executor_runner for ${target} with ${pte_file} using ${system_config} to '${output_folder}/cmake-out'"
94+
echo "Build Arm Baremetal executor_runner for ${target} with ${pte_file} using ${system_config} ${extra_build_flags} to '${output_folder}/cmake-out'"
9095
echo "--------------------------------------------------------------------------------"
9196

9297
cd ${et_root_dir}/examples/arm/executor_runner
9398

94-
build_with_etdump_flags=""
99+
if [ "$bundleio" = true ] ; then
100+
build_bundleio_flags=" -DET_BUNDLE_IO=ON "
101+
fi
102+
95103
if [ "$build_with_etdump" = true ] ; then
96-
echo "Building with etdump e.g. -DEXECUTORCH_ENABLE_EVENT_TRACER=ON"
97104
build_with_etdump_flags=" -DEXECUTORCH_ENABLE_EVENT_TRACER=ON "
98105
fi
99106

100-
mkdir -p "$output_folder"
107+
echo "Building with BundleIO/etdump/extra flags: ${build_bundleio_flags} ${build_with_etdump_flags} ${extra_build_flags}"
108+
mkdir -p "${output_folder}"
101109

102110
cmake \
103111
-DCMAKE_BUILD_TYPE=${build_type} \
104112
-DCMAKE_TOOLCHAIN_FILE=${toolchain_cmake} \
105113
-DTARGET_CPU=${target_cpu} \
106114
-DET_DIR_PATH:PATH=${et_root_dir} \
107115
-DET_BUILD_DIR_PATH:PATH=${et_build_dir} \
108-
-DET_PTE_FILE_PATH:PATH="${pte_file}" \
116+
-DET_PTE_FILE_PATH:PATH="${pte_file}" \
109117
-DETHOS_SDK_PATH:PATH=${ethos_u_root_dir} \
110118
-DETHOSU_TARGET_NPU_CONFIG=${target} \
119+
${build_bundleio_flags} \
111120
${build_with_etdump_flags} \
112121
-DPYTHON_EXECUTABLE=$(which python3) \
113122
-DSYSTEM_CONFIG=${system_config} \

backends/arm/scripts/run_fvp.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ _setup_msg="please refer to ${et_root_dir}/examples/arm/setup.sh to properly ins
1919

2020
elf_file=""
2121
target="ethos-u55-128"
22+
timeout="240"
2223

2324
help() {
2425
echo "Usage: $(basename $0) [options]"
2526
echo "Options:"
2627
echo " --elf=<ELF_FILE> elf file to run"
2728
echo " --target=<TARGET> Target to build and run for Default: ${target}"
29+
echo " --timeout=<TIME_IN_SEC> Maximum target runtime, used to detect hanging, might need to be higer on large models Default: ${timeout}"
2830
exit 0
2931
}
3032

@@ -33,6 +35,7 @@ for arg in "$@"; do
3335
-h|--help) help ;;
3436
--elf=*) elf_file="${arg#*=}";;
3537
--target=*) target="${arg#*=}";;
38+
--timeout=*) timeout="${arg#*=}";;
3639
*)
3740
;;
3841
esac
@@ -63,6 +66,7 @@ num_macs=$(echo ${target} | cut -d - -f 3)
6366

6467
echo "--------------------------------------------------------------------------------"
6568
echo "Running ${elf_file} for ${target} run with FVP:${fvp_model} num_macs:${num_macs}"
69+
echo "WARNING: Corstone FVP is not cycle accurate and should NOT be used to determine valid runtime"
6670
echo "--------------------------------------------------------------------------------"
6771

6872
log_file=$(mktemp)
@@ -75,7 +79,7 @@ if [[ ${target} == *"ethos-u55"* ]]; then
7579
-C mps3_board.uart0.out_file='-' \
7680
-C mps3_board.uart0.shutdown_on_eot=1 \
7781
-a "${elf_file}" \
78-
--timelimit 220 2>&1 | tee ${log_file} || true # seconds
82+
--timelimit ${timeout} 2>&1 | tee ${log_file} || true # seconds
7983
echo "[${BASH_SOURCE[0]}] Simulation complete, $?"
8084
elif [[ ${target} == *"ethos-u85"* ]]; then
8185
${fvp_model} \
@@ -86,7 +90,7 @@ elif [[ ${target} == *"ethos-u85"* ]]; then
8690
-C mps4_board.uart0.out_file='-' \
8791
-C mps4_board.uart0.shutdown_on_eot=1 \
8892
-a "${elf_file}" \
89-
--timelimit 220 2>&1 | tee ${log_file} || true # seconds
93+
--timelimit ${timeout} 2>&1 | tee ${log_file} || true # seconds
9094
echo "[${BASH_SOURCE[0]}] Simulation complete, $?"
9195
else
9296
echo "Running ${elf_file} for ${target} is not supported"

backends/arm/test/test_arm_baremetal.sh

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -92,18 +92,18 @@ test_run_ethosu_fvp() { # End to End model tests using run.sh
9292

9393
# TOSA quantized
9494
echo "${TEST_SUITE_NAME}: Test ethos-u target TOSA"
95-
examples/arm/run.sh --target=TOSA --model_name=add
96-
examples/arm/run.sh --target=TOSA --model_name=mul
95+
examples/arm/run.sh --et_build_root=arm_test/test_run --target=TOSA --model_name=add
96+
examples/arm/run.sh --et_build_root=arm_test/test_run --target=TOSA --model_name=mul
9797

9898
# Ethos-U55
9999
echo "${TEST_SUITE_NAME}: Test ethos-u target Ethos-U55"
100-
examples/arm/run.sh --target=ethos-u55-128 --model_name=add
101-
examples/arm/run.sh --target=ethos-u55-128 --model_name=mul
100+
examples/arm/run.sh --et_build_root=arm_test/test_run --target=ethos-u55-128 --model_name=add
101+
examples/arm/run.sh --et_build_root=arm_test/test_run --target=ethos-u55-128 --model_name=mul
102102

103103
# Ethos-U85
104104
echo "${TEST_SUITE_NAME}: Test ethos-u target Ethos-U85"
105-
examples/arm/run.sh --target=ethos-u85-128 --model_name=add
106-
examples/arm/run.sh --target=ethos-u85-128 --model_name=mul
105+
examples/arm/run.sh --et_build_root=arm_test/test_run --target=ethos-u85-128 --model_name=add
106+
examples/arm/run.sh --et_build_root=arm_test/test_run --target=ethos-u85-128 --model_name=mul
107107
echo "${TEST_SUITE_NAME}: PASS"
108108
}
109109

@@ -113,26 +113,26 @@ test_models_ethosu_fvp() { # End to End model tests using model_test.py
113113
source examples/arm/ethos-u-scratch/setup_path.sh
114114

115115
# Build common libs once
116-
python3 backends/arm/test/test_model.py --build_libs
116+
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --build_libs
117117

118118
# TOSA quantized
119119
echo "${TEST_SUITE_NAME}: Test ethos-u target TOSA"
120-
python3 backends/arm/test/test_model.py --target=TOSA --model=mv2
121-
python3 backends/arm/test/test_model.py --target=TOSA --model=mv3
122-
python3 backends/arm/test/test_model.py --target=TOSA --model=lstm
123-
python3 backends/arm/test/test_model.py --target=TOSA --model=edsr
120+
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=TOSA --model=mv2
121+
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=TOSA --model=mv3
122+
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=TOSA --model=lstm
123+
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=TOSA --model=edsr
124124

125125
# Ethos-U55
126126
echo "${TEST_SUITE_NAME}: Test ethos-u target Ethos-U55"
127-
python3 backends/arm/test/test_model.py --target=ethos-u55-128 --model=mv2
128-
python3 backends/arm/test/test_model.py --target=ethos-u55-64 --model=mv3
129-
python3 backends/arm/test/test_model.py --target=ethos-u55-256 --model=lstm
127+
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u55-128 --model=mv2 --extra_flags="-DET_ATOL=1.20 -DET_RTOL=1.20"
128+
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u55-64 --model=mv3 --extra_flags="-DET_ATOL=5.00 -DET_RTOL=5.00"
129+
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u55-256 --model=lstm --extra_flags="-DET_ATOL=0.02 -DET_RTOL=0.02"
130130

131131
# Ethos-U85
132132
echo "${TEST_SUITE_NAME}: Test ethos-u target Ethos-U85"
133-
python3 backends/arm/test/test_model.py --target=ethos-u85-256 --model=mv2
134-
python3 backends/arm/test/test_model.py --target=ethos-u85-1024 --model=mv3
135-
python3 backends/arm/test/test_model.py --target=ethos-u85-128 --model=lstm
133+
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u85-256 --model=mv2 --extra_flags="-DET_ATOL=1.20 -DET_RTOL=1.20"
134+
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u85-1024 --model=mv3 --extra_flags="-DET_ATOL=5.00 -DET_RTOL=5.00"
135+
python3 backends/arm/test/test_model.py --test_output=arm_test/test_model --target=ethos-u85-128 --model=lstm --extra_flags="-DET_ATOL=0.02 -DET_RTOL=0.02"
136136
echo "${TEST_SUITE_NAME}: PASS"
137137
}
138138

@@ -146,4 +146,4 @@ test_full_ethosu_fvp() { # All End to End model tests
146146

147147

148148

149-
${TEST_SUITE}
149+
${TEST_SUITE}

backends/arm/test/test_model.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,12 @@ def get_args():
5656
default=False,
5757
help="Don't save temporary files during compilation",
5858
)
59-
59+
parser.add_argument(
60+
"--extra_flags",
61+
required=False,
62+
default=None,
63+
help="Extra cmake flags to pass the when building the executor_runner",
64+
)
6065
args = parser.parse_args()
6166

6267
if args.model and "ethos-u" in args.target and args.system_config is None:
@@ -95,6 +100,8 @@ def build_libs(et_build_root: str, script_path: str):
95100
os.path.join(script_path, "build_executorch.sh"),
96101
f"--et_build_root={et_build_root}",
97102
"--build_type=Release",
103+
"--devtools",
104+
"--etdump",
98105
]
99106
)
100107
run_external_cmd(
@@ -148,6 +155,7 @@ def build_pte(
148155
"examples.arm.aot_arm_compiler",
149156
"--delegate",
150157
"--quantize",
158+
"--bundleio",
151159
intermediate,
152160
f"--model_name={model_name}",
153161
f"--target={target}",
@@ -158,7 +166,7 @@ def build_pte(
158166
]
159167
)
160168

161-
pte_file = os.path.join(output, f"{model_name}_arm_delegate_{args.target}.pte")
169+
pte_file = os.path.join(output, f"{model_name}_arm_delegate_{args.target}.bpte")
162170
return pte_file
163171

164172

@@ -168,17 +176,26 @@ def build_ethosu_runtime(
168176
pte_file: str,
169177
target: str,
170178
system_config: str,
179+
extra_flags: str,
171180
elf_build_path: str,
172181
):
182+
183+
extra_build_flag = ""
184+
if extra_flags:
185+
extra_build_flag = f"--extra_build_flags={extra_flags}"
186+
173187
run_external_cmd(
174188
[
175189
"bash",
176190
os.path.join(script_path, "build_executorch_runner.sh"),
177191
f"--et_build_root={et_build_root}",
178192
f"--pte={pte_file}",
193+
"--bundleio",
194+
"--etdump",
179195
f"--target={target}",
180196
"--build_type=Release",
181197
f"--system_config={system_config}",
198+
extra_build_flag,
182199
f"--output={elf_build_path}",
183200
]
184201
)
@@ -239,6 +256,7 @@ def run_elf_with_fvp(script_path: str, elf_file: str, target: str):
239256
pte_file,
240257
args.target,
241258
args.system_config,
259+
args.extra_flags,
242260
elf_build_path,
243261
)
244262
print(f"ELF file created: {elf_file} ")

0 commit comments

Comments
 (0)