
    ghJ                         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y)    )	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                 (    t         |   |dd       y NLayerNormalization
ReduceMeansuper__init__selfr   	__class__s     ^/var/www/openai/venv/lib/python3.12/site-packages/onnxruntime/transformers/fusion_layernorm.pyr   z!FusionLayerNormalization.__init__        4lC    input_name_to_nodesoutput_name_to_nodec           	         g }| j                   j                  ||      }t        |      dk(  st        |      dkD  ry|j                  d   }|d   j                  dk7  s|d   j                  d   |k7  ryt        |      dk(  r(|d   j                  dk7  s|d   j                  d   |k7  ryd}|D ]N  }| j                   j                  |d|d      }	| j                   j                  |d	dgg 
      }
|	|	}G|
J|
d   }P |y| j                   j                  |g dg dfg dg dfg|      \  }}}|dk  ry|d   }||vry|d   }| j                   j                  |      \  }}|
|dk  s|dkD  rt        j                  d|        y|d   }| j                   j                  |d      dk7  ry||j                  d      d   }|j                  d	k(  r'|j                  |       ||j                  d      d   }n|}|j                  dk7  ry||j                  d      d   }|j                  dk7  ry|j                  |       |j                  |       |j                  |dd        |j                  |||g       | j                   j                  ||j                  ||      st        j                  d       y|j                  d	k7  r|n|}|j                  d| j                   j!                  |j                  d   |      z
     }| j                   j#                  |dd      sy|j                  d| j                   j!                  |j                  d   |      z
     }| j                   j#                  |dd      sy| j$                  j                  |       t'        j(                  d|j                  d   ||g|j                  d   g| j                   j+                  dd            }|j,                  j                  t'        j.                  dt1        |            g       | j2                  j                  |       | j4                  | j6                  |j8                  <   y)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x=AX!2ZZ]
A;%'8A;+<+<Q+?:+Mx=A{""e+x{/@/@/Cz/QE<<UEK^jo<pJ 44UVUOUW4XJ%%'%b>  #'::#@#@<oNDFXY  $
 q Q;#8#&q/

55oF:qJ4GLLcdncopq?::))(C8A='(:;A>	&!!),*9+;+;A+>?BH !Hu$+HOOA,>?B  E)d#h'l3B/0}hABzz//  	
 LLOP)2):):f)DX)~~a$***@*@ASAZAZ[\A]_g*h&hizz>>|QPbc"((TZZ-C-CHOOTUDVXe-f)fg
zz>>z1N^_##N3)) JJqM<<"))!,-,,-A{,[	
 	  '')>)>y%PZJ[)\(]^  0<@<P<P$$^%8%89r   __name__
__module____qualname__r	   r   r   rl   __classcell__r   s   @r   r   r      s*    Di D|Qd |Q |Qr   r   c                   R     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                 (    t         |   |dd       y r   r   r   s     r   r   z%FusionLayerNormalizationNCHW.__init__   r   r   c                 z   | j                   j                  |      }|t        j                  | d| d       y t	        |j
                        dk7  s$|j
                  d   dk7  s|j
                  d   dk7  r(t        j                  | d| d|j
                          y |j                  |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=+6JKLu{{q EKKNa$75;;q>Q;NLLK=+6`afalal`mno}}ekk!n-..r   
input_namepermc                     | j                   j                  d      }||dz   dz   |z   }t        j                  d|g|g|      }|j                  j                  t        j                  d|      g       |S )z&Append a Transpose node after an input	Transpose_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   sw    JJ//<	#f,s2Z?K))+zlU`Tahqr  '')>)>vt)L(MNr   r   r   c                 
   t        j                  |d      }t        |t              r|dgk7  ryg }| j                  j                  ||      }t        |      dk7  ry|j                  d   }|d   j                  dk7  s|d   j                  d   |k7  ry|d   }| j                  j                  |d|d      }	|	y| j                  j                  |	g d	g d
|      }
|
y|
\  }}}}}||k7  ry| j                  j                  |      \  }}|
|dk  s|dkD  rt        j                  d|        yt        j                  |d      }t        |t              sJ |dgk7  ry| j                  j                  |d      dk7  ry||	j                  d      d   }|}|j                  dk7  ry||j                  d      d   }|j                  dk7  ry|j!                  |       |j#                  |
       |j#                  |||	g       | j                  j%                  ||j                  ||      st        j                  d       y|j                  dk7  r|	n|}|j                  d| j                  j'                  |j                  d   |      z
     }| j)                  |d      }|y|j                  d| j                  j'                  |j                  d   |      z
     }| j)                  |d      }|yt+        j,                  |dz   t.        j0                  |j2                  |      }t+        j,                  |dz   t.        j0                  |j2                  |      }| j                  j5                  || j6                         | j                  j5                  || j6                         | j8                  j#                  |       | j;                  |j                  d   g d      }| j                  j=                  dd      }| j;                  |dz   g d|j                  d         }t+        j>                  d|j                  d   |dz   |dz   g|dz   g|      }|j@                  j#                  t+        jB                  dtE        |            g       | jF                  j!                  |       | jF                  j!                  |       | jF                  j!                  |       | j6                  | jH                  |jJ                  <   | j6                  | jH                  |jJ                  <   | j6                  | jH                  |jJ                  <   d} | jM                  |        y)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4&4A3;::**41DEx=AZZ]
A;%'8A;+<+<Q+?:+Mqk::66sECVbg6hzz337	
 LXI
O%5x(?

55oF:qJ4GLLcdncopq++,<fE$%%%A3;::))(C8A='(:;A>	u$+HOOA,>?B  E)d#l+}hABzz//  	
 LLOP)2):):f)DX)~~a$***@*@ASAZAZ[\A]_g*h&hi((7IJ>"((TZZ-C-CHOOTUDVXe-f)fg
&&z3CD<(()?ARARTZT`T`bhi&&zG';[=N=NPVP\P\^de	

"";0D0DE

""9d.B.BC##N344TZZ]LQ"jj99:N\g9h55+-|]=Q=QRS=T
  )) #**1-|g/EzT[G[\(;67$	
 	  '')>)>y%PZJ[)\(]^  1  0  !12=A=Q=Q$$_%9%9:<@<P<P$$^%8%89>B>R>R$$%5%:%:;1l+r   )N)rn   ro   rp   r	   r   r~   strr   intr   r   rl   rq   rr   s   @r   rt   rt      sC    Di 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                 *    t         |   |ddd       y )Nr   r(   TFr   r   s     r   r   z#FusionLayerNormalizationTF.__init__/  s     4eTBr   r   r   c                 ,   g }| j                   j                  |g dg dfg dg dfg|      \  }}}|yt        |      dk(  sJ |d   dv r|d	   dv r|d
   dv st        j	                  d       y|dd \  }}}	}
}}|dd \  }}}}d}t        |      dk(  r|d   }|j
                  dk(  sJ | j                   j                  |dd|      }|t        j	                  d       y| j                   j                  |d|      }||n| j                   j                  |d|      }|t        j	                  d       y| j                   j                  |      \  }}||dk  s|dkD  r|t        j	                  d       y|L|j                  d   |j                  vs|j                  d   |j                  vrt        j	                  d       y|L|j                  d   |j                  vs|j                  d   |j                  vrt        j	                  d       y|j                  d   |j                  d	   k7  rt        j	                  d       y||||	|
|||||||g}|J| j                   j                  |dd|      }|t        j	                  d       y|j                  |||g       | j                   j                  ||j                  | j                   j                         | j                   j                               st        j	                  d       y| j                  j                  |       |	j                  d	   }|j                  d   }t!        j"                  d|j                  d   ||g|j                  d   g| j                   j%                  dd            }|j&                  j                  t!        j(                  dt+        |            g       | j,                  j/                  |       | j0                  | j2                  |j4                  <   y)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  sG     )-)F)F <  ?! B  G$*
&<L =!Q&&&a F*}Q/?6/Im\]N^bhNhLLXY !	
IUVXVYIZFJ
4F|"&q/K&&&000ZZ,,T5!=PQ
LL/0!ZZ223EqJ]^ " &&'91>QR 	
 LL,-ZZ22:>
7?glw/?KDWLL12$$Q'z/?/??CUC[C[\]C^fpfvfvCvLLVW"$$Q'z/?/??CUC[C[\]C^fpfvfvCvLLVWA*"2"21"55LL@A 
 "**11*faI\]K"45!!#5{K"PQzz//KKJJ**,JJ**,	
 LL?@##N3!''*%%a(
 %% $$Q'zB[[^$,,-A{,[	

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