
     NghJ                         d dl mZ d dlmZmZ d dlmZ d dlmZm	Z	 d dl
mZ  ee          Z G d de          Z G d d	e          Z G d
 de          ZdS )    )	getLogger)DictList)Fusion)TensorProtohelper)	OnnxModelc                   4     e Zd Zdef fdZdedefdZ xZS )FusionLayerNormalizationmodelc                 N    t                                          |dd           d S NLayerNormalization
ReduceMeansuper__init__selfr   	__class__s     e/var/www/html/ai-engine/env/lib/python3.11/site-packages/onnxruntime/transformers/fusion_layernorm.pyr   z!FusionLayerNormalization.__init__   &     4lCCCCC    input_name_to_nodesoutput_name_to_nodec           	         g }| j                             ||          }t          |          dk    st          |          dk    rdS |j        d         }|d         j        dk    s|d         j        d         |k    rdS t          |          dk    r*|d         j        dk    s|d         j        d         |k    rdS d}|D ]N}| j                             |d|d          }	| j                             |d	dgg 
          }
|	|	}D|
|
d         }O|dS | j                             |g dg dfg dg dfg|          \  }}}|dk     rdS |d         }||vrdS |d         }| j                             |          \  }}||dk    s|dk    rt          
                    d|            dS |d         }| j                             |d          dk    rdS ||j        d                  d         }|j        d	k    r/|                    |           ||j        d                  d         }n|}|j        dk    rdS ||j        d                  d         }|j        dk    rdS |                    |           |                    |           |                    |dd                    |                    |||g           | j                             ||j        ||          st          
                    d           dS |j        d	k    r|n|}|j        d| j                             |j        d         |          z
           }| j                             |dd          sdS |j        d| j                             |j        d         |          z
           }| j                             |dd          sdS | j                            |           t'          j        d|j        d         ||g|j        d         g| j                             dd                    }|j                            t'          j        dt1          |                    g           | j                            |           | j        | j        |j        <   dS )a  
        Fuse Layer Normalization subgraph into one node LayerNormalization:
              +----------------------+
              |                      |
              |                      v
          [Root] --> ReduceMean -->  Sub  --> Pow --> ReduceMean --> Add --> Sqrt --> Div --> Mul --> Add
                     (axis=2 or -1)  |      (Y=2)   (axis=2 or -1)  (E-6 or E-12 or 0)    ^
                                     |                                               |
                                     +-----------------------------------------------+

         It also handles cases of duplicated sub nodes exported from older version of PyTorch:
              +----------------------+
              |                      v
              |           +-------> Sub-----------------------------------------------+
              |           |                                                           |
              |           |                                                           v
          [Root] --> ReduceMean -->  Sub  --> Pow --> ReduceMean --> Add --> Sqrt --> Div  --> Mul --> Add
              |                      ^
              |                      |
              +----------------------+
        r      NSub   DivF	recursiveCast)excludeSqrtAddr   Powr   r   r   r   r   r   )r'   r(   r   r)   r#   r   )r   r   r   r   r   r   -C6?Hskip SkipLayerNormalization fusion since epsilon value is not expected:           @Mulr(   4It is not safe to fuse LayerNormalization node. Skiplayernorm weightlayernorm biasr   	LayerNormname_prefixinputsoutputsnameepsilon)r   get_childrenleninputop_typefind_first_child_by_typematch_child_pathmatch_parent_pathsget_constant_inputloggerdebugfind_constant_inputoutputappendextendis_safe_to_fuse_nodesinput_index$is_constant_with_specified_dimensionnodes_to_remover   	make_nodecreate_node_name	attributemake_attributefloatnodes_to_addthis_graph_namenode_name_to_graph_namer9   )r   noder   r   subgraph_nodeschildren
root_inputdiv_nodechild
div_node_1
div_node_2path_idparent_nodes_sub_nodesecond_add_nodei
add_weightpow_node	temp_nodemul_nodelast_add_nodenode_before_weightweight_input
bias_inputnormalize_nodes                             r   fusezFusionLayerNormalization.fuse   s   , :**41DEEx==AX!2!2FZ]
A;%''8A;+<Q+?:+M+MFx==A{"e++x{/@/Cz/Q/Q 
	* 
	*E<<UEK^jo<ppJ 44UVUOUW4XXJ%%'%b>F#':#@#@<<<oooNDDDFXFXFXY  $
 $
 q Q;;F#8##F&q/
55oFF:qJ4G4GLLpdnppqqqF?:))(C88A==F'(:;A>	&&!!),,,*9+;A+>?BHH !Hu$$F+HOA,>?B E))Fd###h'''l3B3/000}hABBBz// 	
 
 	 LLOPPPF)2):f)D)DXX)~a$**@*@ASAZ[\A]_g*h*h&hiz>>|QPbcc 	F"(TZ-C-CHOTUDVXe-f-f)fg
z>>z1N^__ 	F##N333) JqM<<")!,-,,-A{,[[	
 
 
 	 '')>y%PZJ[J[)\)\(]^^^  000<@<P$^%8999r   __name__
__module____qualname__r	   r   r   rl   __classcell__r   s   @r   r   r      s        Di D D D D D D|Qd |Q |Q |Q |Q |Q |Q |Q |Q |Qr   r   c                   X     e Zd Zdef fdZd Zddedee         fdZ	de
d	e
fd
Z xZS )FusionLayerNormalizationNCHWr   c                 N    t                                          |dd           d S r   r   r   s     r   r   z%FusionLayerNormalizationNCHW.__init__   r   r   c                    | j                             |          }|"t                              | d| d           d S t	          |j                  dk    s"|j        d         dk    s|j        d         dk    r)t                              | d| d|j                    d S |                    |j        d         g          S )N z is not initializer.r-   r   r   z* shall have 3 dimensions Cx1x1. Got shape r   )r   get_constant_valuerC   rD   r<   shapereshape)r   output_namedescriptionvalues       r   get_weight_or_biasz/FusionLayerNormalizationNCHW.get_weight_or_bias   s    
--k::=LLKKK+KKKLLL4u{q  EKNa$7$75;q>Q;N;NLLKnn+nnafalnnooo4}}ek!n-...r   N
input_namepermc                     | j                             d          }||dz   dz   |z   }t          j        d|g|g|          }|j                            t          j        d|          g           |S )z&Append a Transpose node after an input	TransposeN_out-r6   r   )r   rN   r   rM   rO   rH   rP   )r   r   r   r{   	node_nametranspose_nodes         r   create_transpose_nodez2FusionLayerNormalizationNCHW.create_transpose_node   s~    J//<<	#f,s2Z?K)+zlU`Tahqrrr '')>vt)L)L(MNNNr   r   r   c                 j
   t          j        |d          }t          |t                    r|dgk    rdS g }| j                            ||          }t          |          dk    rdS |j        d         }|d         j        dk    s|d         j        d         |k    rdS |d         }| j        	                    |d|d          }	|	dS | j        
                    |	g d	g d
|          }
|
dS |
\  }}}}}||k    rdS | j                            |          \  }}||dk    s|dk    rt                              d|            dS t          j        |d          }t          |t                    sJ |dgk    rdS | j                            |d          dk    rdS ||	j        d                  d         }|}|j        dk    rdS ||j        d                  d         }|j        dk    rdS |                    |           |                    |
           |                    |||	g           | j                            ||j        ||          st                              d           dS |j        dk    r|	n|}|j        d| j                            |j        d         |          z
           }|                     |d          }|dS |j        d| j                            |j        d         |          z
           }|                     |d          }|dS t+          j        |dz   t.          j        |j        |          }t+          j        |dz   t.          j        |j        |          }| j                            || j                   | j                            || j                   | j                            |           |                     |j        d         g d          }| j                            dd          }|                     |dz   g d|j        d                   }t+          j        d|j        d         |dz   |dz   g|dz   g|          }|j                             t+          j!        dtE          |                    g           | j#                            |           | j#                            |           | j#                            |           | j        | j$        |j%        <   | j        | j$        |j%        <   | j        | j$        |j%        <   d} | &                    |            dS )a*  
        Fuse Layer Normalization subgraph into one node LayerNormalization:
              +----------------------+
              | NxCxHxW              |
              |                      v                                                     (Cx1x1)  (Cx1x1)
          [Root] --> ReduceMean -->  Sub --> Pow --> ReduceMean --> Add --> Sqrt --> Div --> Mul --> Add -->
                     (axes=1)        |      (Y=2)     (axes=1)     (E-6)             ^
                                     |                                               |
                                     +-----------------------------------------------+

        Fused subgraph:
                       (0,2,3,1)                            (0,3,1,2)
            [Root] --> Transpose --> LayerNormalization --> Transpose -->
        axesr   Nr   r   r    Fr!   r&   r*   r+   r,   r.   r/   r(   r0   r#   r1   r2   _NHWC)r   r   r-   r   r   r3   r4   	_out_nhwc)r   r-   r   r   r6   r:   zLayerNormalization(NHWC))'r	   get_node_attribute
isinstancelistr   r;   r<   r=   r>   r?   match_parent_pathrB   rC   rD   rE   rF   rG   rH   rI   rJ   r~   r   make_tensorr   FLOATry   add_initializerrS   rL   r   rN   rM   rO   rP   rQ   rR   rT   r9   increase_counter)!r   rU   r   r   r   rV   rW   rX   subrY   r^   
_sqrt_nodera   reduce_mean_noderd   r`   rb   rc   re   rf   rg   rh   ri   weightrj   biasweight_nhwc	bias_nhwctranspose_inputlayernorm_node_nametranspose_outputrk   counter_names!                                    r   rl   z!FusionLayerNormalizationNCHW.fuse   s    +D&994&& 	4A3;;F:**41DEEx==AFZ]
A;%''8A;+<Q+?:+M+MFqk:66sECVbg6hhFz33777OO	
 
 FLXI
O%5x(??F
55oFF:qJ4G4GLLpdnppqqqF+,<fEE$%%%%%A3;;F:))(C88A==F'(:;A>	u$$F+HOA,>?B E))Fd###l+++}hABBBz// 	
 
 	 LLOPPPF)2):f)D)DXX)~a$**@*@ASAZ[\A]_g*h*h&hi((7IJJ>F"(TZ-C-CHOTUDVXe-f-f)fg
&&z3CDD<F()?ARTZT`bhii&zG';[=NPVP\^dee	
"";0DEEE
""9d.BCCC##N33344TZ]LLLQQ"j99:N\g9hh55+-|||]=QRS=T
 
  ) #*1-|g/EzT[G[\(;67$	
 
 
 	 '')>y%PZJ[J[)\)\(]^^^  111  000  !1222=A=Q$_%9:<@<P$^%89>B>R$%5%:;1l+++++r   )N)rn   ro   rp   r	   r   r~   strr   intr   r   rl   rq   rr   s   @r   rt   rt      s        Di D D D D D D
/ 
/ 
/
 
 
49 
 
 
 
},d }, }, }, }, }, }, }, }, },r   rt   c                   4     e Zd Zdef fdZdedefdZ xZS )FusionLayerNormalizationTFr   c                 P    t                                          |ddd           d S )Nr   r(   TFr   r   s     r   r   z#FusionLayerNormalizationTF.__init__/  s(     4eTBBBBBr   r   r   c                 T   g }| j                             |g dg dfg dg dfg|          \  }}}|dS t          |          dk    sJ |d         dv r|d	         dv r
|d
         dv st                              d           dS |dd         \  }}}	}
}}|dd         \  }}}}d}t          |          dk    r|d         }|j        dk    sJ | j                             |dd|          }|t                              d           dS | j                             |d|          }||n| j                             |d|          }|t                              d           dS | j                             |          \  }}||dk    s|dk    r|t                              d           dS |D|j	        d         |j	        vs|j	        d         |j	        vrt                              d           dS |D|j	        d         |j	        vs|j	        d         |j	        vrt                              d           dS |j	        d         |j	        d	         k    rt                              d           dS ||||	|
|||||||g}|S| j                             |dd|          }|t                              d           dS |
                    |||g           | j                             ||j        | j                                         | j                                                   st                              d           dS | j        
                    |           |	j	        d	         }|j	        d         }t!          j        d|j	        d         ||g|j        d         g| j                             dd                    }|j        
                    t!          j        dt+          |                    g           | j                            |           | j        | j        |j        <   dS )aU  
         Layer Norm from Tensorflow model(using keras2onnx or tf2onnx):
          +------------------------------------+
          |                                    |
          |                                    |
        (Cast_1)                               |
          |                                    |
          |                                    v                                           (B)                             (B)             (A)
         Add --> (Cast_1) --> ReduceMean -->  Sub  --> Mul --> ReduceMean --> (Cast_3) --> Add --> Sqrt --> Reciprocol --> Mul --> Mul --> Sub --> Add
          |                       |                                                                                         |       ^              ^
          |                       |                                                                                         |       |              |
          |                       +--------------------------------------------------(Cast_2)-------------------------------|-------+              |
          |                                                                                                                 v                      |
          +---------------------------------------------------------------------------------------------------------------> Mul--------------------+
        )
r   r/   r/   
Reciprocalr'   r(   r   r/   r   r   )
r   r   Nr   r   r   Nr   r   N)r   r/   r/   r   r'   r(   r#   r   r/   r   r   )r   r   Nr   r   r   r   Nr   r   NNr-   r   )r   r   r   r   z=return indice is exepected in [0, 1], but got {return_indice}      r#   r/   zmul_node_3 not foundzroot node is nonegh㈵>zepsilon is not matchedz;reduce_mean_node_1 and mul_node_3 shall link from root nodez%mul_node_2 shall have two same inputszcast_node_2 not foundz$not safe to fuse layer normalizationr   r3   r4   r6   r:   )r   rA   r<   rC   rD   r>   match_parent
get_parentrB   r=   rH   rI   rF   r   r   rL   r   rM   rN   rO   rP   rQ   rR   rG   rS   rT   r9   )r   rU   r   r   return_indicer_   r^   
sub_node_0
mul_node_0
mul_node_1reciprocol_node	sqrt_node
add_node_0reduce_mean_node_0
mul_node_2
sub_node_1reduce_mean_node_1cast_node_3
mul_node_3node_before_reduce	root_noderb   r:   rV   cast_node_2ri   rj   
fused_nodes                               r   rl   zFusionLayerNormalizationTF.fuse2  s     )-)F)F   <;;    ?>>! B  G$*
 $*
&<L F=!!Q&&&&a F**}Q/?6/I/Im\]N^bhNhNhLLXYYYF !	
IUVXVYVYIZFJ
4F|""&q/K&&0000Z,,T5!=PQQ
LL/000F!Z223EqJ]^^ " &&'91>QRR 	
 LL,---FZ22:>>
7?gllw/?/?KDWLL1222F$Q'z/???CUC[\]C^fpfvCvCvLLVWWWF"$Q'z/???CUC[\]C^fpfvCvCvLLVWWWFA*"21"555LL@AAAF 
 "*11*faI\]]K"4555!!#5{K"PQQQz//KJ**,,J**,,	
 
 	 LL?@@@F##N333!'*%a(
 % $Q'zB[^$,,-A{,[[	
 
 

 	##V%:9eGnn%U%U$VWWW  ,,,8<8L$Z_555r   rm   rr   s   @r   r   r   .  s        Ci C C C C C C_Md _M _M _M _M _M _M _M _M _Mr   r   N)loggingr   typingr   r   fusion_baser   onnxr   r   
onnx_modelr	   rn   rC   r   rt   r    r   r   <module>r      s2  
                     $ $ $ $ $ $ $ $            	8		@Q @Q @Q @Q @Qv @Q @Q @QFY, Y, Y, Y, Y,6 Y, Y, Y,xcM cM cM cM cM cM cM cM cM cMr   