Ë
    ÝÍ:j‡(  ã                  óF   — d dl mZ d dlZddlmZ ddlmZ  G d„ de«      Zy)	é    )Ú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 )	Ú
FusionGeluc                ó(   •— t         ‰| �  |dd«       y )NÚGeluÚErf)ÚsuperÚ__init__)ÚselfÚmodelÚ	__class__s     €ú�/home/mcse/projects/srt_converter/srt-converter-venv/lib/python3.12/site-packages/onnxruntime/quantization/fusions/fusion_gelu.pyr   zFusionGelu.__init__   s   ø€ Ü‰Ñ˜ ¨Õ.ó    c                ó°   — | j                  |||«      s&| j                  |||«      s| j                  |||«      r| j                  j	                  dd«       yy)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   Úerf_nodeÚinput_name_to_nodesÚoutput_name_to_nodes       r   ÚfusezFusionGelu.fuse   sT   € ð �K‰K˜Ð"5Ð7JÔKØ�{‰{˜8Ð%8Ð:MÔNØ�{‰{˜8Ð%8Ð:MÔNà�J‰J×'Ñ'¨¸Õ;ð Or   c                ó˜  — |j                   d   |vry||j                   d      }t        |«      dk7  s|d   j                  dk7  ry|d   }| j                  |d«      sy|j                   d   |vry||j                   d      }t        |«      dk7  s|d   j                  dk7  ry|d   }| j	                  |dd|«      }|€y| j                  |dd¬	«      dk7  ry|j                  d   }|j                  d   |j                   d   k(  rdnd}	||j                  |	   k(  r[||j                   d      }t        |«      dk7  s|d   j                  dk7  ry|d   }
| j                  |
d
«      sy|
j                   d   }nH| j	                  |d|	|«      }
|
€y| j                  |
d
«      sy||
j                  vry|j                   d   }|||||
g}| j                  ||g||«      sy| j                  j                  |«       t        j                  j                  d| j                  «       |g|g¬«      }d|_        | j                  j!                  |«       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   Fr   ÚAddÚMulÚDivçà-� ö?çü©ñÒ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ØØ& x§¡°qÑ'9Ñ:ˆÜˆx‹=˜AÒ ¨!¡×!4Ñ!4¸Ò!=ØØ  ™ˆà×&Ñ& }°aÔ8Øà×Ñ Ñ"Ð*=Ñ=Øà& }×';Ñ';¸AÑ'>Ñ?ˆÜˆx‹=˜AÒ ¨!¡×!4Ñ!4¸Ò!=Øà  ™ˆà×Ñ ¨%°Ð4GÓHˆØˆ;Øà×#Ñ# C¨°uÐ#Ó=ÀÒBØàŸ™ 1™ˆà$×*Ñ*¨1Ñ-°×1EÑ1EÀaÑ1HÒH‘!ÈaˆØ˜]×0Ñ0°Ñ9Ò9Ø*¨=×+?Ñ+?ÀÑ+BÑCˆHÜ�8‹} Ò! X¨a¡[×%8Ñ%8¸EÒ%AØØ ‘{ˆHØ×*Ñ*¨8°SÔ9ØØ&Ÿo™o¨aÑ0‰Oà×(Ñ(¨¸¸wÐH[Ó\ˆHØÐØà×*Ñ*¨8°SÔ9Øà X§^¡^Ñ3Øà+×2Ñ2°1Ñ5ˆOà˜x¨¸ÀxÐPˆØ×)Ñ)¨.¸?Ð:KÐM`ÐbuÔvØà×Ñ×#Ñ# NÔ3Ü—[‘[×*Ñ*Ø˜×5Ñ5Ó7ÀÐ@PÐ[jÐZkð +ó 
ˆ
ð ,ˆ
ÔØ×Ñ× Ñ  Ô,Ør   c                óp  — |j                   d   |vry||j                   d      }t        |«      dk7  s|d   j                  dk7  ry|d   }| j                  |d«      sy|j                   d   |vry||j                   d      }t        |«      dk7  s|d   j                  dk7  ry|d   }| j                  |d«      sy|j                   d   |vry||j                   d      }t        |«      dk7  s|d   j                  dk7  ry|d   }| j	                  |dd|«      }|€yd}	| j                  |d	d
¬«      dk7  r*| j	                  |dd|«      }	|	€y| j                  |	d«      sy|j                  d   }
|
|j                  vry|||||g}|	r|j                  |	«       | j                  ||j                   d   g||«      sy| j                  j                  |«       t        j                  j                  d| j                  «       |
g|j                   d   g¬«      }d|_        | j                   j                  |«       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   Fr   r   r    r&   r!   Nr"   r#   r$   ÚSqrtg       @r   r'   r   T)r,   r-   r.   r/   r0   r1   r2   r<   r3   r4   r5   r6   r7   r8   r9   r:   r;   )r   r   r   r   r=   r>   r?   Úmulr@   Ú	sqrt_noderA   rE   rF   s                r   r   zFusionGelu.fuse_2z   si  € ð" �?‰?˜1ÑÐ%8Ñ8ØØ& x§¡°qÑ'9Ñ:ˆÜˆx‹=˜AÒ ¨!¡×!4Ñ!4¸Ò!=ØØ  ™ˆà×&Ñ& }°aÔ8Øà×Ñ Ñ"Ð*=Ñ=ØØ& }×';Ñ';¸AÑ'>Ñ?ˆÜˆx‹=˜AÒ ¨!¡×!4Ñ!4¸Ò!=ØØ  ™ˆà×&Ñ& }°cÔ:Øà×Ñ Ñ"Ð*=Ñ=ØØ& }×';Ñ';¸AÑ'>Ñ?ˆÜˆx‹=˜AÒ ¨!¡×!4Ñ!4¸Ò!=ØØ�q‰kˆà×Ñ ¨%°Ð4GÓHˆØˆ;Øàˆ	Ø×#Ñ# C¨°uÐ#Ó=ÀÒBØ×)Ñ)¨#¨v°qÐ:MÓNˆIØÐ ØØ×*Ñ*¨9°cÔ:ØàŸ™ 1™ˆà §¡Ñ*Øà˜x¨¸ÀsÐKˆÙØ×!Ñ! )Ô,à×)Ñ)¨.¸3¿:¹:Àa¹=¸/ÐK^Ð`sÔtØà×Ñ×#Ñ# NÔ3Ü—[‘[×*Ñ*Ø˜×5Ñ5Ó7ÀÐ@PÐ[^×[eÑ[eÐfgÑ[hÐZið +ó 
ˆ
ð ,ˆ
ÔØ×Ñ× Ñ  Ô,Ør   c                ó.  — |j                   d   |vry||j                   d      }t        |«      dk7  s|d   j                  dk7  ry|d   }| j                  |d«      sy|j                   d   |vry||j                   d      }t        |«      dk7  s|d   j                  dk7  ry|d   }| j                  |d«      sy| j	                  |dd|«      }|€y| j                  |dd¬	«      }|dk  ryd|z
  }	|j                  |	   }
|j                   d   |vry||j                   d      }t        |«      dk7  s|d   j                  dk7  ry|d   }|j                  d   |
k(  s|j                  d   |
k(  sy|||||g}| j                  ||j                   d   g||«      sy| j                  j                  |«       t        j                  j                  d
| j                  «       |
g|j                   d   g¬«      }d|_        | j                  j!                  |«       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   Fr   r   r    r&   g   `ž æ?r#   r$   r   r'   r   Tr+   )r   r   r   r   r=   r>   rC   Ú	first_mulÚiÚroot_input_indexrA   Úlast_mulrE   rF   s                 r   r   zFusionGelu.fuse_3Æ   sN  € ð$ �?‰?˜1ÑÐ%8Ñ8ØØ& x§¡°qÑ'9Ñ:ˆÜˆx‹=˜AÒ ¨!¡×!4Ñ!4¸Ò!=ØØ  ™ˆà×&Ñ& }°aÔ8Øà×Ñ Ñ"Ð*=Ñ=ØØ& }×';Ñ';¸AÑ'>Ñ?ˆÜˆx‹=˜AÒ ¨!¡×!4Ñ!4¸Ò!=ØØ˜A‘;ˆà×&Ñ& x°Ô5Øà×%Ñ% h°°qÐ:MÓNˆ	ØÐØà×$Ñ$ YÐ0BÈ%Ð$ÓPˆØˆqŠ5Øà˜q™5ÐØ"Ÿ™Ð)9Ñ:ˆà�?‰?˜1ÑÐ%8Ñ8ØØ& x§¡°qÑ'9Ñ:ˆÜˆx‹=˜AÒ ¨!¡×!4Ñ!4¸Ò!=ØØ˜A‘;ˆà—‘˜qÑ! ^Ò3°x·~±~ÀaÑ7HÈNÒ7ZØà# X¨}¸hÈÐQˆØ×)Ñ)ØØ�_‰_˜QÑÐ ØØô	
ð à×Ñ×#Ñ# NÔ3Ü—[‘[×*Ñ*Ø˜×5Ñ5Ó7ÀÐ@PÐ[c×[jÑ[jÐklÑ[mÐZnð +ó 
ˆ
ð ,ˆ
ÔØ×Ñ× Ñ  Ô,Ør   )r   r   )r   úonnx.NodeProtor   údict[str, list[onnx.NodeProto]]r   údict[str, onnx.NodeProto])r   rP   r   rQ   r   rR   ÚreturnÚbool)	Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   Ú__classcell__)r   s   @r   r	   r	      s»   ø„ õ/ð<à ð<ð =ð<ð 7ó	<ð"Uà ðUð =ðUð 7ð	Uð
 
óUðnJà ðJð =ðJð 7ð	Jð
 
óJðXJà ðJð =ðJð 7ð	Jð
 
÷Jr   r	   )Ú
__future__r   r6   Ú
onnx_modelr   Úfusionr   r	   © r   r   ú<module>r]      s!   ðõ #ã å "Ý ôB�õ Br   