Skip to content

Commit fc67945

Browse files
Ninja91facebook-github-bot
authored andcommitted
Add a16w8 reduce_sum FVP coverage for Ethos-U85
Summary: Adds an a16w8 (int16 IO + int8 weights) sweep for `aten.sum.dim_IntList` reducing the last dim with `keepdim=True`. The new tests `test_sum_dim_intlist_a16w8_{u55,u85}_INT` run on the standard Corstone-300 / Corstone-320 FVP harness. The U85 case surfaces a known numerics issue in the Vela `regor` lowering at int16 IO precision (silent zero output), tracked upstream at https://gitlab.arm.com/artificial-intelligence/ethos-u/ethos-u-vela/-/issues/23. The Ethos-U55 path uses a different accumulator and is correct on the same OFM rescale. Also annotates the four `dim_None{,_4d_tensor}` parametrize ids on `test_sum_u{55,85}_INT_1_0` (and the corresponding fp16 / bf16 variants) with `skips=` -- those cases cannot be exercised through the FVP harness because `executorch.devtools.bundled_program.config` rejects `None` as a model input. The dim=None case is properly covered by the existing `SumDefault` class. Test design: - Standard `pipeline.run()` with the same a16w8 kwargs other arm a16w8 tests use (e.g. `test_native_layer_norm_16a8w_u85_INT` in `test_layer_norm.py`): `a16w8_quantization=True, symmetric_io_quantization=True, qtol=128, epsilon=2**-16`. - Numerical comparison is the standard `atol`/`rtol` check from `pipeline.run()` -- no SQNR helpers. - The U85 a16w8 test is wrapped with both `common.XfailIfNoCorstone320` (handles missing-FVP environments via `FileNotFoundError`) and `pytest.mark.xfail(strict=False, reason="...")` (handles the silent-zero bug). Both are function-level decorators that compose cleanly -- pattern matches `test_max_pool1d.py:111-114`. `strict=False` keeps the test target green both on stock Vela 5.0 (cases XFAIL) and once the upstream Vela fix is in tree (cases XPASS allowed). Differential Revision: D103667823
1 parent 851cffb commit fc67945

2 files changed

Lines changed: 74 additions & 2 deletions

File tree

backends/arm/test/ops/test_sum.py

Lines changed: 73 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55

66
from typing import Callable, Tuple
77

8+
import pytest
9+
810
import torch
911
from executorch.backends.arm.test import common
1012

@@ -96,7 +98,19 @@ def test_sum_dim_intlist_tosa_INT(test_data: input_t1):
9698
pipeline.run()
9799

98100

99-
@common.parametrize("test_data", Sum.test_parameters)
101+
# dim=None cases skipped: executorch.devtools.bundled_program.config rejects
102+
# None as a model input. dim=None is covered by the SumDefault class below.
103+
_DIM_NONE_SKIP_REASON = (
104+
"bundled_program cannot serialize None as a model input; "
105+
"dim=None is covered by SumDefault"
106+
)
107+
_dim_none_skips = {
108+
"dim_None": _DIM_NONE_SKIP_REASON,
109+
"dim_None_4d_tensor": _DIM_NONE_SKIP_REASON,
110+
}
111+
112+
113+
@common.parametrize("test_data", Sum.test_parameters, skips=_dim_none_skips)
100114
@common.XfailIfNoCorstone300
101115
def test_sum_u55_INT_1_0(test_data: Tuple):
102116
pipeline = EthosU55PipelineINT[input_t1](
@@ -108,7 +122,7 @@ def test_sum_u55_INT_1_0(test_data: Tuple):
108122
pipeline.run()
109123

110124

111-
@common.parametrize("test_data", Sum.test_parameters)
125+
@common.parametrize("test_data", Sum.test_parameters, skips=_dim_none_skips)
112126
@common.XfailIfNoCorstone320
113127
def test_sum_u85_INT_1_0(test_data: Tuple):
114128
pipeline = EthosU85PipelineINT[input_t1](
@@ -220,3 +234,60 @@ def test_sum_tosa_FP(test_data: Callable[[], input_t2]):
220234
def test_sum_tosa_INT(test_data: Callable[[], input_t2]):
221235
pipeline = TosaPipelineINT[input_t1](SumDefault(), test_data(), SumDefault.aten_op)
222236
pipeline.run()
237+
238+
239+
# a16w8 (int16 IO + int8 weights) coverage for sum.dim_IntList. Surfaces the
240+
# Ethos-U85 int16 ReduceSum silent-zero issue tracked upstream at
241+
# https://gitlab.arm.com/artificial-intelligence/ethos-u/ethos-u-vela/-/issues/23.
242+
243+
244+
class SumLastDim(torch.nn.Module):
245+
"""Reduce the last dim with keepdim=True."""
246+
247+
def forward(self, x: torch.Tensor) -> torch.Tensor:
248+
return x.sum(dim=-1, keepdim=True)
249+
250+
251+
a16w8_sum_test_parameters = {
252+
"rank1_16": lambda: (torch.rand(16),),
253+
"rank3_8x1x16": lambda: (torch.rand(8, 1, 16),),
254+
"rank3_4x4x16": lambda: (torch.rand(4, 4, 16),),
255+
}
256+
257+
258+
@common.parametrize("test_data", a16w8_sum_test_parameters)
259+
@common.XfailIfNoCorstone300
260+
def test_sum_dim_intlist_a16w8_u55_INT(test_data: Callable[[], input_t1]):
261+
pipeline = EthosU55PipelineINT[input_t1](
262+
SumLastDim(),
263+
test_data(),
264+
aten_op,
265+
exir_ops=[],
266+
a16w8_quantization=True,
267+
symmetric_io_quantization=True,
268+
qtol=128,
269+
epsilon=2**-16,
270+
)
271+
pipeline.run()
272+
273+
274+
# All cases hit upstream Vela issue #23 (linked above). strict=False so the
275+
# test target stays green both on stock Vela 5.0 (cases XFAIL) and once the
276+
# Vela fix is in tree (cases XPASS).
277+
@common.parametrize("test_data", a16w8_sum_test_parameters)
278+
@common.XfailIfNoCorstone320
279+
@pytest.mark.xfail(
280+
reason="Ethos-U85 int16 ReduceSum returns zero (vela#23)", strict=False
281+
)
282+
def test_sum_dim_intlist_a16w8_u85_INT(test_data: Callable[[], input_t1]):
283+
pipeline = EthosU85PipelineINT[input_t1](
284+
SumLastDim(),
285+
test_data(),
286+
aten_op,
287+
exir_ops=[],
288+
a16w8_quantization=True,
289+
symmetric_io_quantization=True,
290+
qtol=128,
291+
epsilon=2**-16,
292+
)
293+
pipeline.run()

backends/arm/test/targets.bzl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ def define_arm_tests():
3030
"ops/test_slice.py",
3131
"ops/test_sigmoid.py",
3232
"ops/test_sub.py",
33+
"ops/test_sum.py",
3334
"ops/test_tanh.py",
3435
"ops/test_view.py",
3536
"ops/test_cos.py",

0 commit comments

Comments
 (0)