
    `i                      j    S SK JrJr  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)	    )DictOptional)	getLogger)helper)	OnnxModel)Fusionc                   r   ^  \ rS rSrS\4U 4S jjrS\S\4S jrS\\	   4S jr
S\S\S\\	   4S	 jrS
rU =r$ )FusionFastGelu   modelc                 (   > [         TU ]  USS5        g )NFastGeluTanh)super__init__)selfr   	__class__s     m/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/onnxruntime_tools/transformers/fusion_fastgelu.pyr   FusionFastGelu.__init__   s    
F3    input_name_to_nodesoutput_name_to_nodec                 X    U R                  XU5      (       a  g U R                  XU5        g )N)fuse_1fuse_2)r   erf_noder   r   s       r   fuseFusionFastGelu.fuse   s&    ;;x6IJJH3FGr   returnc                 
   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5      nUS:  a  gU R                  R                  XxS:X  a  SOSU5      n	U	c  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                  U
SUS:X  a  SOSU5      nUc  gU R                  R                  USSX9/S9nUc  gU R                  R                  USS	S
9nUS:  a  gU R                  R                  USUS:X  a  SOSU5      nUc  gU R                  R	                  US5      (       d  gUR                  S   U	R                   S   :w  a  gXgXQXX/nU R                  R                  XR                   S   /UU5      (       d  gU R                  R                  U5        [        R                  " SU	R                   S   /UR                   U R                  R                  S5      S9nSUl        U R                   R#                  U5        g)a  
Fuse Gelu with tanh into one node:
      +---------------------------+
      |                           |
      |                           v
    [root] --> Pow --> Mul -----> Add  --> Mul --> Tanh --> Add --> Mul
      |       (Y=3)   (B=0.0447...)       (B=0.7978...)    (B=1)     ^
      |                                                              |
      +------> Mul(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   N   Add      ?Mul      ?+ݓ?-C6?deltaexclude,C?Pow      @r   inputsoutputsnamecom.microsoft)outputlenop_typer   has_constant_inputmatch_parentfind_constant_input
get_parentinputis_safe_to_fuse_nodesnodes_to_removeextendr   	make_nodecreate_node_namedomainnodes_to_addappend)r   	tanh_noder   r   childrenadd_after_tanhmul_after_tanhmul_halfi	root_nodemul_before_tanhadd_before_tanhmul_after_powpowsubgraph_nodes
fused_nodes                   r   r   FusionFastGelu.fuse_1   s    A&99&'7'7':;x=A!!4!4!=!!zz,,^SAA  #+>>&'<'<Q'?@x=A!!4!4!=!!::**>5$H[\JJ**8S9q5JJ))(aAQH[\	**11)UAGZ["JJ**?F&*Qq5**11/5qTUv![\^qr"

//Nakv/w JJ**=&*Oq5jj%%mUaAQPcd;zz,,S#6699Q<9++A.. ncp
 zz//AVAVWXAY@Z\o0CE E##N3%%j.7.>.>q.A-B.<.C.C+/::+F+Fz+RT
 ,
  ,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      nUS:  a  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UR                  S   UR                   S   :X  a  SOSU5      n	U	c  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                  U
SUS:X  a  SOSU5      nUc  gU R                  R                  USSX9/S9nUc  gU R                  R                  USS	S
9nUS:  a  gU R                  R                  USUS:X  a  SOSU5      nUc  gU R                  R	                  US5      (       d  gUR                  S   U	R                   S   :w  a  gXXQXUU/nU R                  R                  XR                   S   /UU5      (       d  gU R                  R                  U5        [        R                  " SU	R                   S   /UR                   U R                  R                  S5      S9nSUl        U R                   R#                  U5        g)aw  
This pattern is from Tensorflow mode.
Fuse Gelu with tanh into one node:
      +---------------------------+
      |                           |
      |                           v
    [root] --> Pow --> Mul -----> Add  --> Mul --> Tanh --> Add --> Mul(B=0.5)-->Mul-->
      |       (Y=3)   (B=0.0447...)       (B=0.7978...)    (B=1)                  ^
      |                                                                           |
      +---------------------------------------------------------------------------+
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(   r*   r,   r-   r.   r   r/   r3   T)r4   r5   r6   r   r7   r9   r:   r;   r8   r<   r=   r>   r   r?   r@   rA   rB   rC   )r   rD   r   r   rE   rF   rH   rI   mul_after_mul_halfrJ   rK   rL   rM   rN   rO   rP   s                   r   r   FusionFastGelu.fuse_2m   sc    A&99&'7'7':;x=A!!4!4!=!!zz,,^SAA  #+>>&'<'<Q'?@x=A!!4!4!=A;JJ**8S9q5??1%88&q'9:x=A!!4!4!=%a[JJ))*</A/G/G/Jhoo^_N`/`!fg*=?	 **11)UAGZ["JJ**?F&*Qq5**11/5qTUv![\^qr"

//Nakv/w JJ**=&*Oq5jj%%mUaAQPcd;zz,,S#6699Q<9++A.. ._gt
 zz//AZAZ[\A]@^`s0CE E##N3%%j.7.>.>q.A-B.@.G.G+/::+F+Fz+RT
 ,
  ,r    )__name__
__module____qualname____firstlineno__r   r   r   r   r   boolr   r   __static_attributes____classcell__)r   s   @r   r
   r
      se    4i 4H$ HT H
T-XVZ^ T-l\T \PT \YabfYg \ \r   r
   N)typingr   r   loggingr   onnxr   
onnx_modelr   fusion_baser   rV   loggerr
   rU   r   r   <module>rc      s.   
 "     	8	{V {r   