Skip to content

Commit 5a79e18

Browse files
authored
Arm backend: Add target tests for cond and while. (pytorch#16408)
Currently only Ethos-U85 supports the operators. Signed-off-by: Erik Lundell <erik.lundell@arm.com>
1 parent e485840 commit 5a79e18

3 files changed

Lines changed: 145 additions & 4 deletions

File tree

‎backends/arm/ethosu/compile_spec.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ def __init__(
7777
if "u55" in target_lower:
7878
# Add the Ethos-U55 extension marker
7979
base_tosa_version += "+u55"
80+
if "u85" in self.target:
81+
base_tosa_version += "+cf"
8082
tosa_spec = TosaSpecification.create_from_string(base_tosa_version)
8183

8284
self._set_compile_specs(tosa_spec, compiler_flags)

‎backends/arm/test/ops/test_cond.py‎

Lines changed: 80 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,13 @@
99
from executorch.backends.arm.test import common
1010
from executorch.backends.arm.test.tester.arm_tester import ArmTester
1111
from executorch.backends.arm.test.tester.test_pipeline import (
12+
EthosU85PipelineINT,
13+
OpNotSupportedPipeline,
1214
TosaPipelineFP,
1315
TosaPipelineINT,
16+
VgfPipeline,
1417
)
18+
from pytest import mark
1519

1620
aten_op = "torch.ops.higher_order.cond"
1721
exir_op = "torch.ops.higher_order.cond"
@@ -210,6 +214,15 @@ def _make_calibration_samples(
210214
return (if_example_inputs, else_example_inputs)
211215

212216

217+
def _set_branch_calibration_samples(
218+
pipeline, module: torch.nn.Module, example_inputs: tuple
219+
) -> None:
220+
calibration_samples = _make_calibration_samples(module, example_inputs)
221+
quant_stage_pos = pipeline.find_pos("quantize")
222+
quant_stage = pipeline._stages[quant_stage_pos].args[0]
223+
quant_stage.calibration_samples = calibration_samples
224+
225+
213226
@common.parametrize(
214227
"case",
215228
test_cases,
@@ -247,10 +260,7 @@ def test_cond_tosa_INT(case: Callable[[], tuple[torch.nn.Module, tuple]]):
247260
pipeline = TosaPipelineINT[tuple](
248261
module, example_inputs, aten_op, tosa_extensions=["cf"]
249262
)
250-
calibration_samples = _make_calibration_samples(module, example_inputs)
251-
quant_stage_pos = pipeline.find_pos("quantize")
252-
quant_stage = pipeline._stages[quant_stage_pos].args[0]
253-
quant_stage.calibration_samples = calibration_samples
263+
_set_branch_calibration_samples(pipeline, module, example_inputs)
254264

255265
# Make sure no cond ops are left after partitioning.
256266
pipeline.add_stage_after(
@@ -260,3 +270,69 @@ def test_cond_tosa_INT(case: Callable[[], tuple[torch.nn.Module, tuple]]):
260270
["torch.ops.higher_order.cond"],
261271
)
262272
pipeline.run()
273+
274+
275+
@common.parametrize(
276+
"case",
277+
test_cases,
278+
)
279+
def test_cond_u55_INT(case: Callable[[], tuple[torch.nn.Module, tuple]]):
280+
module, example_inputs = case()
281+
pipeline = OpNotSupportedPipeline[tuple](module, example_inputs, {aten_op: 1})
282+
pipeline.pop_stage("check_count.exir")
283+
pipeline.run()
284+
285+
286+
@common.parametrize(
287+
"case",
288+
test_cases,
289+
xfails={
290+
"one_arg_and_scalar_one_output": "Incorrect quantization on the scalar.",
291+
"nested_one_arg_one_output": "Node submodule_0 target submodule_0 references nonexistent attribute submodule_0",
292+
},
293+
skips={
294+
"one_arg_one_output": "Segfault when transpose goes into cond. MLBEDSW-11416.",
295+
"one_arg_const_one_output": "Segfault when transpose goes into cond. MLBEDSW-11416.",
296+
"multiple_one_arg_one_output": "Segfault when transpose goes into cond. MLBEDSW-11416.",
297+
},
298+
)
299+
@common.XfailIfNoCorstone320.with_args(raises=None)
300+
def test_cond_u85_INT(case: Callable[[], tuple[torch.nn.Module, tuple]]):
301+
module, example_inputs = case()
302+
pipeline = EthosU85PipelineINT[tuple](module, example_inputs, aten_op, exir_op)
303+
_set_branch_calibration_samples(pipeline, module, example_inputs)
304+
pipeline.run()
305+
306+
307+
@mark.skip("Cond not supported in model_converter.")
308+
@common.parametrize(
309+
"case",
310+
test_cases,
311+
)
312+
@common.SkipIfNoModelConverter
313+
def test_cond_vgf_FP(case: Callable[[], tuple[torch.nn.Module, tuple]]):
314+
module, example_inputs = case()
315+
VgfPipeline[tuple](
316+
module,
317+
example_inputs,
318+
aten_op,
319+
exir_op,
320+
).run()
321+
322+
323+
@mark.skip("Cond not supported in model_converter.")
324+
@common.parametrize(
325+
"case",
326+
test_cases,
327+
)
328+
@common.SkipIfNoModelConverter
329+
def test_cond_vgf_INT(case: Callable[[], tuple[torch.nn.Module, tuple]]):
330+
module, example_inputs = case()
331+
pipeline = VgfPipeline[tuple](
332+
module,
333+
example_inputs,
334+
aten_op,
335+
exir_op,
336+
)
337+
_set_branch_calibration_samples(pipeline, module, example_inputs)
338+
pipeline.run()

‎backends/arm/test/ops/test_while.py‎

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@
1111
from executorch.backends.arm.test import common
1212
from executorch.backends.arm.test.tester.arm_tester import ArmTester
1313
from executorch.backends.arm.test.tester.test_pipeline import (
14+
EthosU85PipelineINT,
15+
OpNotSupportedPipeline,
1416
TosaPipelineFP,
1517
TosaPipelineINT,
18+
VgfPipeline,
1619
)
20+
from pytest import mark
1721

1822
input_single = Tuple[torch.Tensor]
1923
input_double = Tuple[torch.Tensor, torch.Tensor]
@@ -199,3 +203,62 @@ def test_while_loop_tosa_INT(case: Callable[[], Tuple[torch.nn.Module, Tuple]]):
199203
["torch.ops.higher_order.while_loop"],
200204
)
201205
pipeline.run()
206+
207+
208+
@common.parametrize(
209+
"case",
210+
test_cases,
211+
)
212+
def test_while_loop_u55_INT(case: Callable[[], Tuple[torch.nn.Module, Tuple]]):
213+
module, example_inputs = case()
214+
OpNotSupportedPipeline[tuple](
215+
module,
216+
example_inputs,
217+
non_delegated_ops={"torch.ops.higher_order.while_loop": 1},
218+
u55_subset=True,
219+
).run()
220+
221+
222+
@common.parametrize(
223+
"case",
224+
test_cases,
225+
)
226+
@common.XfailIfNoCorstone320
227+
def test_while_loop_u85_INT(case: Callable[[], Tuple[torch.nn.Module, Tuple]]):
228+
module, example_inputs = case()
229+
EthosU85PipelineINT[tuple](
230+
module,
231+
example_inputs,
232+
"torch.ops.higher_order.while_loop",
233+
).run()
234+
235+
236+
@mark.skip("While not supported in model_converter.")
237+
@common.parametrize(
238+
"case",
239+
test_cases,
240+
)
241+
@common.SkipIfNoModelConverter
242+
def test_while_loop_vgf_FP(case: Callable[[], Tuple[torch.nn.Module, Tuple]]):
243+
module, example_inputs = case()
244+
VgfPipeline[tuple](
245+
module,
246+
example_inputs,
247+
"torch.ops.higher_order.while_loop",
248+
tosa_version="TOSA-1.0+FP",
249+
).run()
250+
251+
252+
@mark.skip("While not supported in model_converter.")
253+
@common.parametrize(
254+
"case",
255+
test_cases,
256+
)
257+
@common.SkipIfNoModelConverter
258+
def test_while_loop_vgf_INT(case: Callable[[], Tuple[torch.nn.Module, Tuple]]):
259+
module, example_inputs = case()
260+
VgfPipeline[tuple](
261+
module,
262+
example_inputs,
263+
"torch.ops.higher_order.while_loop",
264+
).run()

0 commit comments

Comments
 (0)