
    g'                     j    d dl mZ d dlmZmZ d dlmZ d dlmZ d dl	m
Z
  ee      Z G d de      Zy)	    )	getLogger)DictOptional)Fusion)helper)	OnnxModelc                        e Zd Zdef fdZdedefdZdededee   fdZ	dededee   fdZ
dededee   fd	Z xZS )

FusionGelumodelc                 (    t         |   |dd       y )NGeluErf)super__init__)selfr   	__class__s     Y/var/www/openai/venv/lib/python3.12/site-packages/onnxruntime/transformers/fusion_gelu.pyr   zFusionGelu.__init__   s    .    input_name_to_nodesoutput_name_to_nodec                 z    | j                  |||      ry | j                  |||      ry | j                  |||       y )N)fuse_1fuse_2fuse_3)r   erf_noder   r   s       r   fusezFusionGelu.fuse   s>    ;;x!46IJ;;x!46IJH13FGr   returnc                    |j                   d   |vry||j                   d      }t        |      dk7  s|d   j                  dk7  ry|d   }| j                  j	                  |d      sy|j                   d   |vry||j                   d      }t        |      dk7  s|d   j                  dk7  ry|d   }| j                  j                  |dd|      }|y| j                  j                  |dd	      dk7  ry|j                  d   }|j                  d   |j                   d   k(  rdnd}	||j                  |	   k(  re||j                   d      }t        |      dk7  s|d   j                  dk7  ry|d   }
| j                  j	                  |
d
      sy|
j                   d   }n\| j                  j                  |d|	|      }
|
y| j                  j	                  |
d
      sy||
j                  vry|j                   d   }|||||
g}| j                  j                  ||g||      sy| j                  j                  |       t        j                  d|g|g| j                  j                  d            }d|_        | j                  j!                  |       | j"                  | j$                  |j&                  <   | j)                  d       y)ay  
        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   zFusionGelu.fuse_1   s   ( ??1%88&x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..}eWNabH::003?X^^3+2215OxxPzz//_-/BDW
 ##N3%%N+o5FTZZMhMhioMp

 ,
  ,8<8L8L$$Z__5f%r   c                    |j                   d   |vry||j                   d      }t        |      dk7  s|d   j                  dk7  ry|d   }| j                  j	                  |d      sy|j                   d   |vry||j                   d      }t        |      dk7  s|d   j                  dk7  ry|d   }| j                  j	                  |d      sy|j                   d   |vry||j                   d      }t        |      dk7  s|d   j                  dk7  ry|d   }| j                  j                  |dd|      }|yd}	| j                  j                  |dd	
      dk7  r>| j                  j                  |dd|      }	|	y| j                  j	                  |	d      sy| j                  j                  |d|      }
|
y|
j                   d   |j                  vry|||||g}|	r|j                  |	       | j                  j                  ||j                   d   g||      sy| j                  j                  |       t        j                  d|
j                   d   g|j                   d   g| j                  j                  d            }d|_        | j"                  j                  |       | j$                  | j&                  |j(                  <   | j+                  d       y)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.   r/   r   r0   r1   r2   
get_parentr3   r;   r4   r5   r6   r   r7   r8   r9   r:   r<   r=   r+   r>   )r   r   r   r   r?   r@   rA   mulrB   	sqrt_node	root_noderG   rH   s                r   r   zFusionGelu.fuse_2n   s    ??1%88&x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/xsK!!),zz//SZZ]O-@BU
 ##N3%%I,,Q/03::a=/PTPZPZPkPklrPs

 ,
  ,8<8L8L$$Z__5f%r   c                 p   |j                   d   |vry||j                   d      }t        |      dk7  s|d   j                  dk7  ry|d   }| j                  j	                  |d      sy|j                   d   |vry||j                   d      }t        |      dk7  s|d   j                  dk7  ry|d   }| j                  j	                  |d      sy| j                  j                  |dd|      }|y| j                  j                  |dd	      }|dk  ry| j                  j                  ||dk(  rdnd|      }	|	y|j                   d   |vry||j                   d      }t        |      dk7  s|d   j                  dk7  ry|d   }
|
j                  d   |	j                   d   k(  s |
j                  d   |	j                   d   k(  sy|||||
g}| j                  j                  ||
j                   d   g||      sy| j                  j                  |       t        j                  d
|	j                   d   g|
j                   d   g| j                  j                  d
            }d|_        | j                   j#                  |       | j$                  | j&                  |j(                  <   | j+                  d
       y)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.   r/   r   r0   r1   r2   rK   r3   r4   r5   r6   r   r7   r8   r9   r:   r;   r<   r=   r+   r>   )r   r   r   r   r?   r@   rE   	first_mulirN   last_mulrG   rH   s                r   r   zFusionGelu.fuse_3   s    ??1%88&x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&xq'9:x=A!!4!4!=A;q!Y%5%5a%88HNN1<MQZQaQabcQd<d#X}hQzz//__Q 	
 ##N3%%I,,Q/08??1;M:NUYU_U_UpUpqwUx

 ,
  ,8<8L8L$$Z__5f%r   )__name__
__module____qualname__r   r   r   r   r   boolr   r   r   __classcell__)r   s   @r   r
   r
      s    /i /H$ HT HRD Rt RX`aeXf RhKD Kt KX`aeXf KZHD Ht HX`aeXf Hr   r
   N)loggingr   typingr   r   fusion_baser   onnxr   
onnx_modelr   rS   loggerr
    r   r   <module>r_      s.   
  !    	8	t tr   