
    g3                    F    d dl mZ d dlZddlmZ ddlmZ  G d de      Zy)	    )annotationsN   )	ONNXModel   )Fusionc                  4     e Zd Zd fdZ	 	 	 	 	 	 ddZ xZS )FusionLayerNormalizationc                (    t         |   |dd       y )NLayerNormalization
ReduceMean)super__init__)selfmodel	__class__s     f/var/www/openai/venv/lib/python3.12/site-packages/onnxruntime/quantization/fusions/fusion_layernorm.pyr   z!FusionLayerNormalization.__init__   s     4lC    c                h   | 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 ]  }| j                  |d|d      }| n |y| j                  |g d	g d
fg dg dfg|      \  }}	}
|dk  ry|	d   }||vry|	d   }| j                  |      \  }}|
|dk  s|dkD  ry|	d   }| j                  |d      dk7  ry||j                  d      d   }|j                  dk7  ry||j                  d      d   }|j                  dk7  ry|g}|j                  |       |j                  |	dd        |j                  |||g       | j                  ||j                  ||      sy|j                  d| j                  |j                  d   |      z
     }| j                  |d      sy|j                  d| j                  |j                  d   |      z
     }| j                  |d      sy| j                  j                  |       t        j                   j#                  d| j%                         |j                  d   ||g|j                  d   g      }|j&                  j                  t        j                   j)                  dt+        |            g       | j,                  j/                  |       y)a  
        Interface function that tries to fuse a node sequence containing a ReduceMean node into a single
        LayerNormalization node.

              +----------------------+
              |                      |
              |                      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   r   NSubr   DivF)	recursive)SqrtAddr   Powr   )r   r   r   r   r   )r   r   r   r   Castr   )r   r   r   r   r   r   g-C6?   g       @Mulr   r   )nameinputsoutputsepsilon)r   get_childrenleninputop_typefind_first_child_by_typematch_parent_pathsget_constant_inputfind_constant_inputoutputextendis_safe_to_fuse_nodesinput_indexis_constant_with_specified_ranknodes_to_removeonnxhelper	make_nodecreate_unique_node_name	attributemake_attributefloatnodes_to_addappend)r   reduce_mean_nodeinput_name_to_nodesoutput_name_to_nodechildren
root_inputdiv_nodechildpath_idparent_nodes_sub_nodesecond_add_nodei
add_weightpow_nodemul_nodelast_add_nodesubgraph_nodesweight_input
bias_inputnormalize_nodes                         r   fusezFusionLayerNormalization.fuse   sj   < ::**+;=PQx=AX!2%++A.
A;%'8A;+<+<Q+?:+Mx=A{""e+x{/@/@/Cz/QE44UECVbg4hH#  #'#:#:<oNG&  
$
 q Q;#8#&q///@:qJ4G?##Hc2a7&xq'9:1=u$+HOOA,>?B  E)*+h'l3B/0}hAB))  	
 ~~a$*:*:8??1;Mx*X&XY33L!D"((T-=-=hooa>PR_-`)`a
33JB##N3.. --/$**1-|ZH"))!,-	 / 
 	  '')C)CIuU_O`)a(bc  0r   )r   r   )r:   zonnx.NodeProtor;   zdict[str, list[onnx.NodeProto]]r<   zdict[str, onnx.NodeProto])__name__
__module____qualname__r   rO   __classcell__)r   s   @r   r	   r	      s.    Du1(u1 =u1 7	u1r   r	   )
__future__r   r1   
onnx_modelr   fusionr   r	    r   r   <module>rX      s!    #  " y1v y1r   