o
    ;ήceA                     @   s   d dl mZ d dlmZ d dlZd dlmZ d dlm	Z	 d dl
mZmZ d dlmZmZ d dlmZ eeZG d	d
 d
e	ZdS )    )	getLogger)TupleN)AttentionMask)Fusion)FusionUtilsNumpyHelper)	NodeProtohelper)	OnnxModelc                       sP   e Zd Zdedededef fddZdedeeef fd	d
Z	dd Z
  ZS )FusionQOrderedAttentionmodelhidden_size	num_headsattention_maskc                    s&   || _ || _|| _t |dd d S )NQOrderedAttentionQOrderedLayerNormalization)r   r   r   super__init__)selfr   r   r   r   	__class__ Y/tmp/pip-target-vg8gfxp4/lib/python/onnxruntime/transformers/fusion_qordered_attention.pyr      s   z FusionQOrderedAttention.__init__	reshape_qreturnc                 C   sf  | j |jd }|du rCt|jd  d | j |dgdg}|du r,| j| jfS |d }t|j	dkr=| j| jfS |j	d j
}t|}t|dksZ|d dksZ|d dkritd	| d
 | j| jfS |d }|d }|| }| jdkr|| jkr| jrtd| j d| d d| _| jdkr|| jkr| jrtd| j d| d d| _||fS )zDetect num_heads and hidden_size from a reshape node.
        Args:
            reshape_q (NodeProto): reshape node for Q
        Returns:
            Tuple[int, int]: num_heads and hidden_size
           Nz is not initializer.Constantr            zq_shape_value=z7. Expected value are like [0, 0, num_heads, head_size].z--num_heads is z. Detected value is z. Using detected value.Fz--hidden_size is )r   get_initializerinputloggerdebugmatch_parent_pathr   r   len	attributetr   to_arraynum_heads_warningwarninghidden_size_warning)r   r   q_shapeconstant_nodeq_shape_valuer   	head_sizer   r   r   r   get_num_heads_and_hidden_size!   s8   	
$z5FusionQOrderedAttention.get_num_heads_and_hidden_sizec           B      C   sr  | j |ddgddg}|d ur|d }nd S | j |dgd g}|d u r,td d S |d }| j |g dg d}|d u rGtd	 d S |\}}	}
}}}}t|| j sYd S t|| j sbd S g }t|jD ]\}}||vrrqi||d jd kr|qi|	| qit
|d
krd S |d }| j |g dg d}|d u rtd d S |\}}}}}}t|| j sd S t|| j sd S | j |dgd
g}|d u rtd d S |d }| j |jd d u rd S t|| j dsd S | j |g dg d}|d u rtd d S |\}}}}}}} }!t|| j sd S t|| j s%d S t| | j s/d S t|| j s9d S | j |!g dg d}"|"d u rQtd d S |"\}}#}$}%}&}'t|%| j scd S t|$| j smd S | j |'dgd
g}(|(d u rtd d S |(d }(| j |(jd d u rd S t|(| j dsd S | j |!g dg d})|)d u rtd d S |)\}}}*}+},}-t|+| j sd S t|*| j sd S | j |-dgd
g}.|.d u rtd d S |.d }.| j |.jd d u rd S t|.| j dsd S | j |g dg d}/|/d u rtd d S | j |(jd }0| j |.jd }1| j |jd }2t|0}3t|1}4t|2}5t|3jd
d  }6t|4jd
d  }7t|5jd
d  }8|jd |kr3|'jd |kr5|-jd |kr7| j|/d jd }9| |#\}:};|jd g}<|<	|jd
  |<	|$jd
  |<	|*jd
  |<	|jd
  |<	|(jd  |<	|.jd  |<	|jd  |<	|(jd
  |<	|.jd
  |<	|jd
  | j |&jd r|<	|&jd  n|<	|&jd
  | j |,jd r|<	|,jd  n|<	|,jd
  | j |jd r0|<	|jd  n|<	|jd
  |<	| jd
  |<	|jd
  |<	|jd
  |9d ur[|<	|9 n|<	d | j |(jd }=t|= | j |.jd }>t|> | j |jd }?t|? | j d}@tjd|<|
jd g|@d}A| j ||jd |Ajd  | j |	|	jd |jd  |Ajtd|:g |Ajtdd
g |Ajtddg |Ajtdd
g |Ajtd|6|7|8gg d |A_| j	|A | j| j |Aj!< | j"|
|||g | j"| | j"|" | j"|) | j"| | j"|(|.|g d!| _#d S d S d S d S )"NQuantizeLinearAddr   DequantizeLinearz=fuse_qordered_attention: failed to match input qdq nodes path)r2   MatMulReshape	Transposer4   r1   r5   )NNr   r   r   r   r   z1fuse_qordered_attention: failed to match qkv pathr   )r7   r6   r4   r1   r2   r5   )r   r   r   r   r   Nz/fuse_qordered_attention: failed to match v pathF)r4   r1   Softmaxr2   Divr4   r1   r5   )r   r   r   r   Nr   r   r   z0fuse_qordered_attention: failed to match qk path)r   r   r   r   r   Nz/fuse_qordered_attention: failed to match q pathz/fuse_qordered_attention: failed to match k path)MulSubCast	Unsqueezer=   )Nr   r   r   r   z8fuse_qordered_attention: failed to match mask_nodes path r   )inputsoutputsnamer   order_inputorder_weightorder_outputqkv_hidden_sizeszcom.microsoftT)$r   r$   r"   r#   r   check_qdq_node_for_fusion	enumerater!   outputappendr%   get_constant_valuer    r   r(   npprodshaper   process_maskr0   transpose_2d_int8_tensorcreate_node_namer	   	make_nodereplace_node_inputr&   extendmake_attributedomainnodes_to_addthis_graph_namenode_name_to_graph_namerA   nodes_to_removeprune_graph)Br   normalize_nodeinput_name_to_nodesoutput_name_to_nodeadd_before_layernorm
start_nodedequantize_input	qkv_nodes_projection_matmulreshape_qkvtranspose_qkvdequantize_qkvquantize_qkv
matmul_qkvother_inputsir!   
root_inputv_nodesdequantize_v
quantize_vadd_vmatmul_vdequantize_v_matmul_weightqk_nodesdequantize_qk_softmaxquantize_qk_softmax
softmax_qkadd_qkdiv_qkdequantize_qkquantize_qk	matmul_qkq_nodesr   dequantize_q
quantize_qadd_qmatmul_qdequantize_q_matmul_weightk_nodesdequantize_k
quantize_kadd_kmatmul_kdequantize_k_matmul_weight
mask_nodesq_weightk_weightv_weightqwkwvwqw_out_sizekw_out_sizevw_out_size
mask_indexr   r   attention_inputsq_weight_tensork_weight_tensorv_weight_tensorattention_node_nameattention_noder   r   r   fuseT   s  




















0






zFusionQOrderedAttention.fuse)__name__
__module____qualname__r
   intr   r   r   r   r0   r   __classcell__r   r   r   r   r      s    3r   )loggingr   typingr   numpyrK   fusion_attentionr   fusion_baser   fusion_utilsr   r   onnxr   r	   
onnx_modelr
   r   r"   r   r   r   r   r   <module>   s   