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-
21- # pyre-ignore
2216from executorch .backends .xnnpack .recipes import XNNPackRecipeType
2317from 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 )
0 commit comments