
    `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S rSrS\4U 4S jjrS\S\4S jrS\S\S\\	   4S jr
S\S\S\\	   4S	 jr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     i/var/www/html/ai-image-ml/venv/lib/python3.13/site-packages/onnxruntime_tools/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   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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/UU5      (       d  gU R                  R                  U5        [        R                  " S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   N   AddMulDiv-?MbP?delta      ?r   inputsoutputs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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   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//@QSf0CE E##N3%%fn5EP_O`a
+
  ,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   /UU5      (       d  gU R                  R                  U5        [        R                  " SU
R                   S   /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   Nr"   r#   r$   r*   r%   r&   r'   r(   Sqrtg       @r   r+   r.   T)r/   r0   r1   r   r2   r3   r4   
get_parentr5   r<   r6   r7   r8   r   r9   r:   r;   )r   r   r   r   r=   r>   r?   mulr@   	sqrt_node	root_noderE   rF   s                r   r   FusionGelu.fuse_2h   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//AQd0CE E##N3%%fi6F6Fq6I5JUXU_U_`aUbTcd
+
  ,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                  XR                   S   /UU5      (       d  gU R                  R                  U5        [        R                  " S
U	R                   S   /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   Nr"   r#   r$   r*   g   `?r'   r(   r   r+   r.   T)r/   r0   r1   r   r2   r3   r4   rJ   r5   r6   r7   r8   r   r9   r:   r;   r<   )r   r   r   r   r=   r>   rC   	first_mulirM   last_mulrE   rF   s                r   r   FusionGelu.fuse_3   sz    ??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//QRAS@TVi0CE E##N3%%fi6F6Fq6I5JU]UdUdefUgThi
+
  ,r    )__name__
__module____qualname____firstlineno__r   r   r   r   r   boolr   r   r   __static_attributes____classcell__)r   s   @r   r
   r
      s    /i /H$ HT HMD Mt MX`aeXf M^FD Ft FX`aeXf FP@D @t @X`aeXf @ @r   r
   N)typingr   r   loggingr   onnxr   
onnx_modelr   fusion_baser   rU   loggerr
   rT   r   r   <module>rb      s.   
 "     	8	b br   