1111selection and combine multiple backends optimally for target hardware.
1212"""
1313
14- import sys
1514from 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-
2116# pyre-ignore
17+ from executorch .backends .qualcomm .recipes import QNNRecipeType
2218from executorch .backends .xnnpack .recipes import XNNPackRecipeType
2319from executorch .export .recipe import ExportRecipe , RecipeType
20+ from executorch .export .utils import (
21+ is_supported_platform_for_coreml_lowering ,
22+ is_supported_platform_for_qnn_lowering ,
23+ )
2424
25+ if is_supported_platform_for_coreml_lowering ():
26+ import coremltools as ct
27+ from executorch .backends .apple .coreml .recipes import CoreMLRecipeType
2528
2629## IOS Target configs
2730# The following list of recipes are not exhaustive for CoreML; refer to CoreMLRecipeType for more detailed recipes.
3437 # pyre-ignore
3538 "ios-arm64-coreml-int8" : [CoreMLRecipeType .PT2E_INT8_STATIC ],
3639 }
37- if sys .platform != "win32"
40+ if is_supported_platform_for_coreml_lowering ()
41+ else {}
42+ )
43+
44+ # Android Target configs
45+ ANDROID_CONFIGS : Dict [str , List [RecipeType ]] = (
46+ {
47+ # pyre-ignore
48+ "android-arm64-snapdragon-fp16" : [QNNRecipeType .FP16 ],
49+ }
50+ if is_supported_platform_for_qnn_lowering ()
3851 else {}
3952)
4053
@@ -46,7 +59,7 @@ def _create_target_recipe(
4659 Create a combined recipe for a target.
4760
4861 Args:
49- target : Human-readable hardware configuration name
62+ target_config : Human-readable hardware configuration name
5063 recipes: List of backend recipe types to combine
5164 **kwargs: Additional parameters - each backend will use what it needs
5265
@@ -67,7 +80,6 @@ def _create_target_recipe(
6780 f"Failed to create { recipe_type .value } recipe for { target_config } : { e } "
6881 ) from e
6982
70- # Combine into single recipe
7183 if len (backend_recipes ) == 1 :
7284 return backend_recipes [0 ]
7385
@@ -100,6 +112,10 @@ def get_ios_recipe(
100112 recipe = get_ios_recipe('ios-arm64-coreml-int8')
101113 session = export(model, recipe, example_inputs)
102114 """
115+
116+ if not is_supported_platform_for_coreml_lowering ():
117+ raise ValueError ("CoreML is not supported on this platform" )
118+
103119 if target_config not in IOS_CONFIGS :
104120 supported = list (IOS_CONFIGS .keys ())
105121 raise ValueError (
@@ -115,3 +131,48 @@ def get_ios_recipe(
115131
116132 backend_recipes = IOS_CONFIGS [target_config ]
117133 return _create_target_recipe (target_config , backend_recipes , ** kwargs )
134+
135+
136+ # Android Recipe
137+ def get_android_recipe (
138+ target_config : str = "android-arm64-snapdragon-fp16" , ** kwargs
139+ ) -> ExportRecipe :
140+ """
141+ Get Android-optimized recipe for specified hardware configuration.
142+
143+ Supported configurations:
144+ - 'android-arm64-snapdragon-fp16': QNN fp16 recipe
145+
146+ Args:
147+ target_config: Android configuration string
148+ **kwargs: Additional parameters for backend recipes
149+
150+ Returns:
151+ ExportRecipe configured for Android deployment
152+
153+ Raises:
154+ ValueError: If target configuration is not supported
155+
156+ Example:
157+ recipe = get_android_recipe('android-arm64-snapdragon-fp16')
158+ session = export(model, recipe, example_inputs)
159+ """
160+
161+ if not is_supported_platform_for_qnn_lowering ():
162+ raise ValueError ("QNN is not supported on this platform" )
163+
164+ if target_config not in ANDROID_CONFIGS :
165+ supported = list (ANDROID_CONFIGS .keys ())
166+ raise ValueError (
167+ f"Unsupported Android configuration: '{ target_config } '. "
168+ f"Supported: { supported } "
169+ )
170+
171+ kwargs = kwargs or {}
172+
173+ if target_config == "android-arm64-snapdragon-fp16" :
174+ if "soc_model" not in kwargs :
175+ kwargs ["soc_model" ] = "SM8650"
176+
177+ backend_recipes = ANDROID_CONFIGS [target_config ]
178+ return _create_target_recipe (target_config , backend_recipes , ** kwargs )
0 commit comments