1010
1111"""
1212
13- import copy
1413import logging
1514
1615import torch
2221 SupportedTOSAOperatorCheck ,
2322)
2423from executorch .backends .arm .tosa import TosaSpecification
24+ from executorch .backends .arm .tosa .cast_support import (
25+ supported_to_dim_order_casts ,
26+ SupportedCastMap ,
27+ )
2528from executorch .exir .dialects ._ops import ops as exir_ops
2629
2730logger = logging .getLogger (__name__ )
2831
29- SupportedTypeDict = dict [torch .dtype , list [torch .dtype ]]
30-
3132
3233@register_tosa_support_check
3334class ToCopySupported (SupportedTOSAOperatorCheck ):
34- """Provide TOSA support check for ``_to_dim_order_copy``.
35-
36- Attributes:
37- SUPPORTED_INT_PROFILE_DTYPES (dict[torch.dtype, list[torch.dtype]]):
38- Allowed output dtypes for each integer input dtype.
39- SUPPORTED_FP_PROFILE_DTYPES (dict[torch.dtype, list[torch.dtype]]):
40- Allowed output dtypes for each floating input dtype.
41-
42- """
35+ """Provide TOSA support check for ``_to_dim_order_copy``."""
4336
4437 targets = [
4538 exir_ops .edge .dim_order_ops ._to_dim_order_copy .default ,
4639 ]
4740
48- @staticmethod
49- def _merge_supported_types (
50- dtypes1 : SupportedTypeDict ,
51- dtypes2 : SupportedTypeDict ,
52- ) -> SupportedTypeDict :
53- """Return a merged mapping of supported dtype transitions.
54-
55- Args:
56- dtypes1 (dict[torch.dtype, list[torch.dtype]]): Base mapping.
57- dtypes2 (dict[torch.dtype, list[torch.dtype]]): Mapping to merge in.
58-
59- Returns:
60- dict[torch.dtype, list[torch.dtype]]: Combined mapping.
61-
62- """
63- merged_dtypes = copy .deepcopy (
64- dtypes1
65- ) # Use deepcopy to avoid unintentionally modifying SUPPORTED_INT_PROFILE_DTYPES
66- for k , v in dtypes2 .items ():
67- merged_dtypes [k ] = merged_dtypes .get (k , []) + v
68- return merged_dtypes
69-
70- SUPPORTED_INT_PROFILE_DTYPES : SupportedTypeDict = {
71- torch .bool : [torch .bool , torch .int8 , torch .int16 , torch .int32 ],
72- torch .int8 : [torch .bool , torch .int8 , torch .int16 , torch .int32 ],
73- torch .int16 : [torch .bool , torch .int8 , torch .int16 , torch .int32 ],
74- torch .int32 : [torch .bool , torch .int8 , torch .int16 , torch .int32 ],
75- torch .int64 : [torch .bool , torch .int8 , torch .int16 , torch .int32 ],
76- }
77- SUPPORTED_FP_PROFILE_DTYPES : SupportedTypeDict = {
78- torch .int8 : [torch .int8 , torch .float16 , torch .float32 ],
79- torch .int16 : [torch .int16 , torch .float16 , torch .float32 ],
80- torch .int32 : [torch .int32 , torch .float16 , torch .float32 ],
81- # INT64 inputs to casts *should* be ok, since they should be rejected by
82- # CheckInt64InputsAndOutputs if the cast can't be done AOT.
83- torch .int64 : [
84- torch .int8 ,
85- torch .int16 ,
86- torch .int32 ,
87- torch .float16 ,
88- torch .float32 ,
89- ],
90- torch .float16 : [
91- torch .int8 ,
92- torch .int16 ,
93- torch .int32 ,
94- torch .float16 ,
95- torch .float32 ,
96- ],
97- torch .float32 : [
98- torch .float32 ,
99- torch .int8 ,
100- torch .int16 ,
101- torch .int32 ,
102- torch .float16 ,
103- torch .float32 ,
104- ],
105- }
106- SUPPORTED_INT_FP_PROFILE_DTYPES : SupportedTypeDict = {
107- torch .bool : [torch .float32 ],
108- }
109- SUPPORTED_BF16_EXTENSION_DTYPES : SupportedTypeDict = {
110- torch .int8 : [torch .bfloat16 ],
111- torch .int16 : [torch .bfloat16 ],
112- torch .int32 : [torch .bfloat16 ],
113- torch .int64 : [torch .bfloat16 ],
114- torch .float32 : [torch .bfloat16 ],
115- torch .bfloat16 : [
116- torch .int8 ,
117- torch .int16 ,
118- torch .int32 ,
119- torch .bfloat16 ,
120- torch .float32 ,
121- ],
122- }
123- SUPPORTED_FP8E4M3_EXTENSION_DTYPES : SupportedTypeDict = {
124- torch .float16 : [torch .float8_e4m3fn ],
125- torch .float32 : [torch .float8_e4m3fn ],
126- torch .float8_e4m3fn : [torch .float16 , torch .float32 ],
127- }
128- SUPPORTED_FP8E5M2_EXTENSION_DTYPES : SupportedTypeDict = {
129- torch .float16 : [torch .float8_e5m2 ],
130- torch .float32 : [torch .float8_e5m2 ],
131- torch .float8_e5m2 : [torch .float16 , torch .float32 ],
132- }
133- SUPPORTED_BF16_FP8E4M3_EXTENSION_DTYPES : SupportedTypeDict = {
134- torch .bfloat16 : [torch .float8_e4m3fn ],
135- torch .float8_e4m3fn : [torch .bfloat16 ],
136- }
137- SUPPORTED_BF16_FP8E5M2_EXTENSION_DTYPES : SupportedTypeDict = {
138- torch .bfloat16 : [torch .float8_e5m2 ],
139- torch .float8_e5m2 : [torch .bfloat16 ],
140- }
141-
14241 @staticmethod
14342 def _is_quantized_identity_cast (node : torch .fx .Node ) -> bool :
14443 for user in node .users :
@@ -153,7 +52,7 @@ def _is_quantized_identity_cast(node: torch.fx.Node) -> bool:
15352 return False
15453 return True
15554
156- def is_node_tosa_supported ( # noqa: C901
55+ def is_node_tosa_supported (
15756 self , node : fx .Node , tosa_spec : TosaSpecification
15857 ) -> bool :
15958 """Return True if the node is supported by TOSA.
@@ -163,43 +62,7 @@ def is_node_tosa_supported( # noqa: C901
16362 input dtype.
16463
16564 """
166- supported_dtypes : SupportedTypeDict = {}
167- if tosa_spec .support_integer ():
168- supported_dtypes = self ._merge_supported_types (
169- self .SUPPORTED_INT_PROFILE_DTYPES , supported_dtypes
170- )
171- if tosa_spec .support_float ():
172- supported_dtypes = self ._merge_supported_types (
173- self .SUPPORTED_FP_PROFILE_DTYPES , supported_dtypes
174- )
175- if tosa_spec .support_integer () and tosa_spec .support_float ():
176- supported_dtypes = self ._merge_supported_types (
177- self .SUPPORTED_INT_FP_PROFILE_DTYPES , supported_dtypes
178- )
179- if tosa_spec .support_extension ("bf16" ):
180- supported_dtypes = self ._merge_supported_types (
181- self .SUPPORTED_BF16_EXTENSION_DTYPES , supported_dtypes
182- )
183- if tosa_spec .support_extension ("fp8e4m3" ):
184- supported_dtypes = self ._merge_supported_types (
185- self .SUPPORTED_FP8E4M3_EXTENSION_DTYPES , supported_dtypes
186- )
187- if tosa_spec .support_extension ("fp8e5m2" ):
188- supported_dtypes = self ._merge_supported_types (
189- self .SUPPORTED_FP8E5M2_EXTENSION_DTYPES , supported_dtypes
190- )
191- if tosa_spec .support_extension ("bf16" ) and tosa_spec .support_extension (
192- "fp8e4m3"
193- ):
194- supported_dtypes = self ._merge_supported_types (
195- self .SUPPORTED_BF16_FP8E4M3_EXTENSION_DTYPES , supported_dtypes
196- )
197- if tosa_spec .support_extension ("bf16" ) and tosa_spec .support_extension (
198- "fp8e5m2"
199- ):
200- supported_dtypes = self ._merge_supported_types (
201- self .SUPPORTED_BF16_FP8E5M2_EXTENSION_DTYPES , supported_dtypes
202- )
65+ supported_dtypes : SupportedCastMap = supported_to_dim_order_casts (tosa_spec )
20366
20467 if len (node .all_input_nodes ) != 1 :
20568 self .reporter .report_reject (
@@ -221,7 +84,6 @@ def is_node_tosa_supported( # noqa: C901
22184 )
22285 return False
22386
224- # Check input type
22587 input_dtype = input_val .dtype
22688 if input_dtype not in supported_dtypes :
22789 self .reporter .report_reject (
@@ -230,7 +92,6 @@ def is_node_tosa_supported( # noqa: C901
23092 )
23193 return False
23294
233- # Check output type
23495 output_val = node .meta ["val" ]
23596 if not isinstance (output_val , torch ._subclasses .FakeTensor ):
23697 self .reporter .report_reject (
@@ -242,10 +103,7 @@ def is_node_tosa_supported( # noqa: C901
242103 )
243104 return False
244105 if output_val .dtype not in supported_dtypes [input_dtype ]:
245- if (
246- tosa_spec .support_integer ()
247- and ToCopySupported ._is_quantized_identity_cast (node )
248- ):
106+ if tosa_spec .support_integer () and self ._is_quantized_identity_cast (node ):
249107 return True
250108 self .reporter .report_reject (
251109 node ,
0 commit comments