§
    kŠtj‡(  ã                  ó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     €új/var/www/html/CA-Chatbot/venv/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~   € ð �KŠK˜Ð"5Ð7JÑ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Ô-°Ô1EÀaÔ1HÒHÐH�!�!ÈaˆØ˜]Ô0°Ô9Ò9Ð9Ø*¨=Ô+?ÀÔ+BÔCˆHÝ�8‰}Œ} Ò!Ð! X¨a¤[Ô%8¸EÒ%AÐ%AØ�uØ ”{ˆHØ×*Ò*¨8°SÑ9Ô9ð Ø�uØ&œo¨aÔ0ˆOˆOà×(Ò(¨¸¸wÐH[Ñ\Ô\ˆHØÐØ�uà×*Ò*¨8°SÑ9Ô9ð Ø�uà X¤^Ð3Ð3Ø�uà+Ô2°1Ô5ˆOà˜x¨¸ÀxÐPˆØ×)Ò)¨.¸?Ð:KÐM`ÐbuÑvÔvð 	Ø�5àÔ×#Ò# NÑ3Ô3Ð3Ý”[×*Ò*Ø˜×5Ò5Ñ7Ô7ÀÐ@PÐ[jÐZkð +ñ 
ô 
ˆ
ð ,ˆ
ÔØÔ× Ò  Ñ,Ô,Ð,Øˆ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Ø�qŒkˆà×Ò ¨%°Ð4GÑHÔHˆØˆ;Ø�5àˆ	Ø×#Ò# C¨°uÐ#Ñ=Ô=ÀÒBÐBØ×)Ò)¨#¨v°qÐ:MÑNÔNˆIØÐ Ø�uØ×*Ò*¨9°cÑ:Ô:ð Ø�uàœ 1œˆà ¤Ð*Ð*Ø�5à˜x¨¸ÀsÐKˆØð 	-Ø×!Ò! )Ñ,Ô,Ð,à×)Ò)¨.¸3¼:Àa¼=¸/ÐK^Ð`sÑtÔtð 	Ø�5àÔ×#Ò# NÑ3Ô3Ð3Ý”[×*Ò*Ø˜×5Ò5Ñ7Ô7ÀÐ@PÐ[^Ô[eÐfgÔ[hÐZið +ñ 
ô 
ˆ
ð ,ˆ
ÔØÔ× Ò  Ñ,Ô,Ð,Øˆ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à×$Ò$ YÐ0BÈ%Ð$ÑPÔPˆØˆqŠ5ˆ5Ø�5à˜q™5ÐØ"œÐ)9Ô:ˆàŒ?˜1ÔÐ%8Ð8Ð8Ø�5Ø& x¤°qÔ'9Ô:ˆÝˆx‰=Œ=˜AÒÐ ¨!¤Ô!4¸Ò!=Ð!=Ø�5Ø˜A”;ˆà”˜qÔ! ^Ò3Ð3°x´~ÀaÔ7HÈNÒ7ZÐ7ZØ�5à# X¨}¸hÈÐQˆØ×)Ò)ØØŒ_˜QÔÐ ØØñ	
ô 
ð 	ð �5àÔ×#Ò# NÑ3Ô3Ð3Ý”[×*Ò*Ø˜×5Ò5Ñ7Ô7ÀÐ@PÐ[cÔ[jÐklÔ[mÐZnð +ñ 
ô 
ˆ
ð ,ˆ
ÔØÔ× Ò  Ñ,Ô,Ð,Øˆ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   