Skip to content

Commit 971909d

Browse files
committed
[Backend Tester] [WIP] Add Qualcomm tester and register flow
ghstack-source-id: 5336762 ghstack-comment-id: 3105206238 Pull-Request: #12739
1 parent 4fd2079 commit 971909d

File tree

4 files changed

+124
-0
lines changed

4 files changed

+124
-0
lines changed

backends/qualcomm/tests/TARGETS

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,13 @@ python_library(
3737
"//executorch/backends/qualcomm/debugger:utils",
3838
],
3939
)
40+
41+
python_library(
42+
name = "tester",
43+
srcs = [
44+
"tester.py",
45+
],
46+
deps = [
47+
":test_qnn_delegate"
48+
]
49+
)

backends/qualcomm/tests/tester.py

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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+
from typing import Any, List, Optional, Tuple
8+
9+
import executorch
10+
import executorch.backends.test.harness.stages as BaseStages
11+
12+
import torch
13+
from executorch.backends.qualcomm._passes.qnn_pass_manager import QnnPassManager
14+
from executorch.backends.qualcomm.partition.qnn_partitioner import QnnPartitioner
15+
from executorch.backends.qualcomm.utils.utils import (
16+
generate_htp_compiler_spec,
17+
generate_qnn_executorch_compiler_spec,
18+
get_soc_to_chipset_map,
19+
)
20+
from executorch.backends.test.harness import Tester as TesterBase
21+
from executorch.backends.test.harness.stages import StageType
22+
from executorch.exir import EdgeCompileConfig, to_edge_transform_and_lower
23+
from executorch.exir.backend.partitioner import Partitioner
24+
from torch.export import ExportedProgram
25+
26+
27+
class Partition(BaseStages.Partition):
28+
def __init__(self, partitioner: Optional[Partitioner] = None):
29+
super().__init__(
30+
partitioner=partitioner or QnnPartitioner,
31+
)
32+
33+
34+
class ToEdgeTransformAndLower(BaseStages.ToEdgeTransformAndLower):
35+
def __init__(
36+
self,
37+
partitioners: Optional[List[Partitioner]] = None,
38+
edge_compile_config: Optional[EdgeCompileConfig] = None,
39+
soc_model: str = "SM8650",
40+
):
41+
backend_options = generate_htp_compiler_spec(use_fp16=True)
42+
self.chipset = get_soc_to_chipset_map()[soc_model]
43+
self.compiler_specs = generate_qnn_executorch_compiler_spec(
44+
soc_model=self.chipset,
45+
backend_options=backend_options,
46+
)
47+
48+
super().__init__(
49+
partitioners=partitioners or [QnnPartitioner(self.compiler_specs)],
50+
edge_compile_config=edge_compile_config
51+
or EdgeCompileConfig(_check_ir_validity=False),
52+
default_partitioner_cls=QnnPartitioner,
53+
)
54+
55+
def run(self, artifact: ExportedProgram, inputs=None) -> None:
56+
ep = QnnPassManager().transform_for_export_pipeline(artifact)
57+
transform_passes = QnnPassManager().get_to_edge_transform_passes(ep)
58+
59+
self.edge_dialect_program = to_edge_transform_and_lower(
60+
ep,
61+
transform_passes=transform_passes,
62+
partitioner=self.partitioners,
63+
compile_config=self.edge_compile_conf,
64+
)
65+
66+
67+
class QualcommTester(TesterBase):
68+
def __init__(
69+
self,
70+
module: torch.nn.Module,
71+
example_inputs: Tuple[torch.Tensor],
72+
dynamic_shapes: Optional[Tuple[Any]] = None,
73+
):
74+
# Specialize for Qualcomm
75+
stage_classes = (
76+
executorch.backends.test.harness.Tester.default_stage_classes()
77+
| {
78+
StageType.PARTITION: Partition,
79+
StageType.TO_EDGE_TRANSFORM_AND_LOWER: ToEdgeTransformAndLower,
80+
}
81+
)
82+
83+
super().__init__(
84+
module=module,
85+
stage_classes=stage_classes,
86+
example_inputs=example_inputs,
87+
dynamic_shapes=dynamic_shapes,
88+
)

backends/test/suite/flow.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,13 @@ def all_flows() -> dict[str, TestFlow]:
7171
except Exception as e:
7272
logger.info(f"Skipping Vulkan flow registration: {e}")
7373

74+
try:
75+
from executorch.backends.test.suite.flows.qualcomm import QUALCOMM_TEST_FLOW
76+
77+
flows += [
78+
QUALCOMM_TEST_FLOW,
79+
]
80+
except Exception as e:
81+
logger.info(f"Skipping Qualcomm flow registration: {e}")
82+
7483
return {f.name: f for f in flows if f is not None}

backends/test/suite/flows/qualcomm.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from executorch.backends.qualcomm.tests.tester import QualcommTester
2+
from executorch.backends.test.suite.flow import TestFlow
3+
4+
5+
def _create_qualcomm_flow(
6+
name: str,
7+
quantize: bool = False,
8+
) -> TestFlow:
9+
return TestFlow(
10+
name,
11+
backend="qualcomm",
12+
tester_factory=QualcommTester,
13+
quantize=quantize,
14+
)
15+
16+
17+
QUALCOMM_TEST_FLOW = _create_qualcomm_flow("qualcomm")

0 commit comments

Comments
 (0)