
    fPiO                         d dl 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)Fusion)TensorProtohelper)	OnnxModelc                   >     e Zd Zd
dededef fdZdedefd	Z xZS )FusionLayerNormalizationTFmodelcheck_constant_and_dimensionforcec                 j    t                                          |dd           || _        || _        d S NLayerNormalization
ReduceMean)super__init__r   r   )selfr
   r   r   	__class__s       }/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/onnxruntime/transformers/fusion_layernorm.pyr   z!FusionLayerNormalization.__init__   s3     4lCCC,H)


    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 ]O}| j                             |d|d          }	|	|	} n*| j                             |d	dg          }
|

|
d
         } nP|dS | j                             |g dg dfg dg dfg|          \  }}}|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         |vrdS ||j        d                  }|D ]}|j        d	k    r?|                    |           |j        d         |vr3||j        d                  d         }n|}|j        dk    r[|j        d         |vrk||j        d                  d         }|j        dk    r|                    |           |                    |           |                    |dd
                    |                    |||g           |j        d	k    r|n|}|j        d| j                             |j        d         |          z
           }| j        r| j                             |dd          sW|j        d| j                             |j        d         |          z
           }| j        r| j                             |dd          s|j        d         }| j                             ||j        ||          s+| j        rd| _        n6t          
                    d           
| j                            |           t-          j        d|j        d         ||g|g| j                             dd                    }|j                            t-          j        dt7          |                    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)  (B=E-6 or E-12)    ^
                                     |                                                 |
                                     +-------------------------------------------------+

         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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$   layernorm weightlayernorm biasT4It is not safe to fuse LayerNormalization node. Skipr   	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input_indexr   $is_constant_with_specified_dimensionis_safe_to_fuse_nodesr   prune_graphnodes_to_remover   	make_nodecreate_node_name	attributemake_attributefloatnodes_to_addthis_graph_namenode_name_to_graph_namer5   )r   noder   r   subgraph_nodeschildren
root_inputdiv_nodechild
div_node_1
div_node_2_path_idparent_nodes_sub_nodeadd_eps_nodeir6   pow_nodediv_children	temp_nodemul_nodelast_add_nodenode_before_weightweight_input
bias_inputlayer_norm_output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%% "Z88PP
))"~HE * F$(J$A$A<<<oooNDDDFXFXFXY  %
 %
!, F#8##F#AZ22<@@
7?gllg.>.>LLmdkmmnnnF?:))(C88A==F?1%888F +8?1+=>% @	U @	UI F**%%i000#A&.AAA.y/?/BCAF %5((q!)<<</0BCAFM$--!!$'''!!(+++!!,ss"3444!!=(H"EFFF-6->&-H-Hi#>!dj.D.DEWE^_`Eack.l.l*lmL0 9h9ha!3: :  &,Q1G1GXYHZ\i1j1j-jkJ0 9h9hA/: :   - 4Q 7:33$##	  < : '+D$$LL!WXXX$++N;;;#-$
1|Z@*+Z001ES^0__	  N $++V-B9eT[nn-]-],^___$$^444@D@TD()<==A@	U @	Ur   )TF)	__name__
__module____qualname__r   boolr   dictrj   __classcell__r   s   @r   r	   r	      s         i t [_      
SUd SU SU SU SU SU SU SU SU SU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   r   r
   r   s     r   r   z%FusionLayerNormalizationNCHW.__init__   s&     4lCCCCCr   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_valuer?   r@   r8   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-r2   r   )r
   rK   r   rJ   rL   rD   rM   )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$   r.   r    r,   r-   _NHWC)r   r   r)   r   r   r/   r0   	_out_nhwc)r   r)   r   r   r2   r6   zLayerNormalization(NHWC))'r   get_node_attribute
isinstancelistr
   r7   r8   r9   r:   r;   match_parent_pathr>   r?   r@   rA   rB   rC   rD   rG   rE   r   r   make_tensorr   FLOATrz   add_initializerrP   rI   r   rK   rJ   rL   rM   rN   rO   rQ   r5   increase_counter)!r   rR   r   r   r   rS   rT   rU   subrV   r[   
_sqrt_nodesecond_add_nodereduce_mean_noder`   r]   r_   r6   rb   rc   rd   re   rf   weightrg   biasweight_nhwc	bias_nhwctranspose_inputlayernorm_node_nametranspose_outputri   counter_names!                                    r   rj   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Z22?CC
7?gllg.>.>LLmdkmmnnn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%PW..)Y)Y(Z[[[  111  000  !1222=A=Q$_%9:<@<P$^%89>B>R$%5%:;1l+++++r   )N)rk   rl   rm   r   r   r   strr   intr   ro   rj   rp   rq   s   @r   rs   rs      s        Di D D D D D D
/ 
/ 
/
 
 
49 
 
 
 
},d }, }, }, }, }, }, }, }, },r   rs   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$   TFru   rv   s     r   r   z#FusionLayerNormalizationTF.__init__G  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   r/   r0   r2   r6   )r
   r=   r8   r?   r@   r:   match_parent
get_parentr>   r9   rD   rG   rB   r   r   rI   r   rJ   rK   rL   rM   rN   rO   rC   rP   rQ   r5   )r   rR   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_noder_   r6   rS   cast_node_2rf   rg   
fused_nodes                               r   rj   zFusionLayerNormalizationTF.fuseJ  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   )rk   rl   rm   r   r   ro   rj   rp   rq   s   @r   r   r   F  s        Ci C C C C C C_Md _M _M _M _M _M _M _M _M _Mr   r   N)loggingr   fusion_baser   onnxr   r   
onnx_modelr   rk   r?   r	   rs   r    r   r   <module>r      s  
             $ $ $ $ $ $ $ $            	8		YU YU YU YU YUv YU YU YUx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   