Skip to content

Commit 658b99f

Browse files
Add android target recipes and extensive model tests using ios and android recipes (#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 eec95d0 commit 658b99f

File tree

6 files changed

+622
-83
lines changed

6 files changed

+622
-83
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: 72 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,22 @@
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":
16+
from executorch.backends.xnnpack.recipes import XNNPackRecipeType
17+
from executorch.export.recipe import ExportRecipe, RecipeType
18+
from executorch.export.utils import (
19+
is_supported_platform_for_coreml_lowering,
20+
is_supported_platform_for_qnn_lowering,
21+
)
22+
23+
if is_supported_platform_for_coreml_lowering():
1824
import coremltools as ct
1925
from executorch.backends.apple.coreml.recipes import CoreMLRecipeType
2026

21-
# pyre-ignore
22-
from executorch.backends.xnnpack.recipes import XNNPackRecipeType
23-
from executorch.export.recipe import ExportRecipe, RecipeType
27+
if is_supported_platform_for_qnn_lowering():
28+
# pyre-ignore
29+
from executorch.backends.qualcomm.recipes import QNNRecipeType
2430

2531

2632
## IOS Target configs
@@ -34,7 +40,17 @@
3440
# pyre-ignore
3541
"ios-arm64-coreml-int8": [CoreMLRecipeType.PT2E_INT8_STATIC],
3642
}
37-
if sys.platform != "win32"
43+
if is_supported_platform_for_coreml_lowering()
44+
else {}
45+
)
46+
47+
# Android Target configs
48+
ANDROID_CONFIGS: Dict[str, List[RecipeType]] = (
49+
{
50+
# pyre-ignore
51+
"android-arm64-snapdragon-fp16": [QNNRecipeType.FP16],
52+
}
53+
if is_supported_platform_for_qnn_lowering()
3854
else {}
3955
)
4056

@@ -46,7 +62,7 @@ def _create_target_recipe(
4662
Create a combined recipe for a target.
4763
4864
Args:
49-
target: Human-readable hardware configuration name
65+
target_config: Human-readable hardware configuration name
5066
recipes: List of backend recipe types to combine
5167
**kwargs: Additional parameters - each backend will use what it needs
5268
@@ -67,7 +83,6 @@ def _create_target_recipe(
6783
f"Failed to create {recipe_type.value} recipe for {target_config}: {e}"
6884
) from e
6985

70-
# Combine into single recipe
7186
if len(backend_recipes) == 1:
7287
return backend_recipes[0]
7388

@@ -100,6 +115,10 @@ def get_ios_recipe(
100115
recipe = get_ios_recipe('ios-arm64-coreml-int8')
101116
session = export(model, recipe, example_inputs)
102117
"""
118+
119+
if not is_supported_platform_for_coreml_lowering():
120+
raise ValueError("CoreML is not supported on this platform")
121+
103122
if target_config not in IOS_CONFIGS:
104123
supported = list(IOS_CONFIGS.keys())
105124
raise ValueError(
@@ -115,3 +134,48 @@ def get_ios_recipe(
115134

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