U
    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__ P/tmp/pip-unpacked-wheel-socb9apf/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   Zdim)r   r   r   r   r    get_dimensions_from_tensor_proto   s    z3FusionGemmFastGelu.get_dimensions_from_tensor_proto)
input_namer   c                 C   sX   | j |}|r| |S | js8| j ji dd| _d| _| jd k	rT| | 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_dimsZ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   r2   __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   r3   loggerr   r   r   r   r   <module>   s   