@@ -92,6 +92,20 @@ def _is_tosa_dialect_op(target) -> bool:
9292 or "<EdgeOpOverload: tosa." in target_str
9393 )
9494
95+ @staticmethod
96+ def _has_real_tosa_dialect_impl (target ) -> bool :
97+ schema = getattr (target , "_schema" , None )
98+ op_name = getattr (schema , "name" , None )
99+ if op_name is None :
100+ return False
101+
102+ try :
103+ return torch ._C ._dispatch_has_kernel_for_dispatch_key (
104+ op_name , "CompositeExplicitAutograd"
105+ )
106+ except RuntimeError :
107+ return False
108+
95109 @staticmethod
96110 def _arg_contains_symbolic_shape (arg ) -> bool :
97111 if isinstance (arg , torch .fx .Node ):
@@ -197,19 +211,31 @@ def resolve_arg(arg, arg_index=None):
197211
198212 return True
199213
214+ def maybe_delete (self , input_nodes_to_maybe_delete ):
215+ for input_node in input_nodes_to_maybe_delete :
216+ if input_node .meta .get ("is_input" , False ):
217+ # Never delete submodule inputs, they need to match the parameters from the outer module.
218+ continue
219+ if len (input_node .users ) == 0 :
220+ self ._delete_constant_placeholder (input_node )
221+
200222 def call (self , graph_module ):
201223 modified = False
202224 input_nodes_to_maybe_delete = set ()
203225 for node in graph_module .graph .nodes :
204226 if node .op != "call_function" :
205227 continue
206- # Don't fuse TOSA dialect ops as they do not have eager forward functions.
207- # Also don't fuse ops whose explicit args/kwargs include symbolic shape values.
208- if (
209- self ._is_tosa_dialect_op (node .target )
210- or self ._arg_contains_symbolic_shape (node .args )
211- or self ._arg_contains_symbolic_shape (node .kwargs )
212- ):
228+ if node .target == exir_ops .backend .tosa .RESCALE .default :
229+ # Leave fusing of RESCALES to the compiler.
230+ continue
231+ if self ._is_tosa_dialect_op (
232+ node .target
233+ ) and not self ._has_real_tosa_dialect_impl (node .target ):
234+ continue
235+ # Don't fuse ops whose explicit args/kwargs include symbolic shape values.
236+ if self ._arg_contains_symbolic_shape (
237+ node .args
238+ ) or self ._arg_contains_symbolic_shape (node .kwargs ):
213239 continue
214240
215241 input_nodes = node .all_input_nodes
@@ -241,10 +267,7 @@ def call(self, graph_module):
241267
242268 if modified :
243269 graph_module .graph .eliminate_dead_code ()
244- for input_node in input_nodes_to_maybe_delete :
245- if len (input_node .users ) == 0 :
246- self ._delete_constant_placeholder (input_node )
247-
270+ self .maybe_delete (input_nodes_to_maybe_delete )
248271 graph_module = super ().call (graph_module ).graph_module
249272
250273 return PassResult (graph_module , modified )
0 commit comments