Skip to content

Commit fa557ca

Browse files
committed
Update
[ghstack-poisoned]
2 parents 0ffc394 + 9e04e6a commit fa557ca

File tree

20 files changed

+315
-113
lines changed

20 files changed

+315
-113
lines changed

.github/workflows/pull.yml

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -632,32 +632,33 @@ jobs:
632632
# run eval_llama wikitext task
633633
PYTHON_EXECUTABLE=python bash .ci/scripts/test_eval_llama_wikitext.sh
634634
635-
test-eval_llama-mmlu-linux:
636-
name: test-eval_llama-mmlu-linux
637-
uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
638-
permissions:
639-
id-token: write
640-
contents: read
641-
strategy:
642-
fail-fast: false
643-
with:
644-
runner: linux.24xlarge
645-
docker-image: ci-image:executorch-ubuntu-22.04-clang12
646-
submodules: 'recursive'
647-
ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
648-
timeout: 90
649-
script: |
650-
# The generic Linux job chooses to use base env, not the one setup by the image
651-
CONDA_ENV=$(conda env list --json | jq -r ".envs | .[-1]")
652-
conda activate "${CONDA_ENV}"
653-
654-
PYTHON_EXECUTABLE=python bash .ci/scripts/setup-linux.sh --build-tool "cmake"
655-
656-
# install llama requirements
657-
bash examples/models/llama/install_requirements.sh
658-
659-
# run eval_llama mmlu task
660-
PYTHON_EXECUTABLE=python bash .ci/scripts/test_eval_llama_mmlu.sh
635+
# TODO(larryliu0820): Fix this issue before reenabling it: https://gist.github.com/larryliu0820/7377ecd0d79dbc06076cec8d9f2b85d2
636+
# test-eval_llama-mmlu-linux:
637+
# name: test-eval_llama-mmlu-linux
638+
# uses: pytorch/test-infra/.github/workflows/linux_job_v2.yml@main
639+
# permissions:
640+
# id-token: write
641+
# contents: read
642+
# strategy:
643+
# fail-fast: false
644+
# with:
645+
# runner: linux.24xlarge
646+
# docker-image: ci-image:executorch-ubuntu-22.04-clang12
647+
# submodules: 'recursive'
648+
# ref: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
649+
# timeout: 90
650+
# script: |
651+
# # The generic Linux job chooses to use base env, not the one setup by the image
652+
# CONDA_ENV=$(conda env list --json | jq -r ".envs | .[-1]")
653+
# conda activate "${CONDA_ENV}"
654+
655+
# PYTHON_EXECUTABLE=python bash .ci/scripts/setup-linux.sh --build-tool "cmake"
656+
657+
# # install llama requirements
658+
# bash examples/models/llama/install_requirements.sh
659+
660+
# # run eval_llama mmlu task
661+
# PYTHON_EXECUTABLE=python bash .ci/scripts/test_eval_llama_mmlu.sh
661662

662663
test-llama_runner_eager-linux:
663664
name: test-llama_runner_eager-linux

backends/apple/coreml/partition/coreml_partitioner.py

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,27 @@
2323
from torch.fx.passes.operator_support import OperatorSupportBase
2424

2525
logger = logging.getLogger(__name__)
26-
logger.setLevel(logging.WARNING)
26+
logger.setLevel(logging.INFO)
2727

2828

29-
class OperatorsSupportedForCoreMLBackend(OperatorSupportBase):
29+
class _OperatorsSupportedForCoreMLBackend(OperatorSupportBase):
3030
def __init__(
3131
self,
3232
skip_ops_for_coreml_delegation: Optional[List[str]] = None,
3333
lower_full_graph: bool = False,
34+
log: bool = False,
3435
) -> None:
3536
if skip_ops_for_coreml_delegation is None:
3637
skip_ops_for_coreml_delegation = []
3738
super().__init__()
3839
self.skip_ops_for_coreml_delegation = skip_ops_for_coreml_delegation
3940
self.lower_full_graph = lower_full_graph
4041
self._logged_msgs = set()
42+
self._log = log
4143

4244
def log_once(self, msg: str) -> None:
43-
if msg not in self._logged_msgs:
44-
logging.info(msg)
45+
if self._log and msg not in self._logged_msgs:
46+
logger.info(msg)
4547
self._logged_msgs.add(msg)
4648

4749
def is_node_supported(self, submodules, node: torch.fx.Node) -> bool:
@@ -154,8 +156,10 @@ def partition(self, exported_program: ExportedProgram) -> PartitionResult:
154156

155157
capability_partitioner = CapabilityBasedPartitioner(
156158
exported_program.graph_module,
157-
OperatorsSupportedForCoreMLBackend(
158-
self.skip_ops_for_coreml_delegation, self.lower_full_graph
159+
_OperatorsSupportedForCoreMLBackend(
160+
self.skip_ops_for_coreml_delegation,
161+
self.lower_full_graph,
162+
log=True,
159163
),
160164
allows_single_node_partition=True,
161165
)
@@ -191,8 +195,10 @@ def ops_to_not_decompose(
191195
self, ep: ExportedProgram
192196
) -> Tuple[List[torch._ops.OpOverload], Optional[Callable[[torch.fx.Node], bool]]]:
193197
do_not_decompose = []
194-
op_support = OperatorsSupportedForCoreMLBackend(
195-
self.skip_ops_for_coreml_delegation, self.lower_full_graph
198+
op_support = _OperatorsSupportedForCoreMLBackend(
199+
self.skip_ops_for_coreml_delegation,
200+
self.lower_full_graph,
201+
log=False,
196202
)
197203

198204
# CoreML prevents certain ops (like triu) from lowering to CoreML when put in the ExecuTorch op namespace

backends/apple/coreml/test/test_coreml_partitioner.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
from executorch.backends.apple.coreml.compiler import CoreMLBackend
1717
from executorch.backends.apple.coreml.partition import CoreMLPartitioner
1818
from executorch.exir.backend.utils import format_delegated_graph
19-
from executorch.runtime import Runtime
2019

2120

2221
@torch.library.custom_op("unsupported::linear", mutates_args=())
@@ -37,7 +36,13 @@ def _(
3736
return torch.ops.aten.linear.default(x, w, b)
3837

3938

40-
_TEST_RUNTIME = sys.platform == "darwin"
39+
def is_fbcode():
40+
return not hasattr(torch.version, "git_version")
41+
42+
43+
_TEST_RUNTIME = (sys.platform == "darwin") and not is_fbcode()
44+
if _TEST_RUNTIME:
45+
from executorch.runtime import Runtime
4146

4247

4348
class TestCoreMLPartitioner(unittest.TestCase):

backends/apple/coreml/test/test_torch_ops.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,20 @@
1414

1515
from executorch.backends.apple.coreml.compiler import CoreMLBackend
1616
from executorch.backends.apple.coreml.partition import CoreMLPartitioner
17-
from executorch.runtime import Runtime
1817
from torchao.quantization import IntxWeightOnlyConfig, PerAxis, PerGroup, quantize_
1918

20-
_TEST_RUNTIME = sys.platform == "darwin" and tuple(
21-
map(int, platform.mac_ver()[0].split("."))
22-
) >= (15, 0)
19+
20+
def is_fbcode():
21+
return not hasattr(torch.version, "git_version")
22+
23+
24+
_TEST_RUNTIME = (
25+
(sys.platform == "darwin")
26+
and not is_fbcode()
27+
and tuple(map(int, platform.mac_ver()[0].split("."))) >= (15, 0)
28+
)
29+
if _TEST_RUNTIME:
30+
from executorch.runtime import Runtime
2331

2432

2533
class TestTorchOps(unittest.TestCase):

backends/test/suite/__init__.py

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
import unittest
1313

1414
from enum import Enum
15-
from typing import Any, Callable, Tuple
15+
from typing import Callable
16+
17+
import executorch.backends.test.suite.flow
1618

1719
import torch
18-
from executorch.backends.test.harness import Tester
1920
from executorch.backends.test.suite.context import get_active_test_context, TestContext
21+
from executorch.backends.test.suite.flow import TestFlow
2022
from executorch.backends.test.suite.reporting import log_test_summary
2123
from executorch.backends.test.suite.runner import run_test, runner_main
2224

@@ -44,22 +46,20 @@ def is_backend_enabled(backend):
4446
return backend in _ENABLED_BACKENDS
4547

4648

47-
ALL_TEST_FLOWS = []
49+
_ALL_TEST_FLOWS: dict[str, TestFlow] = {}
4850

49-
if is_backend_enabled("xnnpack"):
50-
from executorch.backends.xnnpack.test.tester import Tester as XnnpackTester
5151

52-
XNNPACK_TEST_FLOW = ("xnnpack", XnnpackTester)
53-
ALL_TEST_FLOWS.append(XNNPACK_TEST_FLOW)
52+
def get_test_flows() -> dict[str, TestFlow]:
53+
global _ALL_TEST_FLOWS
5454

55-
if is_backend_enabled("coreml"):
56-
try:
57-
from executorch.backends.apple.coreml.test.tester import CoreMLTester
55+
if not _ALL_TEST_FLOWS:
56+
_ALL_TEST_FLOWS = {
57+
name: f
58+
for name, f in executorch.backends.test.suite.flow.all_flows().items()
59+
if is_backend_enabled(f.backend)
60+
}
5861

59-
COREML_TEST_FLOW = ("coreml", CoreMLTester)
60-
ALL_TEST_FLOWS.append(COREML_TEST_FLOW)
61-
except Exception:
62-
print("Core ML AOT is not available.")
62+
return _ALL_TEST_FLOWS
6363

6464

6565
DTYPES = [
@@ -115,53 +115,51 @@ def _create_tests(cls):
115115
# Expand a test into variants for each registered flow.
116116
def _expand_test(cls, test_name: str):
117117
test_func = getattr(cls, test_name)
118-
for flow_name, tester_factory in ALL_TEST_FLOWS:
119-
_create_test_for_backend(cls, test_func, flow_name, tester_factory)
118+
for flow in get_test_flows().values():
119+
_create_test_for_backend(cls, test_func, flow)
120120
delattr(cls, test_name)
121121

122122

123123
def _make_wrapped_test(
124124
test_func: Callable,
125125
test_name: str,
126-
test_flow: str,
127-
tester_factory: Callable,
126+
flow: TestFlow,
128127
params: dict | None = None,
129128
):
130129
def wrapped_test(self):
131-
with TestContext(test_name, test_flow, params):
130+
with TestContext(test_name, flow.name, params):
132131
test_kwargs = params or {}
133-
test_kwargs["tester_factory"] = tester_factory
132+
test_kwargs["tester_factory"] = flow.tester_factory
134133

135134
test_func(self, **test_kwargs)
136135

136+
wrapped_test._name = test_name
137+
wrapped_test._flow = flow
138+
137139
return wrapped_test
138140

139141

140142
def _create_test_for_backend(
141143
cls,
142144
test_func: Callable,
143-
flow_name: str,
144-
tester_factory: Callable[[torch.nn.Module, Tuple[Any]], Tester],
145+
flow: TestFlow,
145146
):
146147
test_type = getattr(test_func, "test_type", TestType.STANDARD)
147148

148149
if test_type == TestType.STANDARD:
149-
wrapped_test = _make_wrapped_test(
150-
test_func, test_func.__name__, flow_name, tester_factory
151-
)
152-
test_name = f"{test_func.__name__}_{flow_name}"
150+
wrapped_test = _make_wrapped_test(test_func, test_func.__name__, flow)
151+
test_name = f"{test_func.__name__}_{flow.name}"
153152
setattr(cls, test_name, wrapped_test)
154153
elif test_type == TestType.DTYPE:
155154
for dtype in DTYPES:
156155
wrapped_test = _make_wrapped_test(
157156
test_func,
158157
test_func.__name__,
159-
flow_name,
160-
tester_factory,
158+
flow,
161159
{"dtype": dtype},
162160
)
163161
dtype_name = str(dtype)[6:] # strip "torch."
164-
test_name = f"{test_func.__name__}_{dtype_name}_{flow_name}"
162+
test_name = f"{test_func.__name__}_{dtype_name}_{flow.name}"
165163
setattr(cls, test_name, wrapped_test)
166164
else:
167165
raise NotImplementedError(f"Unknown test type {test_type}.")

backends/test/suite/discovery.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Copyright (c) Meta Platforms, Inc. and affiliates.
2+
# All rights reserved.
3+
#
4+
# This source code is licensed under the BSD-style license found in the
5+
# LICENSE file in the root directory of this source tree.
6+
7+
# pyre-unsafe
8+
9+
import os
10+
import unittest
11+
12+
from types import ModuleType
13+
14+
from executorch.backends.test.suite.flow import TestFlow
15+
16+
#
17+
# This file contains logic related to test discovery and filtering.
18+
#
19+
20+
21+
def discover_tests(
22+
root_module: ModuleType, backends: set[str] | None
23+
) -> unittest.TestSuite:
24+
# Collect all tests using the unittest discovery mechanism then filter down.
25+
26+
# Find the file system path corresponding to the root module.
27+
module_file = root_module.__file__
28+
if module_file is None:
29+
raise RuntimeError(f"Module {root_module} has no __file__ attribute")
30+
31+
loader = unittest.TestLoader()
32+
module_dir = os.path.dirname(module_file)
33+
suite = loader.discover(module_dir)
34+
35+
return _filter_tests(suite, backends)
36+
37+
38+
def _filter_tests(
39+
suite: unittest.TestSuite, backends: set[str] | None
40+
) -> unittest.TestSuite:
41+
# Recursively traverse the test suite and add them to the filtered set.
42+
filtered_suite = unittest.TestSuite()
43+
44+
for child in suite:
45+
if isinstance(child, unittest.TestSuite):
46+
filtered_suite.addTest(_filter_tests(child, backends))
47+
elif isinstance(child, unittest.TestCase):
48+
if _is_test_enabled(child, backends):
49+
filtered_suite.addTest(child)
50+
else:
51+
raise RuntimeError(f"Unexpected test type: {type(child)}")
52+
53+
return filtered_suite
54+
55+
56+
def _is_test_enabled(test_case: unittest.TestCase, backends: set[str] | None) -> bool:
57+
test_method = getattr(test_case, test_case._testMethodName)
58+
59+
if backends is not None:
60+
flow: TestFlow = test_method._flow
61+
return flow.backend in backends
62+
else:
63+
return True

0 commit comments

Comments
 (0)