
     Ng(                    N    d dl mZ d dlZddlmZ ddlmZ  G d de          ZdS )	    )annotationsN   )	ONNXModel   )Fusionc                  @     e Zd Zd fdZdd
ZddZddZddZ xZS )
FusionGelumodelr   c                N    t                                          |dd           d S )NGeluErf)super__init__)selfr
   	__class__s     h/var/www/html/ai-engine/env/lib/python3.11/site-packages/onnxruntime/quantization/fusions/fusion_gelu.pyr   zFusionGelu.__init__   s%    .....    erf_nodeonnx.NodeProtoinput_name_to_nodesdict[str, list[onnx.NodeProto]]output_name_to_nodedict[str, onnx.NodeProto]c                    |                      |||          s.|                     |||          s|                     |||          r| j                            dd           dS dS )z
        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   r   r   r   s       r   fusezFusionGelu.fuse   s~     KK"57JKK	<{{8%8:MNN	< {{8%8:MNN	<
 J'';;;;;	< 	<r   returnboolc                   |j         d         |vrdS ||j         d                  }t          |          dk    s|d         j        dk    rdS |d         }|                     |d          sdS |j         d         |vrdS ||j         d                  }t          |          dk    s|d         j        dk    rdS |d         }|                     |dd|          }|dS |                     |dd	
          dk    rdS |j        d         }|j        d         |j         d         k    rdnd}	||j        |	         k    rg||j         d                  }t          |          dk    s|d         j        dk    rdS |d         }
|                     |
d          sdS |
j         d         }nL|                     |d|	|          }
|
dS |                     |
d          sdS ||
j        vrdS |j         d         }|||||
g}|                     ||g||          sdS | j        	                    |           t          j                            d|                                 |g|g          }d|_        | j                            |           dS )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   Fr   AddMulDivN-?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   zFusionGelu.fuse_1#   s   2 ?1%8885&xq'9:x==A!!4!=!=5 &&}a88 	5"*===5&}';A'>?x==A!!4!=!=5 %4GHH;5##Cu#==BB51$*1-1Ea1HHH!!a]0999*=+?+BCH8}}!!Xa[%8E%A%Au{H**8S99 u&oa0OO((wH[\\Hu**8S99 uX^33u+215OxxP)).?:KM`buvv 	5##N333[**5577@P[jZk + 
 

 ,
  ,,,tr   c                   |j         d         |vrdS ||j         d                  }t          |          dk    s|d         j        dk    rdS |d         }|                     |d          sdS |j         d         |vrdS ||j         d                  }t          |          dk    s|d         j        dk    rdS |d         }|                     |d          sdS |j         d         |vrdS ||j         d                  }t          |          dk    s|d         j        dk    rdS |d         }|                     |dd|          }|dS d}	|                     |d	d
          dk    r4|                     |dd|          }	|	dS |                     |	d          sdS |j        d         }
|
|j        vrdS |||||g}|	r|                    |	           |                     ||j         d         g||          sdS | j	        
                    |           t          j                            d|                                 |
g|j         d         g          }d|_        | j                            |           dS )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)r1   r2   r3   r4   r5   r6   r7   rA   r8   r9   r:   r;   r<   r=   r>   r?   r@   )r   r   r   r   rB   rC   rD   mulrE   	sqrt_noderF   rJ   rK   s                r   r   zFusionGelu.fuse_2z   s   " ?1%8885&xq'9:x==A!!4!=!=5 &&}a88 	5"*===5&}';A'>?x==A!!4!=!=5 &&}c:: 	5"*===5&}';A'>?x==A!!4!=!=5qk%4GHH;5	##Cu#==BB))#vq:MNNI u**9c:: u1**5xsK 	-!!),,,)).3:a=/K^`stt 	5##N333[**5577@P[^[efg[hZi + 
 

 ,
  ,,,tr   c                   |j         d         |vrdS ||j         d                  }t          |          dk    s|d         j        dk    rdS |d         }|                     |d          sdS |j         d         |vrdS ||j         d                  }t          |          dk    s|d         j        dk    rdS |d         }|                     |d          sdS |                     |dd|          }|dS |                     |dd	
          }|dk     rdS d|z
  }	|j        |	         }
|j         d         |vrdS ||j         d                  }t          |          dk    s|d         j        dk    rdS |d         }|j        d         |
k    s|j        d         |
k    sdS |||||g}|                     ||j         d         g||          sdS | j        	                    |           t          j                            d|                                 |
g|j         d         g          }d|_        | j                            |           dS )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+   Ng   `?r(   r)   r   r,   r   Tr0   )r   r   r   r   rB   rC   rH   	first_muliroot_input_indexrF   last_mulrJ   rK   s                 r   r   zFusionGelu.fuse_3   s   $ ?1%8885&xq'9:x==A!!4!=!=5 &&}a88 	5"*===5&}';A'>?x==A!!4!=!=5A;&&x55 	5%%hq:MNN	5$$Y0B%$PPq555q5")9:?1%8885&xq'9:x==A!!4!=!=5A;q!^33x~a7HN7Z7Z5#X}hQ))_Q 	
 
 	 5##N333[**5577@P[c[jkl[mZn + 
 

 ,
  ,,,tr   )r
   r   )r   r   r   r   r   r   )r   r   r   r   r   r   r!   r"   )	__name__
__module____qualname__r   r    r   r   r   __classcell__)r   s   @r   r	   r	      s        / / / / / /< < < <"U U U UnJ J J JXJ J J J J J J Jr   r	   )
__future__r   r;   
onnx_modelr   fusionr   r	    r   r   <module>r]      s    # " " " " "  " " " " " "      B B B B B B B B B Br   