
    h'                     Z    S SK Jr  S SKJr  S SKJr  S SKJr  \" \5      r	 " S S\5      r
g)    )	getLogger)Fusion)helper)	OnnxModelc                      ^  \ rS rSrS\4U 4S jjrS\S\4S jrS\S\S\S-  4S	 jr	S\S\S\S-  4S
 jr
S\S\S\S-  4S jrSrU =r$ )
FusionGelu   modelc                 (   > [         TU ]  USS5        g )NGeluErf)super__init__)selfr
   	__class__s     ^/var/www/fran/franai/venv/lib/python3.13/site-packages/onnxruntime/transformers/fusion_gelu.pyr   FusionGelu.__init__   s    .    input_name_to_nodesoutput_name_to_nodec                     U R                  XU5      (       a  g U R                  XU5      (       a  g U R                  XU5        g )N)fuse_1fuse_2fuse_3)r   erf_noder   r   s       r   fuseFusionGelu.fuse   s;    ;;x6IJJ;;x6IJJH3FGr   returnNc                    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                  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                  R                  USSU5      nUc  gU R                  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  ak  X&R                   S      n[        U5      S:w  d  US   R                  S:w  a  gUS   n
U R                  R	                  U
S
5      (       d  gU
R                   S   nObU R                  R                  USX5      n
U
c  gU R                  R	                  U
S
5      (       d  gXR                  ;  a  gUR                   S   nXqXVU
/nU R                  R                  X/X#5      (       d  gU R                  R                  U5        [        R                  " SU/U/U R                  R                  S5      S9nSUl        U R                  R!                  U5        U R"                  U R$                  UR&                  '   U R)                  S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   N   AddMulDiv-?MbP?delta      ?r   inputsoutputsnamecom.microsoftT)outputlenop_typer
   has_constant_inputmatch_parentfind_constant_inputinputis_safe_to_fuse_nodesnodes_to_removeextendr   	make_nodecreate_node_namedomainnodes_to_addappendthis_graph_namenode_name_to_graph_namer,   increase_counter)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   s   ( ??1%88&q'9:x=A!!4!4!= zz,,]A>>"*==&';';A'>?x=A!!4!4!= jj%%hq:MN;::))#vU)CqH1$**1-1E1Ea1HH!a0099*+?+?+BCH8}!Xa[%8%8E%A{H::003??&ooa0Ozz..}eWbH::003??^^3+2215OxPzz//-/B
 
 ##N3%%N+o5FTZZMhMhioMp

 ,
  ,8<8L8L$$Z__5f%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                  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                  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                  R                  USSU5      nUc  gSn	U R                  R                  USS	S
9S:w  aD  U R                  R                  USSU5      n	U	c  gU R                  R	                  U	S5      (       d  gU R                  R                  USU5      n
U
c  gU
R                   S   UR                  ;  a  gXXVU/nU	(       a  UR                  U	5        U R                  R                  XR                   S   /X#5      (       d  gU R                  R                  U5        [        R                  " SU
R                   S   /UR                   S   /U R                  R                  S5      S9nSUl        U R"                  R                  U5        U R$                  U R&                  UR(                  '   U R+                  S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   Nr    r!   r"   r(   r#   r$   r%   r&   Sqrtg       @r   r)   r-   T)r.   r/   r0   r
   r1   r2   r3   
get_parentr4   r<   r5   r6   r7   r   r8   r9   r:   r;   r=   r>   r,   r?   )r   r   r   r   r@   rA   rB   mulrC   	sqrt_node	root_noderH   rI   s                r   r   FusionGelu.fuse_2m   s    ??1%88&q'9:x=A!!4!4!= zz,,]A>>"*==&';';A'>?x=A!!4!4!= zz,,]C@@"*==&';';A'>?x=A!!4!4!=qkjj%%hq:MN;	::))#vU)CqH

//VQ@STI ::00C@@JJ))#q2EF	Acii/sK!!),zz//ZZ]O-@
 
 ##N3%%I,,Q/03::a=/PTPZPZPkPklrPs

 ,
  ,8<8L8L$$Z__5f%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                  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                  R	                  US5      (       d  gU R                  R                  USSU5      nUc  gU R                  R                  USSS	9nUS:  a  gU R                  R                  XxS:X  a  SOSU5      n	U	c  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                  S   U	R                   S   :X  d!  U
R                  S   U	R                   S   :X  d  gXqXVU
/nU R                  R                  UU
R                   S   /UU5      (       d  gU R                  R                  U5        [        R                  " S
U	R                   S   /U
R                   S   /U R                  R                  S
5      S9nSUl        U R                   R#                  U5        U R$                  U R&                  UR(                  '   U R+                  S
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   Nr    r!   r"   r(   g   `?r%   r&   r   r)   r-   T)r.   r/   r0   r
   r1   r2   r3   rM   r4   r5   r6   r7   r   r8   r9   r:   r;   r<   r=   r>   r,   r?   )r   r   r   r   r@   rA   rF   	first_mulirP   last_mulrH   rI   s                r   r   FusionGelu.fuse_3   s    ??1%88&q'9:x=A!!4!4!= zz,,]A>>"*==&';';A'>?x=A!!4!4!=A;zz,,Xs;;JJ++HeQ@ST	JJ**96HPU*Vq5JJ)))q&QaI\]	??1%88&q'9:x=A!!4!4!=A;q!Y%5%5a%88HNN1<MQZQaQabcQd<d#}Qzz//__Q 	
 
 ##N3%%I,,Q/08??1;M:NUYU_U_UpUpqwUx

 ,
  ,8<8L8L$$Z__5f%r    )__name__
__module____qualname____firstlineno__r   r   dictr   boolr   r   r   __static_attributes____classcell__)r   s   @r   r   r      s    /i /H$ HT HRD Rt RX\_cXc RhKD Kt KX\_cXc KZHD Ht HX\_cXc H Hr   r   N)loggingr   fusion_baser   onnxr   
onnx_modelr   rX   loggerr   rW   r   r   <module>re      s+   
     	8	t tr   