Skip to content

Commit 8f470f8

Browse files
committed
[Backend Tester] [WIP] Add Qualcomm tester and register flow
ghstack-source-id: e3705a0 ghstack-comment-id: 3105206238 Pull-Request: #12739
1 parent 0c6e314 commit 8f470f8

File tree

4 files changed

+120
-0
lines changed

4 files changed

+120
-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: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
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_qnn_executorch_compiler_spec,
17+
generate_htp_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 or EdgeCompileConfig(_check_ir_validity=False),
51+
default_partitioner_cls=QnnPartitioner,
52+
)
53+
54+
def run(self, artifact: ExportedProgram, inputs=None) -> None:
55+
ep = QnnPassManager().transform_for_export_pipeline(artifact)
56+
transform_passes = QnnPassManager().get_to_edge_transform_passes(ep)
57+
58+
self.edge_dialect_program = to_edge_transform_and_lower(
59+
ep,
60+
transform_passes=transform_passes,
61+
partitioner=self.partitioners,
62+
compile_config=self.edge_compile_conf,
63+
)
64+
65+
66+
class QualcommTester(TesterBase):
67+
def __init__(
68+
self,
69+
module: torch.nn.Module,
70+
example_inputs: Tuple[torch.Tensor],
71+
dynamic_shapes: Optional[Tuple[Any]] = None,
72+
):
73+
# Specialize for Qualcomm
74+
stage_classes = (
75+
executorch.backends.test.harness.Tester.default_stage_classes()
76+
| {
77+
StageType.PARTITION: Partition,
78+
StageType.TO_EDGE_TRANSFORM_AND_LOWER: ToEdgeTransformAndLower,
79+
}
80+
)
81+
82+
super().__init__(
83+
module=module,
84+
stage_classes=stage_classes,
85+
example_inputs=example_inputs,
86+
dynamic_shapes=dynamic_shapes,
87+
)

backends/test/suite/flow.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,4 +61,12 @@ def all_flows() -> dict[str, TestFlow]:
6161
except Exception as e:
6262
logger.info(f"Skipping Vulkan flow registration: {e}")
6363

64+
try:
65+
from executorch.backends.test.suite.flows.qualcomm import QUALCOMM_TEST_FLOW
66+
flows += [
67+
QUALCOMM_TEST_FLOW,
68+
]
69+
except Exception as e:
70+
logger.info(f"Skipping Qualcomm flow registration: {e}")
71+
6472
return {f.name: f for f in flows if f is not None}

backends/test/suite/flows/qualcomm.py

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

0 commit comments

Comments
 (0)