Skip to content

Commit b7d2566

Browse files
3l1facebook-github-bot
authored andcommitted
custom fbcode serialize stage to run FVP internally on arm ops tests (#14070)
Summary: Pull Request resolved: #14070 update the codebase to allow a system whereby: - the test inventory in https://www.internalfb.com/code/fbsource/fbcode/executorch/backends/arm/test/ops/, which until now runs on open source CI can all be exercised internally on our internal diff-time sandcastle and CI runs - those tests can **transparently** switch between running an internal version of FVP using Meta's FVP runtimes, build configs and artifacts when run in fbsrouce, but then use the open-source FVp runtime when executed in github opens-ource CI Differential Revision: D81159036
1 parent 8a0a25b commit b7d2566

File tree

5 files changed

+105
-49
lines changed

5 files changed

+105
-49
lines changed

backends/arm/test/TARGETS

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,18 @@ runtime.python_library(
3636
)
3737

3838
runtime.python_library(
39-
name = "arm_tester",
40-
srcs = glob(["tester/*.py"]),
39+
name = "arm_tester_serialize",
40+
srcs = ["tester/serialize.py"],
41+
deps = [
42+
"//executorch/backends/xnnpack/test/tester:tester",
43+
"//executorch/backends/arm:tosa_mapping",
44+
"//executorch/devtools/backend_debug:delegation_info",
45+
]
46+
)
47+
48+
python_library(
49+
name = "arm_tester_lib",
50+
srcs = glob(["tester/*.py"], exclude = ["tester/serialize.py"]),
4151
deps = [
4252
":common",
4353
"//executorch/backends/xnnpack/test/tester:tester",
@@ -51,4 +61,13 @@ runtime.python_library(
5161
]
5262
)
5363

64+
65+
python_library(
66+
name = "arm_tester",
67+
deps = [
68+
"//executorch/backends/arm/test:arm_tester_lib",
69+
"//executorch/backends/arm/test:arm_tester_serialize",
70+
]
71+
)
72+
5473
define_arm_tests()

backends/arm/test/ops/test_tanh.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ def test_tanh_u55_INT(test_data: Tuple):
7676
(test_data(),),
7777
aten_op,
7878
exir_ops=[],
79-
run_on_fvp=False,
79+
run_on_fvp=True,
8080
)
8181
pipeline.run()
8282

backends/arm/test/targets.bzl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# load("//caffe2/test/fb:defs.bzl", "define_tests")
2+
load("@fbsource//tools/build_defs:fbsource_utils.bzl", "is_fbcode")
23
load("@fbcode_macros//build_defs:python_pytest.bzl", "python_pytest")
34
load("@bazel_skylib//lib:paths.bzl", "paths")
45

@@ -36,7 +37,7 @@ def define_arm_tests():
3637
for test_file in test_files:
3738
test_file_name = paths.basename(test_file)
3839
test_name = test_file_name.replace("test_", "").replace(".py", "")
39-
40+
4041
python_pytest(
4142
name = test_name,
4243
srcs = [test_file],
@@ -48,7 +49,7 @@ def define_arm_tests():
4849
"//executorch/kernels/quantized:custom_ops_generated_lib",
4950
],
5051
deps = [
51-
"//executorch/backends/arm/test:arm_tester",
52+
"//executorch/backends/arm/test/tester/fb:arm_tester_fb" if is_fbcode else "//executorch/backends/arm/test:arm_tester",
5253
"//executorch/backends/arm/test:conftest",
5354
"//executorch/exir:lib",
5455
"fbsource//third-party/pypi/pytest:pytest",

backends/arm/test/tester/arm_tester.py

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77

88
import logging
99

10-
import os
1110
from collections import Counter
1211
from pprint import pformat
1312
from typing import (
@@ -47,17 +46,15 @@
4746
)
4847
from executorch.backends.arm.test.runner_utils import (
4948
dbg_tosa_fb_to_json,
50-
get_elf_path,
5149
get_output_quantization_params,
52-
get_target_board,
53-
run_target,
5450
TosaReferenceModelDispatch,
5551
)
5652

5753
from executorch.backends.arm.test.tester.analyze_output_utils import (
5854
dump_error_output,
5955
print_error_diffs,
6056
)
57+
from executorch.backends.arm.test.tester.serialize import Serialize
6158
from executorch.backends.arm.tosa import TosaSpecification
6259
from executorch.backends.arm.tosa.mapping import extract_tensor_meta
6360
from executorch.backends.arm.tosa.partitioner import TOSAPartitioner
@@ -96,7 +93,6 @@
9693

9794
from torch.export.graph_signature import ExportGraphSignature, InputSpec, OutputSpec
9895
from torch.fx import Graph
99-
from torch.utils._pytree import tree_flatten
10096

10197

10298
logger = logging.getLogger(__name__)
@@ -184,44 +180,6 @@ def run(
184180
generate_etrecord=generate_etrecord,
185181
)
186182

187-
188-
class Serialize(tester.Serialize):
189-
def __init__(self, compile_spec: list[CompileSpec], timeout):
190-
super().__init__()
191-
self.timeout = timeout
192-
self.executorch_program_manager: ExecutorchProgramManager | None
193-
self.compile_spec = compile_spec
194-
195-
def run(self, artifact: ExecutorchProgramManager, inputs=None) -> None:
196-
super().run(artifact, inputs)
197-
# Keep the entire ExecutorchProgramManager for execution.
198-
self.executorch_program_manager = artifact
199-
200-
def run_artifact(self, inputs):
201-
if self.executorch_program_manager is None:
202-
raise RuntimeError(
203-
"Tried running artifact from Serialize stage without running the stage."
204-
)
205-
inputs_flattened, _ = tree_flatten(inputs)
206-
intermediate_path = get_intermediate_path(self.compile_spec)
207-
target_board = get_target_board(self.compile_spec)
208-
elf_path = get_elf_path(target_board)
209-
210-
if not os.path.exists(elf_path):
211-
raise FileNotFoundError(
212-
f"Did not find build arm_executor_runner in path {elf_path}, run setup_testing.sh?"
213-
)
214-
215-
return run_target(
216-
self.executorch_program_manager,
217-
inputs_flattened,
218-
intermediate_path,
219-
target_board,
220-
elf_path,
221-
self.timeout,
222-
)
223-
224-
225183
class ToExecutorch(tester.ToExecutorch):
226184
def run_artifact(self, inputs):
227185
with TosaReferenceModelDispatch():
@@ -423,7 +381,11 @@ def serialize(
423381
self, serialize_stage: Optional[Serialize] = None, timeout: int = 480
424382
):
425383
if serialize_stage is None:
426-
serialize_stage = Serialize(self.compile_spec, timeout)
384+
serialize_stage = Serialize(
385+
compile_spec=self.compile_spec,
386+
module=self.original_module,
387+
timeout=timeout
388+
)
427389
assert (
428390
get_intermediate_path(self.compile_spec) is not None
429391
), "Can't dump serialized file when compile specs do not contain an artifact path."
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# Copyright 2024-2025 Arm Limited and/or its affiliates.
2+
#
3+
# This source code is licensed under the BSD-style license found in the
4+
# LICENSE file in the root directory of this source tree.
5+
6+
import logging
7+
import os
8+
from typing import Optional
9+
10+
import executorch.backends.xnnpack.test.tester.tester as tester
11+
12+
import torch.fx
13+
14+
from executorch.backends.arm.arm_backend import get_intermediate_path
15+
from executorch.backends.arm.test.runner_utils import (
16+
get_elf_path,
17+
get_target_board,
18+
run_target,
19+
)
20+
21+
from executorch.exir import ExecutorchProgramManager
22+
from executorch.exir.backend.compile_spec_schema import CompileSpec
23+
from torch.utils._pytree import tree_flatten
24+
25+
26+
logger = logging.getLogger(__name__)
27+
28+
class Serialize(tester.Serialize):
29+
def __init__(
30+
self,
31+
compile_spec: list[CompileSpec],
32+
module: Optional[torch.nn.Module],
33+
timeout: int = 120,
34+
):
35+
"""
36+
Args:
37+
compile_spec: CompileSpecs to be used for serialization.
38+
module: Original Module to be used for serialization. Optional - can be used for reference output generation.
39+
timeout: Timeout for fvp. Default is 120 seconds.
40+
"""
41+
super().__init__()
42+
self.module = module
43+
self.timeout = timeout
44+
self.executorch_program_manager: ExecutorchProgramManager | None
45+
self.compile_spec = compile_spec
46+
47+
def run(self, artifact: ExecutorchProgramManager, inputs=None) -> None:
48+
super().run(artifact, inputs)
49+
# Keep the entire ExecutorchProgramManager for execution.
50+
self.executorch_program_manager = artifact
51+
52+
def run_artifact(self, inputs):
53+
if self.executorch_program_manager is None:
54+
raise RuntimeError(
55+
"Tried running artifact from Serialize stage without running the stage."
56+
)
57+
inputs_flattened, _ = tree_flatten(inputs)
58+
intermediate_path = get_intermediate_path(self.compile_spec)
59+
target_board = get_target_board(self.compile_spec)
60+
elf_path = get_elf_path(target_board)
61+
62+
if not os.path.exists(elf_path):
63+
raise FileNotFoundError(
64+
f"Did not find build arm_executor_runner in path {elf_path}, run setup_testing.sh?"
65+
)
66+
67+
return run_target(
68+
self.executorch_program_manager,
69+
inputs_flattened,
70+
intermediate_path,
71+
target_board,
72+
elf_path,
73+
self.timeout,
74+
)

0 commit comments

Comments
 (0)