
    h(                    F    S SK Jr  S SKrSSKJr  SSKJr   " S S\5      rg)	    )annotationsN   )	ONNXModel   )Fusionc                     ^  \ rS rSrSU 4S jjr      S	S jr        S
S jr        S
S jr        S
S jrSr	U =r
$ )
FusionGelu   c                (   > [         TU ]  USS5        g )NGeluErf)super__init__)selfmodel	__class__s     f/var/www/fran/franai/venv/lib/python3.13/site-packages/onnxruntime/quantization/fusions/fusion_gelu.pyr   FusionGelu.__init__   s    .    c                    U R                  XU5      (       d.  U R                  XU5      (       d  U R                  XU5      (       a  U R                  R	                  SS5        gg)zg
Interface function that tries to fuse a node sequence containing an Erf node into a single
Gelu node.
com.microsoftr   N)fuse_1fuse_2fuse_3r   set_opset_import)r   erf_nodeinput_name_to_nodesoutput_name_to_nodes       r   fuseFusionGelu.fuse   sT     KK7JKK{{8:MNN{{8:MNNJJ''; Or   c                   UR                   S   U;  a  gX!R                   S      n[        U5      S:w  d  US   R                  S:w  a  gUS   nU R                  US5      (       d  gUR                   S   U;  a  gX%R                   S      n[        U5      S:w  d  US   R                  S:w  a  gUS   nU R	                  USSU5      nUc  gU R                  USSS	9S:w  a  gUR                  S   nUR                  S   UR                   S   :X  a  SOSn	XR                  U	   :X  aa  X&R                   S      n[        U5      S:w  d  US   R                  S:w  a  gUS   n
U R                  U
S
5      (       d  gU
R                   S   nONU R	                  USX5      n
U
c  gU R                  U
S
5      (       d  gXR                  ;  a  gUR                   S   nXqXVU
/nU R                  X/X#5      (       d  gU R                  R                  U5        [        R                  R                  SU R                  5       U/U/S9nSUl        U R                  R!                  U5        g)a  
This pattern is from PyTorch model
Fuse Gelu with Erf into one node:
Pattern 1:
               +-------Mul(0.5)---------------------+
               |                                    |
               |                                    v
            [root] --> Div -----> Erf  --> Add --> Mul -->
                      (B=1.4142...)       (1)

Pattern 2:
               +------------------------------------+
               |                                    |
               |                                    v
            [root] --> Div -----> Erf  --> Add --> Mul -->Mul -->
                      (B=1.4142...)       (1)            (0.5)

Note that constant input for Add and Mul could be first or second input: like either A=0.5 or B=0.5 is fine.
r   Fr   AddMulDiv-?MbP?delta      ?r   nameinputsoutputsr   Toutputlenop_typehas_constant_inputmatch_parentfind_constant_inputinputis_safe_to_fuse_nodesnodes_to_removeextendonnxhelper	make_nodecreate_unique_node_namedomainnodes_to_addappend)r   r   r   r   childrenadd_after_erfmul_after_erfdivsubgraph_inputanothermul_halfsubgraph_outputsubgraph_nodes
fused_nodes                 r   r   FusionGelu.fuse_1#   sw   2 ??1%88&q'9:x=A!!4!4!= &&}a88"*==&';';A'>?x=A!!4!4!= %4GH;##Cu#=B1$**1-1E1Ea1HH!a0099*+?+?+BCH8}!Xa[%8%8E%A{H**8S99&ooa0O((w\H**8S99^^3+2215OxP)).:KM`vv##N3[[**557@P[jZk + 

 ,
  ,r   c                   UR                   S   U;  a  gX!R                   S      n[        U5      S:w  d  US   R                  S:w  a  gUS   nU R                  US5      (       d  gUR                   S   U;  a  gX%R                   S      n[        U5      S:w  d  US   R                  S:w  a  gUS   nU R                  US5      (       d  gUR                   S   U;  a  gX&R                   S      n[        U5      S:w  d  US   R                  S:w  a  gUS   nU R	                  USSU5      nUc  gSn	U R                  US	S
S9S:w  a0  U R	                  USSU5      n	U	c  gU R                  U	S5      (       d  gUR                  S   n
XR                  ;  a  gXXVU/nU	(       a  UR                  U	5        U R                  XR                   S   /X#5      (       d  gU R                  R                  U5        [        R                  R                  SU R                  5       U
/UR                   S   /S9nSUl        U R                   R                  U5        g)a  
This pattern is from Keras model
Fuse Gelu with Erf into one node:
               +------------------------------------------+
               |                                          |
               |                                          v
            [root] --> Div -----> Erf  --> Add --> Mul -->Mul
                      (B=1.4142...)       (A=1)   (A=0.5)

Note that constant input for Add and Mul could be first or second input: like either A=0.5 or B=0.5 is fine.
r   Fr   r"   r#   r)   r$   Nr%   r&   r'   Sqrtg       @r   r*   r   T)r/   r0   r1   r2   r3   r4   r5   r?   r6   r7   r8   r9   r:   r;   r<   r=   r>   )r   r   r   r   r@   rA   rB   mulrC   	sqrt_noderD   rH   rI   s                r   r   FusionGelu.fuse_2z   sd   " ??1%88&q'9:x=A!!4!4!= &&}a88"*==&';';A'>?x=A!!4!4!= &&}c::"*==&';';A'>?x=A!!4!4!=qk%4GH;	##Cu#=B))#vq:MNI **9c::1*sK!!),)).::a=/K^tt##N3[[**557@P[^[e[efg[hZi + 

 ,
  ,r   c                V   UR                   S   U;  a  gX!R                   S      n[        U5      S:w  d  US   R                  S:w  a  gUS   nU R                  US5      (       d  gUR                   S   U;  a  gX%R                   S      n[        U5      S:w  d  US   R                  S:w  a  gUS   nU R                  US5      (       d  gU R	                  USSU5      nUc  gU R                  USSS	9nUS:  a  gSU-
  n	UR                  U	   n
UR                   S   U;  a  gX&R                   S      n[        U5      S:w  d  US   R                  S:w  a  gUS   nUR                  S   U
:X  d  UR                  S   U
:X  d  gXqXVU/nU R                  UUR                   S   /UU5      (       d  gU R                  R                  U5        [        R                  R                  S
U R                  5       U
/UR                   S   /S9nSUl        U R                  R!                  U5        g)a  
This pattern is from TensorFlow model
Fuse Gelu with Erf into one node:
               +----------------------------------------------+
               |                                              |
               |                                              v
            [root] --> Mul -----> Erf    -->   Add --> Mul -->Mul
                       (A=0.7071067690849304)  (B=1)  (B=0.5)

Note that constant input for Add and Mul could be first or second input: like either A=0.5 or B=0.5 is fine.
r   Fr   r"   r#   r)   g   `?r&   r'   r   r*   r   Tr.   )r   r   r   r   r@   rA   rF   	first_muliroot_input_indexrD   last_mulrH   rI   s                 r   r   FusionGelu.fuse_3   sO   $ ??1%88&q'9:x=A!!4!4!= &&}a88"*==&';';A'>?x=A!!4!4!=A;&&x55%%hq:MN	$$Y0B%$Pq5q5")9:??1%88&q'9:x=A!!4!4!=A;q!^3x~~a7HN7Z#}Q))__Q 	
 
 ##N3[[**557@P[c[j[jkl[mZn + 

 ,
  ,r    )r   r   )r   onnx.NodeProtor   dict[str, list[onnx.NodeProto]]r   dict[str, onnx.NodeProto])r   rW   r   rX   r   rY   returnbool)__name__
__module____qualname____firstlineno__r   r   r   r   r   __static_attributes____classcell__)r   s   @r   r	   r	      s    /< < =< 7	<"U U =U 7	U
 
UnJ J =J 7	J
 
JXJ J =J 7	J
 
J Jr   r	   )
__future__r   r9   
onnx_modelr   fusionr   r	   rV   r   r   <module>re      s!    #  " B Br   