1010
1111from executorch .backends .nxp .backend .data_format import DataFormat , NXP_NODE_FORMAT
1212from executorch .backends .nxp .backend .edge_helper import (
13+ input_rank ,
1314 is_channels_last_dim_order ,
1415 try_get_arg ,
1516)
2627 MaxPool2DWithIndices ,
2728 MeanDim ,
2829 PermuteCopy ,
30+ Prelu ,
2931 QuantizePerTensor ,
3032 SumDimIntList ,
3133 UpsampleBilinear2D ,
@@ -54,6 +56,11 @@ class NodeFormatInference:
5456 UpsampleNearest2D : {"inputs" : [0 ]},
5557 }
5658
59+ ops_conditionally_with_channels_first_nodes = {
60+ Prelu : {"inputs" : [0 ]},
61+ torch .ops .aten .prelu .default : {"inputs" : [0 ]},
62+ }
63+
5764 # A set of Edge Aten ops, which have the ability to change the format (for example - input nodes
5865 # are channels first but output is formatless).
5966 ops_that_can_change_tensor_format = {
@@ -64,6 +71,8 @@ class NodeFormatInference:
6471 SumDimIntList ,
6572 }
6673
74+ prelu_targets = [Prelu , torch .ops .aten .prelu .default ]
75+
6776 _type_changed_during_last_run : bool
6877
6978 # Mapping between Node and its ancestors (inputs)
@@ -160,6 +169,13 @@ def _infer_format_of_nodes(self, node: Node):
160169 f"Node format inference for node type: { op_type } not found!"
161170 )
162171
172+ elif node .target in self .prelu_targets :
173+ num_parameters_shape = tuple (node .args [1 ].meta ["val" ].shape )
174+ if input_rank (node , 0 ) > 2 and num_parameters_shape != (1 ,):
175+ self ._handle_node_which_uses_channels_first_format (node )
176+ else :
177+ self ._handle_node_which_can_use_any_node_format (node )
178+
163179 elif node .op != "call_function" or (
164180 hasattr (node , "target" ) and node .target in self ._known_targets
165181 ):
@@ -248,10 +264,14 @@ def _handle_node_which_uses_channels_first_format(self, node: Node):
248264 Function for assigning format to nodes that require channels first input (Conv, MaxPool etc.)
249265 """
250266 op_type = self ._get_node_op_type (node )
267+ ops_using_channels_first_format = (
268+ self .ops_with_channels_first_nodes
269+ | self .ops_conditionally_with_channels_first_nodes
270+ )
251271
252272 for index , ancestor_node in enumerate (self ._node_inputs [node ]):
253273 # Go through input nodes and assign them correct format
254- if index in self . ops_with_channels_first_nodes [op_type ]["inputs" ]:
274+ if index in ops_using_channels_first_format [op_type ]["inputs" ]:
255275 self ._assign_format_to_node (ancestor_node , DataFormat .CHANNELS_FIRST )
256276
257277 # We need to propagate channels first format up to already visited nodes
0 commit comments