Skip to content

Commit fc8afbc

Browse files
3l1facebook-github-bot
authored andcommitted
custom fbcode serialize stage to run FVP internally on arm ops tests (#14070)
Summary: 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 a90e907 commit fc8afbc

File tree

5 files changed

+104
-47
lines changed

5 files changed

+104
-47
lines changed

backends/arm/test/TARGETS

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

3838
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",
@@ -50,4 +60,13 @@ python_library(
5060
]
5161
)
5262

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

backends/arm/test/ops/test_tanh.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ def test_tanh_u55_INT(test_data: Tuple):
6969
(test_data(),),
7070
aten_op,
7171
exir_ops=[],
72-
run_on_fvp=False,
72+
run_on_fvp=True,
7373
)
7474
pipeline.run()
7575

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

@@ -32,7 +33,7 @@ def define_arm_tests():
3233
for test_file in test_files:
3334
test_file_name = paths.basename(test_file)
3435
test_name = test_file_name.replace("test_", "").replace(".py", "")
35-
36+
3637
python_pytest(
3738
name = test_name,
3839
srcs = [test_file],
@@ -44,7 +45,7 @@ def define_arm_tests():
4445
"//executorch/kernels/quantized:custom_ops_generated_lib",
4546
],
4647
deps = [
47-
"//executorch/backends/arm/test:arm_tester",
48+
"//executorch/backends/arm/test/tester/fb:arm_tester_fb" if is_fbcode else "//executorch/backends/arm/test:arm_tester",
4849
"//executorch/backends/arm/test:conftest",
4950
"//executorch/exir:lib",
5051
"fbsource//third-party/pypi/pytest:pytest",

backends/arm/test/tester/arm_tester.py

Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,7 @@
4747
)
4848
from executorch.backends.arm.test.runner_utils import (
4949
dbg_tosa_fb_to_json,
50-
get_elf_path,
5150
get_output_quantization_params,
52-
get_target_board,
53-
run_target,
5451
TosaReferenceModelDispatch,
5552
)
5653

@@ -97,6 +94,7 @@
9794
from torch.export.graph_signature import ExportGraphSignature, InputSpec, OutputSpec
9895
from torch.fx import Graph
9996
from torch.utils._pytree import tree_flatten
97+
from executorch.backends.arm.test.tester.serialize import Serialize
10098

10199

102100
logger = logging.getLogger(__name__)
@@ -184,44 +182,6 @@ def run(
184182
generate_etrecord=generate_etrecord,
185183
)
186184

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-
225185
class ToExecutorch(tester.ToExecutorch):
226186
def run_artifact(self, inputs):
227187
with TosaReferenceModelDispatch():
@@ -423,7 +383,7 @@ def serialize(
423383
self, serialize_stage: Optional[Serialize] = None, timeout: int = 480
424384
):
425385
if serialize_stage is None:
426-
serialize_stage = Serialize(self.compile_spec, timeout)
386+
serialize_stage = Serialize(compile_spec=self.compile_spec, module=self.original_module, timeout=timeout)
427387
assert (
428388
get_intermediate_path(self.compile_spec) is not None
429389
), "Can't dump serialized file when compile specs do not contain an artifact path."
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
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 serializer.tosa_serializer as ts # type: ignore[import-untyped]
13+
14+
import torch.fx
15+
import torch.utils._pytree as pytree
16+
17+
from executorch.backends.arm.arm_backend import get_intermediate_path
18+
from executorch.backends.arm.test.runner_utils import (
19+
get_elf_path,
20+
get_target_board,
21+
run_target,
22+
)
23+
24+
from executorch.exir import ExecutorchProgramManager
25+
from executorch.exir.backend.compile_spec_schema import CompileSpec
26+
from torch.utils._pytree import tree_flatten
27+
28+
29+
logger = logging.getLogger(__name__)
30+
31+
class Serialize(tester.Serialize):
32+
def __init__(
33+
self,
34+
compile_spec: list[CompileSpec],
35+
module: Optional[torch.nn.Module],
36+
timeout: int = 120
37+
):
38+
"""
39+
Args:
40+
compile_spec: CompileSpecs to be used for serialization.
41+
module: Original Module to be used for serialization. Optional - can be used for reference output generation.
42+
timeout: Timeout for fvp. Default is 120 seconds.
43+
"""
44+
super().__init__()
45+
self.module = module
46+
self.timeout = timeout
47+
self.executorch_program_manager: ExecutorchProgramManager | None
48+
self.compile_spec = compile_spec
49+
50+
def run(self, artifact: ExecutorchProgramManager, inputs=None) -> None:
51+
super().run(artifact, inputs)
52+
# Keep the entire ExecutorchProgramManager for execution.
53+
self.executorch_program_manager = artifact
54+
55+
def run_artifact(self, inputs):
56+
if self.executorch_program_manager is None:
57+
raise RuntimeError(
58+
"Tried running artifact from Serialize stage without running the stage."
59+
)
60+
inputs_flattened, _ = tree_flatten(inputs)
61+
intermediate_path = get_intermediate_path(self.compile_spec)
62+
target_board = get_target_board(self.compile_spec)
63+
elf_path = get_elf_path(target_board)
64+
65+
if not os.path.exists(elf_path):
66+
raise FileNotFoundError(
67+
f"Did not find build arm_executor_runner in path {elf_path}, run setup_testing.sh?"
68+
)
69+
70+
return run_target(
71+
self.executorch_program_manager,
72+
inputs_flattened,
73+
intermediate_path,
74+
target_board,
75+
elf_path,
76+
self.timeout,
77+
)

0 commit comments

Comments
 (0)