
    Bvh                     Z    d dl 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)Fusion)NumpyHelper)	OnnxModelc                   @     e Zd Zdef fdZ fdZd Zd Zd Z xZ	S )FusionConstantFoldmodelc                 8    t         |   |ddg       d| _        y )N 	Transposer   )super__init__count)selfr	   	__class__s     W/RAG/venv/lib/python3.12/site-packages/onnxruntime/transformers/fusion_constant_fold.pyr   zFusionConstantFold.__init__   s    [M2
    c                     t         |           | j                  dkD  r#t        j	                  d| j                          y y )Nr   zConstant Folded: )r   applyr   loggerinfo)r   r   s    r   r   zFusionConstantFold.apply   s4    ::>KK+DJJ<89 r   c                 P    | j                  |||       | j                  |||       y)zX
        Apply multiple fusions on Transpose nodes that can be constant folded.
        N)fuse_1fuse_2)r   nodeinput_name_to_nodesoutput_name_to_nodes       r   fusezFusionConstantFold.fuse   s(     	D-/BCD-/BCr   c                    t        |j                        dk7  st        |j                        dk7  rt        j	                  d       y| j
                  j                  |j                  d         }|t        j	                  d       yd}||j                  d      D ]-  }|j                  dk(  rt        |j                        dk(  r+d} n |rt        j	                  d	       y||j                  d      D ]%  }|j                  d
k(  r|j                  dk(  r#d} n |rt        j	                  d       yt        j                  |      }t        |j                        dk7  rt        j	                  d       y|j                  }|j                  }	| j                  |       | j                  ||	|j                  d   |j                  d   g|j                         ||j                  d      D ]  }t!        t        |j                              D ]  }
|j                  |
   |j                  d   k(  s#|j                  d   |j                  |
<   |j                  d
k(  sO|
dk(  s|
dk(  sZ|
dk(  rdnd}t#        |j$                        D ])  \  }}|j                  |k(  sd|j$                  |   _        +   | j(                  j+                  |       | xj,                  dz  c_        y)z
        Constant fold any initializer data representing a MatMul's
        weights that are stored in a Transpose op

        Ex: Transpose --> Gemm or Transpose --> MatMul
           :fuse_constant_fold: node has more than one input or outputNr   z8fuse_constant_fold: failed to identify initializer inputFr   TzAfuse_constant_fold: other non-Transpose nodes use the initializerGemmMatMulzOfuse_constant_fold: other non-Gemm and non-MatMul nodes use the transposed data   z7fuse_constant_fold: shape of initializer data is not 2D)name	data_typedimsvalstransAtransB)leninputoutputr   debugr	   get_initializerop_typer   to_arrayshaper%   r&   remove_initializeradd_initializerTrange	enumerate	attributeinodes_to_removeappendr   )r   r   r   r   protoskip
child_nodeweightr%   dtyper9   keyjattr_keys                 r   r   zFusionConstantFold.fuse_1    s    tzz?a3t{{#3q#8LLUV 

**4::a=9=LLST -djjm<J&&+5#djj/Q:N = LL\] .dkk!n=J&&&0J4F4F(4R > LLjk %%e,v||!LLRS zz&,,q/6<<?3	 	 	
 .dkk!n=J3z//01##A&$++a.8*.**Q-J$$Q'!))V3a16*+q&hh+4Z5I5I+JKAx'}}3<=
 4 4Q 7 9 ,K 2 > 	##D)

a
r   c                    t        |j                        dk7  st        |j                        dk7  rt        j	                  d       y| j
                  j                  |dd      }|t        j	                  d       yt        |j                        dk7  st        |j                        dk7  rt        j	                  d       y|j                  d   j                  }|j                  d   j                  }||k7  rt        j	                  d       y|j                  d   }||j                  d      }|D ]A  }	t        |	j                        D ]'  \  }
}||j                  d   k(  s||	j                  |
<   ) C | j                  j                  |       | j                  j                  |       | xj                  dz  c_        y)	z
        Constant fold any Transpose --> Transpose ops since the root input
        is the final result

        Ex: root_input --> Transpose --> Transpose --> next_node to root_input --> next_node
        r    r!   Nr   r   z<fuse_constant_fold: failed to identify parent Transpose nodezAfuse_constant_fold: parent node has more than one input or outputz@fuse_constant_fold: Transpose node permutations aren't identical)r+   r,   r-   r   r.   r	   match_parentr8   intsr7   r:   r;   r   )r   r   r   r   parent_node	node_permparent_node_perm
root_inputoutput_nodesoutput_noder9   input_s               r   r   zFusionConstantFold.fuse_2h   s{    tzz?a3t{{#3q#8LLUV jj--dKCLLWX{  !Q&#k.@.@*AQ*FLL\]NN1%**	&00388((LL[\ !&&q)
*4;;q>:'K&{'8'89	6T[[^++5K%%a( : ( 	##D)##K0

a
r   )
__name__
__module____qualname__r   r   r   r   r   r   __classcell__)r   s   @r   r   r      s&    i :
DFP(r   r   N)loggingr   fusion_baser   fusion_utilsr   
onnx_modelr   rN   r   r    r   r   <module>rW      s+      $  	8	A Ar   