U
    T?h(                     @   st   d dl mZ d dlmZmZmZ d dlmZ d dlm	Z	 d dl
mZmZmZ d dlmZ eeZG dd deZd	S )
    )	getLogger)DictListUnion)Fusion)NumpyHelper)	NodeProtoTensorProtohelper)	OnnxModelc                       sx   e Zd Zed fddZeeedf dddZe	eedf dd	d
Z
eee	ee f ee	ef dddZ  ZS )FusionGemmFastGelu)modelc                    s"   t  |ddd d | _d| _d S )NGemmFastGeluZFastGeluF)super__init__shape_infershape_infer_done)selfr   	__class__ ^/var/www/html/venv/lib/python3.8/site-packages/onnxruntime/transformers/fusion_gemmfastgelu.pyr      s    zFusionGemmFastGelu.__init__N)tensor_protoreturnc                 C   s&   |j jdrt|j jjjS d S d S )Nshape)typeZtensor_typeZHasFieldlenr   dim)r   r   r   r   r    get_dimensions_from_tensor_proto   s    z3FusionGemmFastGelu.get_dimensions_from_tensor_proto)
input_namer   c                 C   sV   | j |}|r| |S | js6| j jdd| _d| _| jd k	rR| | jj| S d S )NT)update)r   Zfind_graph_inputr   r   Zinfer_runtime_shaper   Z	known_vi_)r   r   Zgraph_inputr   r   r   get_dimensions   s    

z!FusionGemmFastGelu.get_dimensions)nodeinput_name_to_nodesoutput_name_to_nodec                 C   s  d}t |jdkrd}| j|dgdg}|dkr6dS |d }d}d}d}	t|jD ]<\}
}| j|}|dkr| |j|
 }qT|
}t|}	qT|	dkrdS t |	j	dkrdS |t |	j	k rdS d}|r0d}t|jD ]2\}
}| j|}|dkrq|
}t|} qq|dkrdS t |j	dkr0dS ||g}| j
||jd g||sXdS | j| |r|jd|  |j| |j| gn|jd|  |j| g}tjd	||j| jd	d
}d|_| j| | j| j|j< dS )z
        This pattern is from PyTorch bert model
        Fuse MatMul with FastGelu into one node:

            [root] --> MatMul --> FastGelu -->

        F   TZMatMulr   N   r   )inputsoutputsnamezcom.microsoft)r   inputr   Zmatch_parent_path	enumerateZget_initializerr!   r   Zto_arrayr   Zis_safe_to_fuse_nodesoutputZnodes_to_removeextendr
   Z	make_nodeZcreate_node_namedomainZnodes_to_addappendZthis_graph_nameZnode_name_to_graph_namer*   )r   r"   r#   r$   Zhas_biasZmatch_nodesmatmulZweight_indexZx_dimsweightir+   ZinitializerZ
bias_indexZbias_weightZsubgraph_nodesr(   Z
fused_noder   r   r   fuse+   st    

 
  $
zFusionGemmFastGelu.fuse)__name__
__module____qualname__r   r   r	   r   intr   strr!   r   r   r   r4   __classcell__r   r   r   r   r      s   
r   N)loggingr   typingr   r   r   Zfusion_baser   Zfusion_utilsr   Zonnxr   r	   r
   Z
onnx_modelr   r5   loggerr   r   r   r   r   <module>   s   