§
    kŠtjE  ã                   óh   — d dl mZ d dlmZ d dlmZ d dlmZ  ee¦  «        Z	 G d„ de¦  «        Z
dS )é    )Ú	getLogger)ÚFusion)Úhelper)Ú	OnnxModelc                   ó”   ‡ — e Zd Zdefˆ fd„Zdedefd„Zdedz  fd„Zdedededz  fd	„Z	dedededz  fd
„Z
dedededz  fd„Zˆ xZS )ÚFusionFastGeluÚmodelc                 óN   •— t          ¦   «                              |dd¦  «         d S )NÚFastGeluÚTanh)ÚsuperÚ__init__)Úselfr	   Ú	__class__s     €úf/var/www/html/CA-Chatbot/venv/lib/python3.11/site-packages/onnxruntime/transformers/fusion_fastgelu.pyr   zFusionFastGelu.__init__   s%   ø€ Ý‰Œ×Ò˜ 
¨FÑ3Ô3Ð3Ð3Ð3ó    Úinput_name_to_nodesÚoutput_name_to_nodec                 óÎ   — |                       |||¦  «        rd S |                      |||¦  «        rd S |                      |||¦  «        rd S |                      |||¦  «        rd S d S )N)Úfuse_1Úfuse_2Úfuse_3Úfuse_4)r   Ú	tanh_noder   r   s       r   ÚfusezFusionFastGelu.fuse   sˆ   € Ø�;Š;�yÐ"5Ð7JÑKÔKð 	ØˆFà�;Š;�yÐ"5Ð7JÑKÔKð 	ØˆFà�;Š;�yÐ"5Ð7JÑKÔKð 	ØˆFà�;Š;�yÐ"5Ð7JÑKÔKð 	ØˆFð	ð 	r   ÚreturnNc                 ó   — |j         d         |vrdS ||j         d                  }t          |¦  «        dk    s|d         j        dk    rdS |d         }| j                             |d¦  «        sdS |j         d         |vrdS ||j         d                  }t          |¦  «        dk    s|d         j        dk    rdS |d         }| j                             |dd|¦  «        }|€dS | j                             |d¦  «        }|dk     rdS |j        |dk    rdnd         }	| j                             ||dk    rdnd|¦  «        }
| j                             |dd|¦  «        }|€dS | j                             |dd	¬
¦  «        }|dk     rdS | j                             |d|dk    rdnd|¦  «        }|€dS | j                             |dd||
r|
gng ¬¦  «        }|€dS | j                             |dd	¬
¦  «        }|dk     rdS | j                             |d|dk    rdnd|¦  «        }|€dS | j                             |d¦  «        sdS |j        d         |	k    rdS ||||||||g}| j         	                    ||j         d         g||¦  «        sdS | j
                             |¦  «         t          j        d|	g|j         | j                             d¦  «        ¬¦  «        }d|_        | j                             |¦  «         | j        | j        |j        <   dS )aj  
        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.microsoftT)ÚoutputÚlenÚop_typer	   Úhas_constant_inputÚmatch_parentÚfind_constant_inputÚinputÚ
get_parentÚis_safe_to_fuse_nodesÚnodes_to_removeÚextendr   Ú	make_nodeÚcreate_node_nameÚdomainÚnodes_to_addÚappendÚthis_graph_nameÚnode_name_to_graph_namer/   )r   r   r   r   ÚchildrenÚadd_after_tanhÚmul_after_tanhÚmul_halfÚiÚ
root_inputÚ	root_nodeÚmul_before_tanhÚadd_before_tanhÚmul_after_powÚpowÚsubgraph_nodesÚ
fused_nodes                    r   r   zFusionFastGelu.fuse_1   s¡  € ð Ô˜AÔÐ&9Ð9Ð9ØˆFØ& yÔ'7¸Ô':Ô;ˆÝˆx‰=Œ=˜AÒÐ ¨!¤Ô!4¸Ò!=Ð!=ØˆFØ! !œˆàŒz×,Ò,¨^¸SÑAÔAð 	ØˆFàÔ  Ô#Ð+>Ð>Ð>ØˆFØ& ~Ô'<¸QÔ'?Ô@ˆÝˆx‰=Œ=˜AÒÐ ¨!¤Ô!4¸Ò!=Ð!=ØˆFØ! !œˆà”:×*Ò*¨>¸5À$ÐH[Ñ\Ô\ˆØÐØˆFàŒJ×*Ò*¨8°SÑ9Ô9ˆØˆqŠ5ˆ5ØˆFà”^¨¨aª¨ A A°QÔ7ˆ
ð ”J×)Ò)¨(¸¸aº¸°A°AÀQÐH[Ñ\Ô\ˆ	àœ*×1Ò1°)¸UÀAÐGZÑ[Ô[ˆØÐ"ØˆFàŒJ×*Ò*¨?¸FÈ&Ð*ÑQÔQˆØˆqŠ5ˆ5ØˆFàœ*×1Ò1°/À5ÈqÐTUÊvÈvÈ!È!Ð[\Ð^qÑrÔrˆØÐ"ØˆFàœ
×/Ò/ØØØØØ#,Ð4�Y�K�K°"ð 0ñ 
ô 
ˆð Ð ØˆFàŒJ×*Ò*¨=¸&ÈÐ*ÑOÔOˆØˆqŠ5ˆ5ØˆFàŒj×%Ò% m°UÀÀaÂÀ¸A¸AÈQÐPcÑdÔdˆØˆ;ØˆFàŒz×,Ò,¨S°#Ñ6Ô6ð 	ØˆFàŒ9�QŒ<˜:Ò%Ð%ØˆFð ØØØØØØØð	
ˆð Œz×/Ò/ØØÔ" 1Ô%Ð&ØØñ	
ô 
ð 	ð ˆFàÔ×#Ò# NÑ3Ô3Ð3ÝÔ%ØØ�<Ø"Ô)Ø”×,Ò,¨ZÑ8Ô8ð	
ñ 
ô 
ˆ
ð ,ˆ
ÔØÔ× Ò  Ñ,Ô,Ð,Ø8<Ô8LˆÔ$ Z¤_Ñ5Øˆtr   c                 óÚ  — |j         d         |vrdS ||j         d                  }t          |¦  «        dk    s|d         j        dk    rdS |d         }| j                             |d¦  «        sdS |j         d         |vrdS ||j         d                  }t          |¦  «        dk    s|d         j        dk    rdS |d         }| j                             |d¦  «        }|dk     rdS |j         d         |vrdS ||j         d                  }t          |¦  «        dk    s|d         j        dk    rdS |d         }| j                             ||j        d         |j         d         k    rdnd|¦  «        }	| j                             |dd|¦  «        }
|
€dS | j                             |
dd	¬
¦  «        }|dk     rdS | j                             |
d|dk    rdnd|¦  «        }|€dS | j                             |dd||	r|	gng ¬¦  «        }|€dS | j                             |dd	¬
¦  «        }|dk     rdS | j                             |d|dk    rdnd|¦  «        }|€dS | j                             |d¦  «        sdS |j        |j        d         |j         d         k    rdnd         }|j        d         |k    rdS |||||
|||g}| j         	                    ||j         d         g||¦  «        sdS | j
                             |¦  «         t          j        d|g|j         | j                             d¦  «        ¬¦  «        }d|_        | j                             |¦  «         | j        | j        |j        <   dS )aÐ  
        This pattern is from Tensorflow model.
        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,   r0   T)r1   r2   r3   r	   r4   r6   r8   r7   r5   r9   r:   r;   r   r<   r=   r>   r?   r@   rA   rB   r/   )r   r   r   r   rC   rD   rF   rG   Úmul_after_mul_halfrI   rJ   rK   rL   rM   rH   rN   rO   s                    r   r   zFusionFastGelu.fuse_2‹   s  € ð Ô˜AÔÐ&9Ð9Ð9ØˆFØ& yÔ'7¸Ô':Ô;ˆÝˆx‰=Œ=˜AÒÐ ¨!¤Ô!4¸Ò!=Ð!=ØˆFØ! !œˆàŒz×,Ò,¨^¸SÑAÔAð 	ØˆFàÔ  Ô#Ð+>Ð>Ð>ØˆFØ& ~Ô'<¸QÔ'?Ô@ˆÝˆx‰=Œ=˜AÒÐ ¨!¤Ô!4¸Ò!=Ð!=ØˆFØ˜A”;ˆàŒJ×*Ò*¨8°SÑ9Ô9ˆØˆqŠ5ˆ5ØˆFàŒ?˜1ÔÐ%8Ð8Ð8ØˆFØ& x¤°qÔ'9Ô:ˆÝˆx‰=Œ=˜AÒÐ ¨!¤Ô!4¸Ò!=Ð!=ØˆFØ% aœ[Ðð ”J×)Ò)ØØ#Ô)¨!Ô,°´ÀÔ0BÒBÐBˆAˆAÈØñ
ô 
ˆ	ð œ*×1Ò1°)¸UÀAÐGZÑ[Ô[ˆØÐ"ØˆFàŒJ×*Ò*¨?¸FÈ&Ð*ÑQÔQˆØˆqŠ5ˆ5ØˆFàœ*×1Ò1°/À5ÈqÐTUÊvÈvÈ!È!Ð[\Ð^qÑrÔrˆØÐ"ØˆFàœ
×/Ò/ØØØØØ#,Ð4�Y�K�K°"ð 0ñ 
ô 
ˆð Ð ØˆFàŒJ×*Ò*¨=¸&ÈÐ*ÑOÔOˆØˆqŠ5ˆ5ØˆFàŒj×%Ò% m°UÀÀaÂÀ¸A¸AÈQÐPcÑdÔdˆØˆ;ØˆFàŒz×,Ò,¨S°#Ñ6Ô6ð 	ØˆFà'Ô-Ð3EÔ3KÈAÔ3NÐRZÔRaÐbcÔRdÒ3dÐ3d¨a¨aÐjkÔlˆ
àŒ9�QŒ<˜:Ò%Ð%ØˆFð ØØØØØØØð	
ˆð Œz×/Ò/ØØÔ& qÔ)Ð*ØØñ	
ô 
ð 	ð ˆFàÔ×#Ò# NÑ3Ô3Ð3ÝÔ%ØØ�<Ø&Ô-Ø”×,Ò,¨ZÑ8Ô8ð	
ñ 
ô 
ˆ
ð ,ˆ
ÔØÔ× Ò  Ñ,Ô,Ð,Ø8<Ô8LˆÔ$ Z¤_Ñ5Øˆtr   c           	      ó¤  — |j         d         |vrdS ||j         d                  }t          |¦  «        dk    s|d         j        dk    rdS |d         }| j                             |d¦  «        sdS |j         d         |vrdS ||j         d                  }t          |¦  «        dk    s|d         j        dk    rdS |d         }| j                             |dd|¦  «        }|€dS | j                             |d¦  «        }|dk     rdS |j        |dk    rdnd         }	| j                             |dd|¦  «        }
|
€dS | j                             |
dd|¦  «        }|€dS | j                             |d¦  «        }|dk     rdS | j                             |
dd|¦  «        }|€dS | j                             |dd	¬
¦  «        }|dk     rdS |j        |dk    rdnd         |	k    rdS | j                             |d|dk    rdnd|¦  «        }|€dS |j        d         |	k    rd}n|j        d         |	k    rd}ndS | j                             |d||¦  «        }|€dS | j                             |dd	¬
¦  «        }|dk     rdS |j        |dk    rdnd         |	k    rdS ||||
|||||g	}| j                             ||j         d         g||¦  «        sdS | j	         
                    |¦  «         t          j        d|	g|j         | j                             d¦  «        ¬¦  «        }d|_        | j                             |¦  «         | j        | j        |j        <   dS )až  
        OpenAI's gelu implementation, also used in Megatron:
           Gelu(x) = x * 0.5 * (1.0 + torch.tanh(0.79788456 * x * (1.0 + 0.044715 * x * x)))

        Fuse subgraph into a FastGelu node:
            +------------ Mul (B=0.79788456) -------------------+
            |                                                   |
            +-------------------------------+                   |
            |                               |                   |
            |                               v                   v
          [root] --> Mul (B=0.044715) --> Mul --> Add(B=1) --> Mul --> Tanh --> Add(B=1) --> Mul-->
            |                                                                                 ^
            |                                                                                 |
            +-----------> Mul (B=0.5) --------------------------------------------------------+
        r   Nr   r   r    r!   r"   r#   r$   r%   r)   r   r,   r0   T)r1   r2   r3   r	   r4   r5   r6   r7   r9   r:   r;   r   r<   r=   r>   r?   r@   rA   rB   r/   )r   r   r   r   rC   rD   Úmul_lastrF   rG   rH   rJ   Úadd_1ÚjÚmul_7978ÚkÚmul_before_add_1ÚanotherÚmul_0447ÚmrN   rO   s                        r   r   zFusionFastGelu.fuse_3ÿ   sé  € ð  Ô˜AÔÐ&9Ð9Ð9ØˆFà& yÔ'7¸Ô':Ô;ˆÝˆx‰=Œ=˜AÒÐ ¨!¤Ô!4¸Ò!=Ð!=ØˆFØ! !œˆàŒz×,Ò,¨^¸SÑAÔAð 	ØˆFàÔ  Ô#Ð+>Ð>Ð>ØˆFØ& ~Ô'<¸QÔ'?Ô@ˆÝˆx‰=Œ=˜AÒÐ ¨!¤Ô!4¸Ò!=Ð!=ØˆFØ˜A”;ˆà”:×*Ò*¨8°U¸DÐBUÑVÔVˆØÐØˆFàŒJ×*Ò*¨8°SÑ9Ô9ˆØˆqŠ5ˆ5ØˆFà”^¨¨aª¨ A A°QÔ7ˆ
àœ*×1Ò1°)¸UÀAÐGZÑ[Ô[ˆØÐ"ØˆFà”
×'Ò'¨¸ÀÐFYÑZÔZˆØˆ=ØˆFØŒJ×*Ò*¨5°#Ñ6Ô6ˆØˆqŠ5ˆ5ØˆFà”:×*Ò*¨?¸EÀ4ÐI\Ñ]Ô]ˆØÐØˆFØŒJ×*Ò*¨8°VÀ6Ð*ÑJÔJˆØˆqŠ5ˆ5ØˆFØŒ>˜q Ašv˜v˜!˜!¨1Ô-°Ò;Ð;ØˆFàœ:×2Ò2°5¸%ÀaÈ1ÂfÀfÀÀÐRSÐUhÑiÔiÐØÐ#ØˆFàÔ! !Ô$¨
Ò2Ð2ØˆGˆGØÔ# AÔ&¨*Ò4Ð4ØˆGˆGàˆFà”:×*Ò*Ð+;¸UÀGÐM`ÑaÔaˆØÐØˆFØŒJ×*Ò*¨8°VÀ6Ð*ÑJÔJˆØˆqŠ5ˆ5ØˆFàŒ>˜q Ašv˜v˜!˜!¨1Ô-°Ò;Ð;ØˆFð ØØØØØØØØð

ˆð Œz×/Ò/ØØŒ_˜QÔÐ ØØñ	
ô 
ð 	ð ˆFàÔ×#Ò# NÑ3Ô3Ð3ÝÔ%ØØ�<Ø”OØ”×,Ò,¨ZÑ8Ô8ð	
ñ 
ô 
ˆ
ð ,ˆ
ÔØÔ× Ò  Ñ,Ô,Ð,Ø8<Ô8LˆÔ$ Z¤_Ñ5Øˆtr   c           	      óJ  — |j         d         |vrdS ||j         d                  }t          |¦  «        dk    s|d         j        dk    rdS |d         }| j                             |d¦  «        sdS |j         d         |vrdS ||j         d                  }t          |¦  «        dk    s|d         j        dk    rdS |d         }|j         d         |vrdS ||j         d                  }t          |¦  «        dk    s|d         j        dk    rdS |d         }| j                             |d¦  «        sdS |j        |j        d         |j         d         k    rdnd         }| j                             |dd|¦  «        }	|	€dS | j                             |	dd	¬
¦  «        }
|
dk     rdS | j                             |	d|
dk    rdnd|¦  «        }|€dS |j        d         |k    rd}n|j        d         |k    rd}ndS | j                             |d||¦  «        }|€dS | j                             |dd	¬
¦  «        }|dk     rdS | j                             |d|dk    rdnd|¦  «        }|€dS |j        d         |k    rd}n|j        d         |k    rd}ndS | j                             |d||¦  «        }|€dS |j        d         |k    s|j        d         |k    rdS |||||	||||g	}| j                             ||j         d         g||¦  «        sdS | j	         
                    |¦  «         t          j        d|g|j         | j                             d¦  «        ¬¦  «        }d|_        | j                             |¦  «         | j        | j        |j        <   |                      d¦  «         dS )aR  
        PyTorch's gelu implementation with tanh approximation:
           Gelu(x) = 0.5 * x * (1 + torch.tanh(0.7978845834732056 * (x + 0.044714998453855515 * x * x * x)))

        Fuse Gelu with tanh into one node:
              +-----------------+------------------+
              |                 |                  |
              |                 v                  v
            [root] ==> Mul --> Mul --> Mul -----> Add  --> Mul --> Tanh --> Add -----> Mul --> Mul -->
              |                       (A=0.0447)          (A=0.7978)        (A=1)       ^     (A=0.5)
              |                                                                         |
              +-------------------------------------------------------------------------+
        Note that constant input for Add and Mul could be first or second input.
        r   Nr   r   r    r!   r"   r#   g{®Gáz„?r%   r)   r   r,   r0   T)r1   r2   r3   r	   r4   r7   r5   r6   r9   r:   r;   r   r<   r=   r>   r?   r@   rA   rB   r/   Úincrease_counter)r   r   r   r   rC   rD   rE   rF   rH   rJ   rW   rK   rY   rL   r[   Ú	mul_cubedÚmul_squaredrN   rO   s                      r   r   zFusionFastGelu.fuse_4s  sC  € ð Ô˜AÔÐ&9Ð9Ð9ØˆFà& yÔ'7¸Ô':Ô;ˆÝˆx‰=Œ=˜AÒÐ ¨!¤Ô!4¸Ò!=Ð!=ØˆFØ! !œˆàŒz×,Ò,¨^¸SÑAÔAð 	ØˆFàÔ  Ô#Ð+>Ð>Ð>ØˆFØ& ~Ô'<¸QÔ'?Ô@ˆÝˆx‰=Œ=˜AÒÐ ¨!¤Ô!4¸Ò!=Ð!=ØˆFØ! !œˆàÔ  Ô#Ð+>Ð>Ð>ØˆFØ& ~Ô'<¸QÔ'?Ô@ˆÝˆx‰=Œ=˜AÒÐ ¨!¤Ô!4¸Ò!=Ð!=ØˆFØ˜A”;ˆàŒz×,Ò,¨X°sÑ;Ô;ð 	ØˆFà#Ô)¨~Ô/CÀAÔ/FÈ.ÔJ_Ð`aÔJbÒ/bÐ/b¨!¨!ÐhiÔjˆ
àœ*×1Ò1°)¸UÀAÐGZÑ[Ô[ˆØÐ"ØˆFàŒJ×*Ò*¨?¸FÈ$Ð*ÑOÔOˆØˆqŠ5ˆ5ØˆFàœ*×1Ò1°/À5ÈqÐTUÊvÈvÈ!È!Ð[\Ð^qÑrÔrˆØÐ"ØˆFàÔ  Ô# zÒ1Ð1ØˆGˆGØÔ" 1Ô%¨Ò3Ð3ØˆGˆGàˆFàœ
×/Ò/°ÀÈÐQdÑeÔeˆØÐ ØˆFàŒJ×*Ò*¨=¸&ÈÐ*ÑMÔMˆØˆqŠ5ˆ5ØˆFà”J×+Ò+¨M¸5ÀqÈAÂvÀvÀ!À!ÐSTÐViÑjÔjˆ	ØÐØˆFàŒ?˜1Ô Ò+Ð+ØˆGˆGØŒ_˜QÔ :Ò-Ð-ØˆGˆGàˆFà”j×-Ò-¨i¸ÀÐI\Ñ]Ô]ˆØÐØˆFàÔ˜QÔ :Ò-Ð-°Ô1BÀ1Ô1EÈÒ1SÐ1SØˆFð ØØØØØØØØð

ˆð Œz×/Ò/ØØŒ_˜QÔÐ ØØñ	
ô 
ð 	ð ˆFàÔ×#Ò# NÑ3Ô3Ð3ÝÔ%ØØ�<Ø”OØ”×,Ò,¨ZÑ8Ô8ð	
ñ 
ô 
ˆ
ð ,ˆ
ÔØÔ× Ò  Ñ,Ô,Ð,Ø8<Ô8LˆÔ$ Z¤_Ñ5Ø×Ò˜jÑ)Ô)Ð)Øˆtr   )Ú__name__Ú
__module__Ú__qualname__r   r   Údictr   Úboolr   r   r   r   Ú__classcell__)r   s   @r   r   r      s:  ø€ € € € € ð4˜ið 4ð 4ð 4ð 4ð 4ð 4ð°4ð Èdð ð ð ð ðjÈTÐTXÉ[ð jð jð jð jðXr°Tð rÐPTð rÐY]Ð`dÑYdð rð rð rð rðhr°Tð rÐPTð rÐY]Ð`dÑYdð rð rð rð rðhy°Tð yÐPTð yÐY]Ð`dÑYdð yð yð yð yð yð yð yð yr   r   N)Úloggingr   Úfusion_baser   Úonnxr   Ú
onnx_modelr   r`   Úloggerr   © r   r   ú<module>rl      sœ   ðð
 Ð Ð Ð Ð Ð à Ð Ð Ð Ð Ð Ø Ð Ð Ð Ð Ð Ø  Ð  Ð  Ð  Ð  Ð  à	ˆ�8Ñ	Ô	€ð^ð ^ð ^ð ^ð ^�Vñ ^ô ^ð ^ð ^ð ^r   