Skip to content

Commit 2265ab8

Browse files
authored
Arm backend: Add U55 portable fallback ops (#20803)
Add missing portable CPU fallback kernels to the U55 selected-op runner. U65 inherits the same portable op list, so the U65 portable runner gets the same fallback coverage. These ops are needed when the partitioner rejects parts of a graph for Ethos-U delegation. The TOSA/Vela delegate segment can still compile successfully, but the model load fails when a non-delegated CPU fallback op is not registered in the portable runner. Added U55/U65 fallback ops: aten::avg_pool2d.out aten::gt.Tensor_out aten::where.self_out aten::expand_copy.out aten::clamp.out aten::mul.out aten::index_select.out aten::fmod.Scalar_out aten::add.out aten::arange.start_out aten::eq.Tensor_out aten::logical_not.out Keep the regular U55 div-mode test on the non-portable ELF so it still detects undelegated CPU fallback regions. Add a separate U55 portable-op variant without xfails to verify the mixed delegated and portable fallback runtime path. Reduce the default Corstone-300 linker heap to keep the portable-op runner linkable with Arm GNU toolchain 15.2 after the additional fallback registrations, while making heap and stack sizes overrideable. Fixes the flow tests: test_adaptive_avgpool2d_batch_sizes[arm_ethos_u55] test_divide_f32_trunc[arm_ethos_u55] test_swin_v2_t[arm_ethos_u55-static_shapes-float32] Signed-off-by: Zingo Andersen <Zingo.Andersen@arm.com>
1 parent c9688e9 commit 2265ab8

4 files changed

Lines changed: 62 additions & 7 deletions

File tree

backends/arm/test/ops/test_div_tensor_mode.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,12 @@ def _is_integer_rounded_div(mode, inputs) -> bool:
102102
),
103103
}
104104

105+
u55_portable_ops_test_data = {
106+
"int8_floor": test_data["int8_floor"],
107+
"int8_int_scalar": test_data["int8_int_scalar"],
108+
"int32_floor": test_data["int32_floor"],
109+
}
110+
105111

106112
@common.parametrize("data", test_data)
107113
def test_div_tensor_mode_tosa_FP(data):
@@ -139,14 +145,34 @@ def test_div_tensor_mode_tosa_INT(data):
139145
test_data,
140146
xfails={
141147
"mode_trunc": "CPU op missing in unittests",
148+
"int8_floor": "CPU op missing in unittests",
149+
"int8_int_scalar": "CPU op missing in unittests",
142150
"int16_trunc": "CPU op missing in unittests",
151+
"int32_floor": "CPU op missing in unittests",
143152
"int32_trunc": "CPU op missing in unittests",
144153
},
145154
)
146155
def test_div_tensor_mode_u55_INT(data):
147156
mode, inputs = data()
148157
model = DivTensorModeFloat(mode)
149158

159+
pipeline = EthosU55PipelineINT[input_tt](
160+
model,
161+
inputs,
162+
aten_ops=[],
163+
exir_ops=[],
164+
use_to_edge_transform_and_lower=True,
165+
)
166+
pipeline.pop_stage("check_count.exir")
167+
pipeline.run()
168+
169+
170+
@common.XfailIfNoCorstone300
171+
@common.parametrize("data", u55_portable_ops_test_data)
172+
def test_div_tensor_mode_u55_INT_portable_ops(data):
173+
mode, inputs = data()
174+
model = DivTensorModeFloat(mode)
175+
150176
pipeline = EthosU55PipelineINT[input_tt](
151177
model,
152178
inputs,

backends/arm/test/setup_testing.sh

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ et_root_dir=$(realpath "${script_dir}/../../..")
1111
build_executor_runner=${et_root_dir}/backends/arm/scripts/build_executor_runner.sh
1212
build_root_test_dir=${et_root_dir}/arm_test/arm_semihosting_executor_runner
1313
extraflags="-DET_ARM_BAREMETAL_METHOD_ALLOCATOR_POOL_SIZE=83886080"
14+
portable_extraflags="${extraflags} -DHEAP_SIZE=0x00007000"
1415

1516
# By default tests with an elf without any portable_ops
1617
# If you supply use_portable_ops=True when creating the ArmTester()
@@ -26,10 +27,21 @@ ${build_executor_runner} --pte=semihosting --target=ethos-u85-128 --system_confi
2627
# test setup to make sure models that are not fully delegated can still be tested and run OK
2728
# To use this you can set use_portable_ops=True when creating ArmTester()
2829

29-
portable_ops_list_u55="aten::permute_copy.out,aten::convolution.out,aten::relu.out,aten::_native_batch_norm_legit_no_training.out,aten::as_strided_copy.out,aten::mean.out,aten::squeeze_copy.dims,dim_order_ops::_clone_dim_order.out,dim_order_ops::_to_dim_order_copy.out"
30+
# Flow-suite missing-kernel failures covered by portable ops:
31+
# Ethos-U55/U65
32+
# aten::avg_pool2d.out - test_adaptive_avgpool2d_batch_sizes[arm_ethos_u55]
33+
# aten::gt.Tensor_out - test_divide_f32_trunc[arm_ethos_u55]
34+
#
35+
# Ethos-U85:
36+
# aten::_native_batch_norm_legit_no_training.out - test_swin_v2_t[arm_ethos_u85-static_shapes-float32]
37+
# dim_order_ops::_to_dim_order_copy.out - test_argmin_dtype[arm_ethos_u85-float32], test_avgpool3d_input_sizes[arm_ethos_u85]
38+
# aten::scalar_tensor.out - U85 operator-suite aggregate fallback coverage
39+
# aten::where.self_out - U85 operator-suite aggregate fallback coverage
40+
41+
portable_ops_list_u55="aten::permute_copy.out,aten::convolution.out,aten::relu.out,aten::_native_batch_norm_legit_no_training.out,aten::as_strided_copy.out,aten::mean.out,aten::squeeze_copy.dims,aten::avg_pool2d.out,aten::gt.Tensor_out,aten::where.self_out,aten::expand_copy.out,aten::clamp.out,aten::mul.out,aten::index_select.out,aten::fmod.Scalar_out,aten::add.out,aten::arange.start_out,aten::eq.Tensor_out,aten::logical_not.out,dim_order_ops::_clone_dim_order.out,dim_order_ops::_to_dim_order_copy.out"
3042
portable_ops_list_u65="${portable_ops_list_u55}"
3143
portable_ops_list_u85="aten::permute_copy.out,aten::convolution.out,aten::relu.out,aten::_native_batch_norm_legit_no_training.out,aten::as_strided_copy.out,aten::mean.out,aten::full_like.out,aten::bmm.out,aten::scalar_tensor.out,aten::index.Tensor_out,aten::where.self_out,dim_order_ops::_to_dim_order_copy.out"
3244

33-
${build_executor_runner} --pte=semihosting --target=ethos-u55-128 --system_config=Ethos_U55_High_End_Embedded --memory_mode=Shared_Sram --select_ops_list="${portable_ops_list_u55}" --output="${build_root_test_dir}_portable-ops_corstone-300" --extra_build_flags=${extraflags}
34-
${build_executor_runner} --pte=semihosting --target=ethos-u65-256 --system_config=Ethos_U65_High_End --memory_mode=Dedicated_Sram_384KB --select_ops_list="${portable_ops_list_u65}" --output="${build_root_test_dir}_portable-ops_corstone-300-u65" --extra_build_flags=${extraflags}
45+
${build_executor_runner} --pte=semihosting --target=ethos-u55-128 --system_config=Ethos_U55_High_End_Embedded --memory_mode=Shared_Sram --select_ops_list="${portable_ops_list_u55}" --output="${build_root_test_dir}_portable-ops_corstone-300" --extra_build_flags="${portable_extraflags}"
46+
${build_executor_runner} --pte=semihosting --target=ethos-u65-256 --system_config=Ethos_U65_High_End --memory_mode=Dedicated_Sram_384KB --select_ops_list="${portable_ops_list_u65}" --output="${build_root_test_dir}_portable-ops_corstone-300-u65" --extra_build_flags="${portable_extraflags}"
3547
${build_executor_runner} --pte=semihosting --target=ethos-u85-128 --system_config=Ethos_U85_SYS_DRAM_Mid --memory_mode=Dedicated_Sram_384KB --select_ops_list="${portable_ops_list_u85}" --output="${build_root_test_dir}_portable-ops_corstone-320" --extra_build_flags=${extraflags}

examples/arm/executor_runner/CMakeLists.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,13 +288,22 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
288288
set(COMPILER_PREPROCESSOR_OPTIONS -E -x c -P)
289289
endif()
290290

291+
set(_arm_runner_linker_preprocessor_options ${COMPILER_PREPROCESSOR_OPTIONS})
292+
foreach(_arm_runner_linker_define IN ITEMS HEAP_SIZE STACK_SIZE)
293+
if(DEFINED ${_arm_runner_linker_define})
294+
list(APPEND _arm_runner_linker_preprocessor_options
295+
"-D${_arm_runner_linker_define}=${${_arm_runner_linker_define}}"
296+
)
297+
endif()
298+
endforeach()
299+
291300
get_filename_component(LINK_FILE_OUT_BASE "${LINK_FILE}" NAME)
292301
set(LINK_FILE_OUT
293302
"${CMAKE_CURRENT_BINARY_DIR}/${LINK_FILE_OUT_BASE}.${LINK_FILE_EXT}"
294303
)
295304

296305
execute_process(
297-
COMMAND ${CMAKE_C_COMPILER} ${COMPILER_PREPROCESSOR_OPTIONS} -o
306+
COMMAND ${CMAKE_C_COMPILER} ${_arm_runner_linker_preprocessor_options} -o
298307
${LINK_FILE_OUT} ${LINK_FILE_IN}
299308
)
300309
target_link_options(arm_executor_runner PRIVATE "-T" "${LINK_FILE_OUT}")

examples/arm/executor_runner/Corstone-300.ld

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2025 Arm Limited and/or its affiliates.
2+
* Copyright 2025-2026 Arm Limited and/or its affiliates.
33
*
44
* This source code is licensed under the BSD-style license found in the
55
* LICENSE file in the root directory of this source tree.
@@ -24,8 +24,16 @@
2424
#define ETHOSU_ARENA 1
2525
#endif
2626

27-
__STACK_SIZE = 0x00008000;
28-
__HEAP_SIZE = 0x00008000;
27+
#ifndef STACK_SIZE
28+
#define STACK_SIZE 0x00008000
29+
#endif
30+
31+
#ifndef HEAP_SIZE
32+
#define HEAP_SIZE 0x00008000
33+
#endif
34+
35+
__STACK_SIZE = STACK_SIZE;
36+
__HEAP_SIZE = HEAP_SIZE;
2937

3038
MEMORY
3139
{

0 commit comments

Comments
 (0)