o
    i̖iE                     @   sL   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 deZ
dS )    )	getLogger)Fusion)helper)	OnnxModelc                       s   e Zd Zdef fddZdedefddZded	B fd
dZdededed	B fddZ	dededed	B fddZ
dededed	B fddZ  ZS )FusionFastGelumodelc                    s   t  |dd d S )NFastGeluTanh)super__init__)selfr   	__class__ j/var/www/html/livekit_bhavya/venv/lib/python3.10/site-packages/onnxruntime/transformers/fusion_fastgelu.pyr      s   zFusionFastGelu.__init__input_name_to_nodesoutput_name_to_nodec                 C   sL   |  |||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   r   r   r   fuse   s   zFusionFastGelu.fusereturnNc                 C   s  |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r5dS ||j d  }t|dksI|d jdkrKdS |d }| j|dd|}|du r^dS | j|d}|dk rkdS |j|dkrsdnd }	| j||dkrdnd|}
| j|dd|}|du rdS | jj|dd	d
}|dk rdS | j|d|dkrdnd|}|du rdS | jj|dd||
r|
gng d}|du rdS | jj|dd	d
}|dk rdS | j|d|dkrdnd|}|du rdS | j|dsdS |jd |	krdS ||||||||g}| j	||j d g||sdS | j
| tjd|	g|j | jd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_noder   r   r   r      s   


zFusionFastGelu.fuse_1c                 C   s  |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r5dS ||j d  }t|dksI|d jdkrKdS |d }| j|d}|dk r\dS |j d |vredS ||j d  }t|dksy|d jdkr{dS |d }| j||jd |j d krdnd|}	| j|dd|}
|
du rdS | jj|
dd	d
}|dk rdS | j|
d|dkrdnd|}|du rdS | jj|dd||	r|	gng d}|du rdS | jj|dd	d
}|dk rdS | j|d|dkrdnd|}|du r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||sAdS | j
| tjd|g|j | jd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(   r,   T)r-   r.   r/   r   r0   r2   r4   r3   r1   r5   r6   r7   r   r8   r9   r:   r;   r<   r=   r>   r+   )r   r   r   r   r?   r@   rB   rC   mul_after_mul_halfrE   rF   rG   rH   rI   rD   rJ   rK   r   r   r   r      s   
$


zFusionFastGelu.fuse_2c              	   C   s  |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r5dS ||j d  }t|dksI|d jdkrKdS |d }| j|dd|}|du r^dS | j|d}|dk rkdS |j|dkrsdnd }	| j|dd|}
|
du rdS | j|
dd|}|du rdS | j|d}|dk rdS | j|
dd|}|du rdS | jj|dd	d
}|dk rdS |j|dkrdnd |	krdS | j|d|dkrdnd|}|du rdS |jd |	krd}n|jd |	krd}ndS | j|d||}|du r	dS | jj|dd	d
}|dk rdS |j|dkr"dnd |	kr*dS ||||
|||||g	}| j||j d g||sEdS | j	
| tjd|	g|j | jd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(   r,   T)r-   r.   r/   r   r0   r1   r2   r3   r5   r6   r7   r   r8   r9   r:   r;   r<   r=   r>   r+   )r   r   r   r   r?   r@   mul_lastrB   rC   rD   rF   add_1jmul_7978kmul_before_add_1anothermul_0447mrJ   rK   r   r   r   r      s   



zFusionFastGelu.fuse_3c              	   C   s  |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r5dS ||j d  }t|dksI|d jdkrKdS |d }|j d |vrXdS ||j d  }t|dksl|d jdkrndS |d }| j|ds{dS |j|jd |j d krdnd }| j|dd|}	|	du rdS | jj|	dd	d
}
|
dk rdS | j|	d|
dkrdnd|}|du rdS |jd |krd}n|jd |krd}ndS | j|d||}|du rdS | jj|dd	d
}|dk rdS | j|d|dkrdnd|}|du r	dS |jd |krd}n|jd |krd}ndS | j|d||}|du r1dS |jd |ksA|jd |krCdS |||||	||||g	}| j||j d g||s^dS | j	
| tjd|g|j | jd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{Gz?r!   r%   r   r(   r,   T)r-   r.   r/   r   r0   r3   r1   r2   r5   r6   r7   r   r8   r9   r:   r;   r<   r=   r>   r+   increase_counter)r   r   r   r   r?   r@   rA   rB   rD   rF   rQ   rG   rS   rH   rU   	mul_cubedmul_squaredrJ   rK   r   r   r   r   s  s   "

 


zFusionFastGelu.fuse_4)__name__
__module____qualname__r   r   dictr   boolr   r   r   r   __classcell__r   r   r   r   r      s    lt"tr   N)loggingr   fusion_baser   onnxr   
onnx_modelr   rY   loggerr   r   r   r   r   <module>   s   