
    Bvhv4                     j    d dl mZ d dlmZ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y)	    )	getLogger)AttentionMaskFusionAttention)AttentionMaskFormat)	NodeProto)	OnnxModelc                   P     e Zd ZdZdededef fdZdedeeef   fdZ	d	 Z
 xZS )
FusionAttentionClipzB
    Fuse Attention subgraph of Clip into one Attention node.
    modelhidden_size	num_headsc                 r    t        |      }t        j                  |_        t        |   ||||ddg       y )NFSkipLayerNormalization)use_multi_head_attentionsearch_op_types)r   r   NoMaskmask_formatsuper__init__)selfr   r   r   attention_mask	__class__s        X/RAG/venv/lib/python3.12/site-packages/onnxruntime/transformers/fusion_attention_clip.pyr   zFusionAttentionClip.__init__   sD     'u-%8%?%?"%*56 	 	
    	reshape_qreturnc                    | j                   j                  |dd      }|t        |j                        dk7  r| j                  | j
                  fS | j                   j                  |j                  d         }|| j                  | j
                  fS t        |      dk7  s|d   dk  r| j                  | j
                  fS |d   }| j                   j                  |j                  d         }|| j                  | j
                  fS t        |      dk7  s|d   dk  r| j                  | j
                  fS |d   }||z  }| j                  dkD  rH|| j                  k7  r9| j                  r-t        j                  d| j                   d| d	       d
| _        | j
                  dkD  rH|| j
                  k7  r9| j                  r-t        j                  d| j
                   d| d	       d
| _
        ||fS )zDetect num_heads and hidden_size for ONNX model from MiDaS
        Args:
            reshape_q (NodeProto): reshape node for q
        Returns:
            Tuple[int, int]: num_heads and hidden_size
        Concat         r      z--num_heads is z. Detected value is z. Using detected value.Fz--hidden_size is )r   match_parentleninputr   r   get_constant_valuenum_heads_warningloggerwarninghidden_size_warning)r   r   concatnum_head_valuer   head_size_value	head_sizer   s           r   get_num_heads_and_hidden_sizez1FusionAttentionClip.get_num_heads_and_hidden_size&   s    ((Ha@>S.!3>>4#3#333 66v||AG!>>4#3#333~!#~a'8A'=>>4#3#333"1%	**77QH">>4#3#3331$(:a(?>>4#3#333#A&	)+>>A)t~~"=%%0@@TU^T__vwx).&aK43C3C$C'''(8(8'99Mk]Zqr ,1(+%%r   c                 
   d }d }dD ]&  }| j                   j                  |d|      }|#|}|}( d }||j                  d   }ndD ]}  }d }| j                   j                  |d|      }	| j                   j                  |d|      }
|	|	}n|
|
}|K| j                   j                  |d|d      }|l|j                  d   }|} n |y | j                   j	                  |g dd	|z
  d d dddg      }|9| j                   j	                  |g d
g d      }|t
        j                  d       y |d   |d   |d   }}}| j                   j	                  |g dg d      }|9| j                   j	                  |g dg d      }|t
        j                  d       y |d   |d   }}d }d }g }| j                   j	                  |g dg d|      }|| j                   j	                  |ddgddg      }|| j                   j	                  |g dg d      }||d	   }n| j                   j	                  |g dg d      }|| j                   j	                  |g dg d       }||d   }nV| j                   j	                  |g d!g d"      }|3t
        j                  d#       y t        |      d	k(  sJ d	|d   z
  }|d   }|d   }| j                   j	                  |g d$g d%      }|?| j                   j	                  |g dg d&      }|t
        j                  d'       y |d	   }n|d   }|d   |d   }}| j                   j	                  |g d(g d)      }|9| j                   j	                  |g dg d      }|t
        j                  d*       y |d   |d   }}|j                  d   |k7  s$|j                  d   |k7  s|j                  d   |k7  rt
        j                  d+       y | j                  |      \  }} |dk  s| dk  rt
        j                  d,       y |}!d-}"|| j                   j	                  |g d.g d/      }#|#|j                  d	   }"nc| j                   j	                  |g d0|dddddg      }$| j                   j	                  |g d1|ddddg      }%|$|%t
        j                  d2       y | j                  d |||||||| ||!j                  d   |"d |d u3      }&|&t
        j                  d4       y | j                  j                  |&       | j                  | j                  |&j                  <   | j                   j#                  |!|g       | j%                  |&j&                         d5| _        y )6N)r   r   r   r   )r   r   AddLayerNormalizationF)r1   MatMulReshape	Transposer4   r3   r   )r1   r3   r4   r5   r3   )r   Nr   r   r   z(fuse_attention: failed to match qkv pathr!   r"   )r4   r5   r4   r1   r3   )r   r   r   r   N)r5   r4   r1   r3   )r   r   r   Nz&fuse_attention: failed to match v path)Softmaxr4   r1   r4   r3   )r   r   r   Nr   )return_indicer8   r3   )r8   r1   Mulr3   )r   r   r   r   )r8   r:   r3   )r   r   r   )Castr;   r8   r1   r:   r3   )r   r   r   r   r   r   )r;   r;   r8   r:   r3   )r   r   r   r   r   z'fuse_attention: failed to match qk path)r4   r5   r4   r:   r1   r3   )r   r   r   r   NN)r   r   r   Nz&fuse_attention: failed to match q path)r5   r4   r5   r4   r1   r3   )r   r   r   r   r   Nz&fuse_attention: failed to match k pathz>fuse_attention: expect to have same input to q, k and v matmulz9fuse_attention: failed to detect num_heads or hidden_size )	WhereSubr;   Expand	Unsqueezer@   r4   r4   r;   )	r   r!   r   r   r   r   r   r   r   )r   r?   r@   r@   r=   Less)r?   r@   r@   r=   rA   z4fuse_attention: failed to match causal mask subgraph)
mask_indexq_matmulk_matmulv_matmulq_addk_addv_addr   r   first_inputoutput
add_qk_strscalecausalz+fuse_attention: failed to create fused nodeT)r   r#   rJ   find_first_child_by_typematch_parent_pathr(   debugr$   r%   r/   create_attention_nodenodes_to_addappendthis_graph_namenode_name_to_graph_namenamenodes_to_removeextendincrease_counterop_typeprune_graph)'r   normalize_nodeinput_name_to_nodesoutput_name_to_nodeskip_input_indexnode_before_layer_normiparent
root_inputnode_before_layer_norm_1node_before_layer_norm_2child	qkv_nodesreshape_qkvtranspose_qkv
matmul_qkvv_nodesadd_vmatmul_vcausal_mask_input_indexadd_maskadd_mask_indicesqk_nodes	matmul_qkq_nodesr   add_qmatmul_qk_nodesadd_kmatmul_kr   r   attention_last_nodeadd_qkadd_qk_nodescausal_mask_nodes_1causal_mask_nodes_2new_nodes'                                          r   fusezFusionAttentionClip.fuseT   sK   !%AZZ,,^=UWXYF!#$ )/&	  
!-/66q9J )-&+/::+B+B>SXZ[+\(+/::+B+B>Sgij+k(+7 .F*-9 .F*)1

;;*('	 ="\\!_
#$ Q T  'JJ00J!!4q!Q7
	
 

44C"I
  GHaLaLbM %/] **..@

 ?jj22EG EF!"+wr{x"&:://>*	 0 
 zz33H%AH
 ::77
Dgiuv''{H  $zz;;JHdfopH'#'::#?#?&O.$
 $/'/{H (,zz'C'C * L /(H
  (/ &-V W &'(A---&'*:1*=&=#{HRL	**..G$

 ?jj22DoG EF
I
I!"+wr{x**..M!

 ?jj22DoG EF!"+wr{x>>!
*hnnQ.?:.MQYQ_Q_`aQbfpQpLLYZ!%!C!CI!N	;>[A-LLTU)::77
 ,L '!* '+jj&B&BS,aAq!<'# '+jj&B&BI,aAq9'#
 '.3F3NLL!WX--#"&--a0D( . 
  LLFG  *6:6J6J$$X]]3##%8-$HIh../  r   )__name__
__module____qualname____doc__r   intr   r   tupler/   r   __classcell__)r   s   @r   r
   r
      sL    

 
 	
$,&y ,&U3PS8_ ,&\{ r   r
   N)loggingr   fusion_attentionr   r   fusion_optionsr   onnxr   
onnx_modelr   r   r(   r
    r   r   <module>r      s.   
  ; .   	8	@ / @ r   