Skip to content

Commit 6f7f7c1

Browse files
Add android target recipes and extensive model tests using ios and android recipes (pytorch#14290)
Summary: Changes in this diff: 1. Adds android target recipes using QNN backend. 2. Add extensive model lowering and accuracy checks using torchvision models. ``` from executorch.export import export qnn_android_recipe = get_android_recipe() # lower a model to pte session = export(model, recipe, example_inputs) out = session.run_method("forward", *example_inputs) ``` Differential Revision: D82284987
1 parent 8d081ed commit 6f7f7c1

File tree

6 files changed

+605
-102
lines changed

6 files changed

+605
-102
lines changed

backends/qualcomm/_passes/TARGETS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,6 @@ runtime.python_library(
1515
"//executorch/backends/transforms:decompose_sdpa",
1616
"//executorch/exir/backend:backend_details",
1717
"//executorch/exir/backend:compile_spec_schema",
18+
"//executorch/backends/qualcomm/quantizer:quantizer",
1819
],
1920
)

export/TARGETS

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,19 @@ runtime.python_library(
117117
"target_recipes.py",
118118
],
119119
deps = [
120+
":export_utils",
120121
"fbsource//third-party/pypi/coremltools:coremltools",
121122
"//executorch/export:recipe",
122123
"//executorch/backends/xnnpack/recipes:xnnpack_recipes",
123124
"//executorch/backends/apple/coreml:coreml_recipes",
125+
"//executorch/backends/qualcomm/recipes:qnn_recipes",
126+
]
127+
)
128+
129+
runtime.python_library(
130+
name = "export_utils",
131+
srcs = ["utils.py"],
132+
deps = [
133+
"//caffe2:torch",
124134
]
125135
)

export/target_recipes.py

Lines changed: 86 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,13 @@
1111
selection and combine multiple backends optimally for target hardware.
1212
"""
1313

14-
import sys
1514
from typing import Dict, List
1615

17-
if sys.platform != "win32":
18-
import coremltools as ct
19-
from executorch.backends.apple.coreml.recipes import CoreMLRecipeType
20-
21-
# pyre-ignore
2216
from executorch.backends.xnnpack.recipes import XNNPackRecipeType
2317
from executorch.export.recipe import ExportRecipe, RecipeType
24-
25-
26-
## IOS Target configs
27-
# The following list of recipes are not exhaustive for CoreML; refer to CoreMLRecipeType for more detailed recipes.
28-
IOS_CONFIGS: Dict[str, List[RecipeType]] = (
29-
{
30-
# pyre-ignore
31-
"ios-arm64-coreml-fp32": [CoreMLRecipeType.FP32, XNNPackRecipeType.FP32],
32-
# pyre-ignore
33-
"ios-arm64-coreml-fp16": [CoreMLRecipeType.FP16],
34-
# pyre-ignore
35-
"ios-arm64-coreml-int8": [CoreMLRecipeType.PT2E_INT8_STATIC],
36-
}
37-
if sys.platform != "win32"
38-
else {}
18+
from executorch.export.utils import (
19+
is_supported_platform_for_coreml_lowering,
20+
is_supported_platform_for_qnn_lowering,
3921
)
4022

4123

@@ -46,7 +28,7 @@ def _create_target_recipe(
4628
Create a combined recipe for a target.
4729
4830
Args:
49-
target: Human-readable hardware configuration name
31+
target_config: Human-readable hardware configuration name
5032
recipes: List of backend recipe types to combine
5133
**kwargs: Additional parameters - each backend will use what it needs
5234
@@ -67,7 +49,6 @@ def _create_target_recipe(
6749
f"Failed to create {recipe_type.value} recipe for {target_config}: {e}"
6850
) from e
6951

70-
# Combine into single recipe
7152
if len(backend_recipes) == 1:
7253
return backend_recipes[0]
7354

@@ -100,8 +81,24 @@ def get_ios_recipe(
10081
recipe = get_ios_recipe('ios-arm64-coreml-int8')
10182
session = export(model, recipe, example_inputs)
10283
"""
103-
if target_config not in IOS_CONFIGS:
104-
supported = list(IOS_CONFIGS.keys())
84+
85+
if not is_supported_platform_for_coreml_lowering():
86+
raise ValueError("CoreML is not supported on this platform")
87+
88+
import coremltools as ct
89+
from executorch.backends.apple.coreml.recipes import CoreMLRecipeType
90+
91+
ios_configs: Dict[str, List[RecipeType]] = {
92+
# pyre-ignore
93+
"ios-arm64-coreml-fp32": [CoreMLRecipeType.FP32, XNNPackRecipeType.FP32],
94+
# pyre-ignore
95+
"ios-arm64-coreml-fp16": [CoreMLRecipeType.FP16],
96+
# pyre-ignore
97+
"ios-arm64-coreml-int8": [CoreMLRecipeType.PT2E_INT8_STATIC],
98+
}
99+
100+
if target_config not in ios_configs:
101+
supported = list(ios_configs.keys())
105102
raise ValueError(
106103
f"Unsupported iOS configuration: '{target_config}'. "
107104
f"Supported: {supported}"
@@ -113,5 +110,68 @@ def get_ios_recipe(
113110
if "minimum_deployment_target" not in kwargs:
114111
kwargs["minimum_deployment_target"] = ct.target.iOS17
115112

116-
backend_recipes = IOS_CONFIGS[target_config]
113+
backend_recipes = ios_configs[target_config]
114+
return _create_target_recipe(target_config, backend_recipes, **kwargs)
115+
116+
117+
# Android Recipe
118+
def get_android_recipe(
119+
target_config: str = "android-arm64-snapdragon-fp16", **kwargs
120+
) -> ExportRecipe:
121+
"""
122+
Get Android-optimized recipe for specified hardware configuration.
123+
124+
Supported configurations:
125+
- 'android-arm64-snapdragon-fp16': QNN fp16 recipe
126+
127+
Args:
128+
target_config: Android configuration string
129+
**kwargs: Additional parameters for backend recipes
130+
131+
Returns:
132+
ExportRecipe configured for Android deployment
133+
134+
Raises:
135+
ValueError: If target configuration is not supported
136+
137+
Example:
138+
recipe = get_android_recipe('android-arm64-snapdragon-fp16')
139+
session = export(model, recipe, example_inputs)
140+
"""
141+
142+
if not is_supported_platform_for_qnn_lowering():
143+
raise ValueError(
144+
"QNN is not supported or not properly configured on this platform"
145+
)
146+
147+
try:
148+
# Qualcomm QNN backend runs various sdk downloads on first use
149+
# with a pip install, so wrap it in a try/except
150+
# pyre-ignore
151+
from executorch.backends.qualcomm.recipes import QNNRecipeType
152+
except:
153+
raise ValueError(
154+
"QNN backend is not available. Please ensure the Qualcomm backend "
155+
"is properly installed and configured, "
156+
)
157+
158+
android_configs: Dict[str, List[RecipeType]] = {
159+
# pyre-ignore
160+
"android-arm64-snapdragon-fp16": [QNNRecipeType.FP16],
161+
}
162+
163+
if target_config not in android_configs:
164+
supported = list(android_configs.keys())
165+
raise ValueError(
166+
f"Unsupported Android configuration: '{target_config}'. "
167+
f"Supported: {supported}"
168+
)
169+
170+
kwargs = kwargs or {}
171+
172+
if target_config == "android-arm64-snapdragon-fp16":
173+
if "soc_model" not in kwargs:
174+
kwargs["soc_model"] = "SM8650"
175+
176+
backend_recipes = android_configs[target_config]
117177
return _create_target_recipe(target_config, backend_recipes, **kwargs)

export/tests/TARGETS

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
load("@fbsource//xplat/executorch/build:runtime_wrapper.bzl", "runtime")
2+
load("@fbsource//xplat/executorch/backends/qualcomm/qnn_version.bzl", "get_qnn_library_version")
23

34
oncall("executorch")
45

@@ -37,11 +38,23 @@ runtime.python_test(
3738
srcs = [
3839
"test_target_recipes.py",
3940
],
41+
env = {
42+
"LD_LIBRARY_PATH": "$(location fbsource//third-party/qualcomm/qnn/qnn-{0}:qnn_offline_compile_libs)".format(get_qnn_library_version()),
43+
"QNN_SDK_ROOT": "$(location fbsource//third-party/qualcomm/qnn/qnn-{0}:__dir__)".format(get_qnn_library_version()),
44+
"HTTP_PROXY": "http://fwdproxy:8080",
45+
"HTTPS_PROXY": "http://fwdproxy:8080",
46+
},
47+
labels = ["long_running"],
4048
deps = [
4149
"//executorch/export:lib",
4250
"//executorch/export:target_recipes",
51+
"//executorch/export:export_utils",
4352
"//executorch/runtime:runtime",
4453
"//executorch/backends/xnnpack/recipes:xnnpack_recipes",
4554
"//executorch/backends/apple/coreml:coreml_recipes",
55+
"//executorch/backends/qualcomm/recipes:qnn_recipes",
56+
"//executorch/examples/models:models",
57+
"//executorch/backends/xnnpack/test/tester:tester",
58+
"fbsource//third-party/pypi/coremltools:coremltools"
4659
]
4760
)

0 commit comments

Comments
 (0)