Skip to content

Commit 566eb46

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 79c8e49 commit 566eb46

File tree

6 files changed

+610
-71
lines changed

6 files changed

+610
-71
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: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,16 @@
1919
from executorch.backends.apple.coreml.recipes import CoreMLRecipeType
2020

2121
# pyre-ignore
22+
from executorch.backends.apple.coreml.recipes import CoreMLRecipeType
23+
24+
# pyre-ignore
25+
from executorch.backends.qualcomm.recipes import QNNRecipeType
2226
from executorch.backends.xnnpack.recipes import XNNPackRecipeType
2327
from executorch.export.recipe import ExportRecipe, RecipeType
24-
28+
from executorch.export.utils import (
29+
is_supported_platform_for_coreml_lowering,
30+
is_supported_platform_for_qnn_lowering,
31+
)
2532

2633
## IOS Target configs
2734
# The following list of recipes are not exhaustive for CoreML; refer to CoreMLRecipeType for more detailed recipes.
@@ -34,7 +41,17 @@
3441
# pyre-ignore
3542
"ios-arm64-coreml-int8": [CoreMLRecipeType.PT2E_INT8_STATIC],
3643
}
37-
if sys.platform != "win32"
44+
if is_supported_platform_for_coreml_lowering()
45+
else {}
46+
)
47+
48+
# Android Target configs
49+
ANDROID_CONFIGS: Dict[str, List[RecipeType]] = (
50+
{
51+
# pyre-ignore
52+
"android-arm64-snapdragon-fp16": [QNNRecipeType.FP16],
53+
}
54+
if is_supported_platform_for_qnn_lowering()
3855
else {}
3956
)
4057

@@ -46,7 +63,7 @@ def _create_target_recipe(
4663
Create a combined recipe for a target.
4764
4865
Args:
49-
target: Human-readable hardware configuration name
66+
target_config: Human-readable hardware configuration name
5067
recipes: List of backend recipe types to combine
5168
**kwargs: Additional parameters - each backend will use what it needs
5269
@@ -67,7 +84,6 @@ def _create_target_recipe(
6784
f"Failed to create {recipe_type.value} recipe for {target_config}: {e}"
6885
) from e
6986

70-
# Combine into single recipe
7187
if len(backend_recipes) == 1:
7288
return backend_recipes[0]
7389

@@ -100,6 +116,10 @@ def get_ios_recipe(
100116
recipe = get_ios_recipe('ios-arm64-coreml-int8')
101117
session = export(model, recipe, example_inputs)
102118
"""
119+
120+
if not is_supported_platform_for_coreml_lowering():
121+
raise ValueError("CoreML is not supported on this platform")
122+
103123
if target_config not in IOS_CONFIGS:
104124
supported = list(IOS_CONFIGS.keys())
105125
raise ValueError(
@@ -115,3 +135,48 @@ def get_ios_recipe(
115135

116136
backend_recipes = IOS_CONFIGS[target_config]
117137
return _create_target_recipe(target_config, backend_recipes, **kwargs)
138+
139+
140+
# Android Recipe
141+
def get_android_recipe(
142+
target_config: str = "android-arm64-snapdragon-fp16", **kwargs
143+
) -> ExportRecipe:
144+
"""
145+
Get Android-optimized recipe for specified hardware configuration.
146+
147+
Supported configurations:
148+
- 'android-arm64-snapdragon-fp16': QNN fp16 recipe
149+
150+
Args:
151+
target_config: Android configuration string
152+
**kwargs: Additional parameters for backend recipes
153+
154+
Returns:
155+
ExportRecipe configured for Android deployment
156+
157+
Raises:
158+
ValueError: If target configuration is not supported
159+
160+
Example:
161+
recipe = get_android_recipe('android-arm64-snapdragon-fp16')
162+
session = export(model, recipe, example_inputs)
163+
"""
164+
165+
if not is_supported_platform_for_qnn_lowering():
166+
raise ValueError("QNN is not supported on this platform")
167+
168+
if target_config not in ANDROID_CONFIGS:
169+
supported = list(ANDROID_CONFIGS.keys())
170+
raise ValueError(
171+
f"Unsupported Android configuration: '{target_config}'. "
172+
f"Supported: {supported}"
173+
)
174+
175+
kwargs = kwargs or {}
176+
177+
if target_config == "android-arm64-snapdragon-fp16":
178+
if "soc_model" not in kwargs:
179+
kwargs["soc_model"] = "SM8650"
180+
181+
backend_recipes = ANDROID_CONFIGS[target_config]
182+
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)