
    g(                     v    d dl mZ 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)Tuple)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        c/var/www/openai/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      }|y |\  }}}}}}| j                   j	                  |g d
g d      }|t
        j                  d       y |\  }}}}}d }g }d }| j                   j	                  |g dg d|      }| j                   j	                  |ddgddg      }|#|}t        |      d	k(  sJ d	|d   z
  }|\  }}}}}n ||}|\  }}nt
        j                  d       y | j                   j	                  |g dg d      }|t
        j                  d       y |\  }}}} }!}"| j                   j	                  |g dg d      }#|#t
        j                  d       y |#\  }$}%}}}&}'|"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 |}*|c| j                   j	                  |g ddddddg      }+|+<| j                   j	                  |g d|ddddg      }+|+t
        j                  d       y | j                  d |"|'||!|&||(|)||*j                  d   d d |d u      },|,y | j                  j                  |,       | j                  | j                  |,j                  <   | j                   j#                  |*|g       d| _        y ) N)r    r   r   r   )r   r    AddLayerNormalizationF)r2   MatMulReshape	Transposer5   r4   r    )r5   r6   r5   r2   r4   )r    r   r   r   Nz&fuse_attention: failed to match v path)Softmaxr5   r2   r5   r4   )r   r   r   Nr   )return_indicer7   r4   z'fuse_attention: failed to match qk path)r5   r6   r5   Mulr2   r4   )r   r   r   r   NNz&fuse_attention: failed to match q path)r6   r5   r6   r5   r2   r4   )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)r   Expand	Unsqueezer;   WhereLess)r:   r;   r;   r<   r=   z4fuse_attention: failed to match causal mask subgraph)
mask_indexq_matmulk_matmulv_matmulq_addk_addv_addr   r   r&   output
add_qk_strscalecausalT)r   r$   rE   find_first_child_by_typematch_parent_pathr)   debugr%   r&   r0   create_attention_nodenodes_to_addappendthis_graph_namenode_name_to_graph_namenamenodes_to_removeextend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	reshape_vadd_vmatmul_vadd_maskadd_mask_indicesqk_nodes
qk_nodes_1
qk_nodes_2causal_mask_input_index_softmax_qk	matmul_qkq_nodes_transpose_qr   mul_qadd_qmatmul_qk_nodes_transpose_k
_reshape_kadd_kmatmul_kr   r   attention_last_nodecausal_mask_nodesnew_nodes-                                                r   fusezFusionAttentionClip.fuseU   s   !%AZZ,,^=UWXYF!#$ )/&	  
!-/66q9J )-&+/::+B+B>SXZ[+\(+/::+B+B>Sgij+k(+7 .F*-9 .F*)1

;;*,@BUW\ ="\\!_
#$ K N  'JJ00J!!4q!Q7
	
 <E9A{M1j**..LN`
 ?LLAB-4*Ay%ZZ11>*	 2 

 ZZ11!F


 !!H'(A---&'*:1*=&=#7?4[!Xq)#!H'/$[)LLBC**..RTl
 ?LLAB?F<L)UE8**..XZo
 ?LLAB<C9z1a>>!
*hnnQ.?:.MQYQ_Q_`aQbfpQpLLYZ!%!C!CI!N	;>[A-LLTU) !%

 < <O(!Q1a8!
 !($(JJ$@$@I,aAq9%!
 %,LL!WX--#&--a0D( . 
    *6:6J6J$$X]]3##%8-$HI  r   )__name__
__module____qualname____doc__r	   intr   r   r   r0   r~   __classcell__)r   s   @r   r   r      sL    

 
 	
$,&y ,&U3PS8_ ,&\l r   r   N)loggingr   typingr   fusion_attentionr   r   fusion_optionsr   onnxr   
onnx_modelr	   r   r)   r    r   r   <module>r      s1   
   ; .   	8	q / q r   