
    ёi                       S SK Jr  S SKrS SKrS SKrS SKrS SKJrJr  S SK	r
S SKrS SKJr  SSKJrJr  SSKJr  SSKJr  S	S
KJrJr  S	SKJrJrJr  S	SKJrJr  \(       a  S SK J!r!  S SKJ"r"  / r#S*S jr$S+S jr%        S,S jr&S-S jr'        S.S jr(        S/S jr)S0S jr*S1S jr+          S2S jr,S3S jr-                      S4S jr.                  S5S jr/S6S jr0        S7S jr1 " S S5      r2              S8S jr3        S9S  jr4      S:S! jr5 " S" S#\5      r6        S;S$ jr7S<S% jr8S=S& jr9S>S' jr:S>S( jr;S?S) jr<g)@    )annotationsN)TYPE_CHECKING
NamedTuple)_C_ops   )
check_typecheck_variable_and_dtype)in_dynamic_or_pir_mode)LayerHelper   )matmul	transpose)reshapesqueeze	unsqueeze)multiplysum)Sequence)Tensorc                x   U R                  SS5       H#  nUR                  5       (       a  M   SU S35       e   U R                  SSS5      R                  S5      S:X  d   S5       e[        UR                  5      nU R                  SSU[        U 5      -
  S	-   -  5      n[        U5      U:X  d   S
U  S35       eU$ )z
Parse labels for an input operand.

Parameters
----------
labelstr:
    the input label string
operand:
    the input operand

Returns
-------
the input operand's full label string in which all anonymous dimensions are
labeled in dots.
. zInvalid equation: z/ is not a valid label, which should be letters....r   z6Invalid equation: `.` is found outside of an ellipsis.   z$Invalid equation: the label string 'z' misses dimensions.)replaceisalphafindlenshape)labelstroperandcndimsfull_labelstrs        T/var/www/html/banglarbhumi/venv/lib/python3.13/site-packages/paddle/tensor/einsum.pyparse_op_labelsr'   -   s    " c2&yy{{ 	
 #RS	
{ '
 E2q)..s3r9 @9 E$$UC53x=3H13L,MNM}& 
.xj8LM&     c                    U R                  S5      n[        U5      [        U5      :X  d    S[        U5       S[        U5       S35       e[        [        [        X!5      5      $ )z
Parse label strings for all input operands.

Parameters
----------
labelstr:
    The equation's label string
operands:
    The input operands

Returns
-------
list of full label strings for all input operands
,,Invalid equation: the number of operands is , but found   segments in the label equation.)splitr   listmapr'   )r!   operands
nop_labelss      r&   parse_labelsr3   R   sg      $Jz?c(m+ 
6s8}o F_%%E	G+
 OZ:;;r(   c                
   US:  a  SU ;   d   S5       eU R                  SS5      n [        U 5      nSU;  d   eUR                  U5      nU(       a   S[        U5       S35       e[	        U 5      [	        U5      :X  d   S5       eg	)
z7
Check whether the equation's right hand side is valid
r   r   4Invalid equation: missing ellipsis in output labels.r   r   zInvalid equation: output label z not used by any input.z4Invalid equation: duplicate output labels are found.N)r   set
differencesortedr   )rhsinput_labelsn_bcast_dimsrhs_setnon_input_labelss        r&   validate_rhsr>   k   s     a| 	
B	
| ++eR
 C#hG l""" )),7 /011H	J
 s8s7|# >#r(   c           	     X   S/[        U5      -  n[        R                  " SU5      nUb  UR                  5       UR	                  5       pT[        R                  " SU 5      nU(       aT  [        [        XE5      SSS2   [        UR                  5       UR	                  5       5      SSS2   5       H	  u  pxXU'   M     [        R                  " [        U5      [        U[        U5      5      5      n	O[        [        [        U5      5      5      n	U	 H  n
U R                  X   5      X*'   M     U$ )a  
Build an inverse map of dimension indices. Three conditions must hold for
the result to be meaningful.
First, no duplicate letter labels in each label string.
Second, the number of dots in dimout_labels >= that in in_labels.
Third, dots are contiguous in each label string.

Parameters
----------
in_labels:
    The dimension labels to map to
out_labels:
    The dimension labels to map from

Returns
-------
The inverse map from out_labels to in_labels. The length of the inverse map equals that of
out_labels. -1 is filled if there's no matching input dimension for a specific label.

Examples
--------
in_labels = 'ij..', out_labels = '..ji'
inv_map = [2, 3, 1, 0]
in_labels = 'ij..', out_labels = '..kji'
inv_map = [2, 3, -1, 1, 0]
r   z\.+N)r   researchstartendziprange	itertoolschainiterr   )	in_labels
out_labelsinv_maprrB   rC   saxdimitis              r&   
build_viewrR      s    8 dS_$G 			&*%A}WWYsIIfi(e!$B$'qwwy!%%')B4R4)H "
 __U5\5c*o+FG%J()^^JM2
  Nr(   c                   [        SR                  U 5      R                  SS5      5      n/ / pT[        S/UQU5       H;  u  pgXg:w  a$  UR	                  U5        UR	                  S5        M.  US==   S-  ss'   M=     Ub"  [        XU5        UR                  SSU-  5      nO'SU-  SR                  S [        XE5       5       5      -   n[        [        U5      5      SSS2    H/  n	XI   U;   d  M  UR                  U	5        UR                  U	5        M1     SR                  U5      n
X-   nU  V	s/ s H  n	[        X5      PM     nn	[        U5      nUnXX4$ s  sn	f )a  
Build the global view, which is a layout of all dimension labels
plus an index table that maps from the layout to the dimensions
in each operand. In the global view, the dimensions are arranged
such that output ones are put on the left and contraction ones
are put on the right.

Parameters
----------
nop_labels:
    The input full label strings of all input operands
rhs:
    The equation right hand side
n_bcast_dims:
    The maximum number of broadcast dimensions

Returns
-------
A tuple of g_labels, g_view, g_nout, g_count
g_labels:
    the layout of all labels in a string
g_view:
    the index table
g_nout:
    the number of output dimensions
g_count:
    the counter array for dimension contractions
r   r   r   r   Nr   c              3  :   #    U  H  u  pUS :X  d  M  Uv   M     g7f)r   N ).0lr#   s      r&   	<genexpr>$build_global_view.<locals>.<genexpr>   s      4
,$!QAA,s   	)
r8   joinr   rD   appendr>   rE   r   poprR   )r2   r9   r;   concatlabelscountabg_labels_outrQ   g_labels_sumg_labelsg_viewg_noutg_counts                  r&   build_global_viewrh      sM   @ BGGJ'//R89FESN6NF+6MM!LLO"INI , S,/{{5#*<=\)BGG 4
f,4
 -
 
 3u:tt$9$JJqMIIaL %
 776?L*H/9:z!j%zF:FGV,,	 ;s   .Ec           	     l   / n/ n[        X5       H0  u  pVUR                  U Vs/ s H  owS:  a  Xg   OSPM     sn5        M2     [        U6  Vs/ s H  n[        U5      S1-
  PM     n	n[        U	5       V
Vs/ s H  u  p[	        U5      S:  d  M  U
PM     nn
nU(       a   SXS       S35       eU	 Vs/ s H$  n[	        U5      S:  a  UR                  5       OSPM&     nnU VVs/ s H#  o Vs/ s H  oS:  =(       d    US:H  PM     snPM%     nnnX4$ s  snf s  snf s  snn
f s  snf s  snf s  snnf )a  
The global shape is the shape of all dimensions rearranged and broadcasting
to the global view. It's a reference data structure for einsum planning.

Parameters
----------
g_view:
    the global view
op_shapes:
    the shapes of the all operands

Returns
-------
g_shape:
    the global shape vector
g_masks:
    list of shape masks for each operand. A dimension's shape mask is a boolean
    indicating whether its size > 1, in other words, it's not squeezable
r   r   zInvalid operands: label r   z- corresponds to non-broadcastable dimensions.)rD   r[   r6   	enumerater   r\   )re   rd   	op_shapesview_shapesg_masksviewop_shaperO   sizes_per_axg_set_shaperN   sizesnon_bcastableg_shape
view_shaperM   s                   r&   build_global_shaperv      sh   , $&K "Gf0M2XHM1<MN 1 584E#4ELLQC4E  #
 &k22yrc%j1n2    
"8!,<#="> ?7 	8
 BMMc%j1nuyy{!3GM BMAL::.:aQ	!r'	:.   + N# N 	/s5   D
D7D D 4+D&&	D0/D+	D0+D0c                f    U R                  SS5      n [        U 5      [        [        U 5      5      :  $ )z/
Returns True if there is any duplicate label.
r   r   )r   r   r6   )r^   s    r&   has_duplicated_labelsrx   /  s,     ^^C$Fv;S[)))r(   c                6    [        U 5      (       a   S5       eX4$ )a  
Merges dimensions with duplicate labels.

For those dimensions with duplicate labels, merge them into one dimension
which represents the diagonal elements. This requires the dimensions with
duplicate labels are equal sized.

Examples
--------
'ijj...i' would be merged into 'ij...'
z#Duplicate labels are not supported.)rx   )r^   r"   s     r&   diagonalizerz   7  s)     %V,, -, ?r(   Planc                H   ^ SU 3nU4S jnXT/XB4nU R                  U5        g)z
Add reduce to the plan
opc                   > [        XTS9$ )Nkeepdim
paddle_sum)vardimsr   s     r&   <lambda>plan_reduce.<locals>.<lambda>R  s    *S@r(   Nadd_step)planr}   reduce_dimsr   varnamefsteps      `   r&   plan_reducer   J  s-     2$iG@Ai-DMM$r(   c                N    SU 3SU 3/nS nXCUS   4nU R                  U5        g )Nr}   c                    [        U 5      U-  $ Nr   )var1var2s     r&   r   "plan_scalar_prod.<locals>.<lambda>Y  s    :d+d2r(   r   r   )r   op1op2varnamesr   r   s         r&   plan_scalar_prodr   W  s7    SE
bJ'H2A#DMM$r(   c
                  ^^ SU 3SU 3pU4S jX#4 5       u  pU Vs/ s H  oU   S:  d  M  UPM     nnU Vs/ s H  oU   S:  d  M  UPM     nn[         R                  " U5      nXU-   U	-      n[         R                  " U5      nUUU-   U	-      nU4S jX#4 5       u  nn[         R                  " [        UU5       VVs/ s H  u  nnU(       a  UOSPM     snn5      n[         R                  " [        UU5       VVs/ s H  u  nnU(       a  UOSPM     snn5      n[         R                  " UU5      n[	        [
        UUXxU	45      u  nnnnn[        U[         R                  " [        U5      5      :g  5      (       a%  [        U
/U
[        U5      4nU R                  U5        [        U[         R                  " [        U5      5      :g  5      (       a%  [        U/U[        U5      4nU R                  U5        UU-   S:  Ga.  US:  Ga'  S[         R                  " UU45      ;  Ga
  / [        UU   5      Q[         R                  " UU   5      P[         R                  " UU	   5      Pn / [        UU   5      Q[         R                  " UU   5      P[         R                  " UU	   5      Pn![        U
/U
U 4nU R                  U5        [        U/UU!4nU R                  U5        [        X/USS4nU R                  U5        [        UXg-   U-      5      n"[        U/UU"4nU R                  U5        GOUUs=:X  a  Us=:X  a  S:X  a"  O  O[        X/USS4nU R                  U5        GOlU(       a:  [        [        UU-   UU-   U-   5      5      n#[         U
/U
U#4nU R                  U5        U(       a4  [        [        UUU-   5      5      n#[         U/UU#4nU R                  U5        US:X  a  ["        X/U4nU R                  U5        GOUU-   S:X  a{  US:X  au  [         U
/U
S	/4nU R                  U5        [         U/US/4nU R                  U5        [        X/U4nU R                  U5        [$        U/USS	/4nU R                  U5        GOIUU-   S:X  Ga  S[         R                  " UU	   UU	   45      ;  a  ['        UU	   UU	   :H  5      (       d   e[        U
/U
/ [        UU   5      QSP[         R                  " UU	   5      P4nU R                  U5        [        U/U/ [        UU   5      QSP[         R                  " UU	   5      P4nU R                  U5        [        X/USS4nU R                  U5        [$        U/USS	/4nU R                  U5        O<["        X/U4nU R                  U5        [        [        U* S5      5      n$[)        XU$SS
9  Xg-   U-    H  n%UU%   S:  =(       d    UU%   S:H  UU%'   M     U	 H  n%SUU%'   M
     [        [        U5      5       H  n%SUU%'   M
     Sn&Xg-   U-    H  n%U&U&S-   sUU%'   n&M     [        U5      TU'   gs  snf s  snf s  snnf s  snnf )z
plan matmul
r}   c              3  .   >#    U  H
  nTU   v   M     g 7fr   rU   )rV   r}   re   s     r&   rX   plan_matmul.<locals>.<genexpr>r  s     :z&*z   r   c              3  .   >#    U  H
  nTU   v   M     g 7fr   rU   )rV   r}   
g_supportss     r&   rX   r   |  s     >:R*R.:r   r   r   FTr   N)nparrayrD   maximumr0   r   anyaranger   r/   r   concatenateprodr   r   rE   r   r   r   allr   )'r   re   r   r   r   rt   IJ1J2Kr   r   op1_viewop2_viewidxI1I2op1_dimsop2_dimsop1_maskop2_maskrM   m
op1_vshape
op2_vshapevshapei1i2j1j2kr   	op1_shape	op2_shaper    fillr   rN   rO   s'    `  `                                  r&   plan_matmulr   _  sD   " cUr#Z$:z:H	1#smq0#B	1	1#smq0#B	1xx!HR!$Hxx!HR!$H>C:>HhS(5KL5KTQ1q=5KLMJS(5KL5KTQ1q=5KLMJZZ
J/FC"b"!!45BBA
8ryyX//004&$X6d
8ryyX//004&$X6d 	R!Ebnnj*%=>>
*Q- 
GGJrN#
 GGJqM"
	

*Q- 
GGJrN#
 GGJqM"
	 i/di/d |T5$6d VAFRK()e+d	r	Q	!	|T5$6d
 b2grBw|45DtfdD0DMM$b"r'*+DtfdD0DMM$6d\4/DMM$"W\a1ftfdRD0DMM$tfdRD0DMM$D<-DMM$TFD2r(2DMM$"W\b]JqM*)
 
 z!}
156666A$z!}%AqA"''*Q-*@A	D MM$A$z!}%AqA"''*Q-*@A	D MM$D<ud:DMM$TFD2r(2DMM$d\4/DMM$uaR|,K;> frkbzA~9r)9    CM" #
Cfrkqc  x.F3KE 
2	1 MLs!   YYYYY!
Y'
c                   X   X   pXB   XC   p[        U5      nU[        U5      -
  nS/U-  U-   n[        [        U5      5      / / / 4u  nnnn[        [        X|5      XS XS 5       H  u  nnnUS:g  US:g  :w  a,  US:w  a  UR	                  U5        M,  UR	                  U5        M?  US:w  d  MG  [        U
U   5      [        UU   5      -   nUU:  a)  UUU   :X  a   UR	                  U5        UU==   U-  ss'   M  UR	                  U5        UU==   [        US-
  S5      -  ss'   M     XS USS& [        XX#XEUUUU5
        g)z!
Plan various kinds of summation
r   Nr   r   )r   r/   rE   rD   r[   intmaxr   )r   re   r   r   r   rt   rg   n_bcastr   r   r   r   ndimnoutr_   r   r   r   r   rN   dim1dim2folds                          r&   plan_summationr     sQ     fkh#*/hx=D#g,DC$J Eg'R3LAq"bghx0(82DD$ BJDBJ'rz		"		"RZx|$s8B<'88DTzdeBi/b	T!	b	S1--	!& uGAJ c
QBJr(   c                    / / p![        U 5       H/  u  p4US:  a  UR                  U5        M  UR                  U5        M1     [        S [        U5       5       5      (       a  / nX4$ )Nr   c              3  .   #    U  H  u  pX:H  v   M     g 7fr   rU   )rV   rQ   rO   s      r&   rX   rearrange.<locals>.<genexpr>2  s     
2/18/   )rj   r[   r   )axespermr   rN   rO   s        r&   	rearranger   *  s[    R$T?7KKOKK	 # 
2)D/
222:r(   c                  ^ [        U5      n[        U5       Vs/ s H  nSU 3PM
     snm[        [        U5      U5       H]  u  pE[        U5      u  pgTU   nU(       a  [        U/X4n	U R                  U	5        U(       d  MB  [        U/X4n	U R                  U	5        M_     U4S jn
U
TS4n	U R                  U	5        gs  snf )z
Plan broadcast across
r}   c            	     d   > SR                  T5      n[        U[        [        TU 5      5      5      $ )Nz * )rZ   evaldictrD   )argsexprr   s     r&   r   plan_broadcast.<locals>.fL  s*    zz(#D$s8T2344r(   N)r   rE   rD   r   r   r   r   )r   r1   nop_axesnoprQ   op_axesr   r   r   r   r   r   s              @r&   plan_broadcastr   8  s     h-C"'*-*Q"QC*-H%*h/
w'
qkseS.DMM$4seS.DMM$ 05 hDMM$% .s   B?c                  D    \ rS rSrS rS
S jrS rS
S jrS
S jrS r	Sr
g	)r{   iT  c                     0 U l         / U l        g r   envsteps)selfs    r&   __init__Plan.__init__U  s    
r(   c                :    U R                   R                  U5        g r   )r   r[   )r   r   s     r&   r   Plan.add_stepY  s    

$r(   c                B    XR                   ;   a  U R                   U   $ S $ r   r   )r   r   s     r&   get_varPlan.get_var\  s    $+xx$7txx ATAr(   c                     X R                   U'   g r   r   )r   r   r   s      r&   set_varPlan.set_var_  s    r(   c                h    S nU R                    H  tp#pE[        [        XB/UQUQ75      5        M!     U$ r   )r   printreprr   resr   in_varnamesout_varnamer   s         r&   show	Plan.showb  s9    26**.AK$<<t<=> 3=
r(   c                    S nU R                    H=  tp#pEU" / [        U R                  U5      QUQ76 nU(       d  M,  U R                  XA5        M?     U$ r   )r   r0   r   r   r   s         r&   executePlan.executeh  sO    26**.AK;S{3;d;C{[. 3= 
r(   r   N)returnNone)__name__
__module____qualname____firstlineno__r   r   r   r   r   r   __static_attributes__rU   r(   r&   r{   r{   T  s!     B r(   c                   [        U 5      n[        US   5      nU[        U5      -
  n[        5       n	[        U5       V
s/ s H  n
SU
 3PM
     nn
[        [	        U	R
                  X5      5        U(       d  [        XU5        U	$ [        X5       Hd  u  p[        XS XS 5       VVs/ s H!  u  p[        US-   =(       a    U(       + 5      PM#     nnn[        U5       H  u  n
nXJ==   U-  ss'   M     Mf     [        [        U5      X5       H  u  pn/ n[        XS UUS U5       H'  u  nnnUR                  U(       a  US:X  a  UOS5        M)     [        [        S U5      5      nU(       a  [        XUSS9  [        U5       H1  u  pX-   nUU   =(       a    US:H  UU'   XJ==   US:X  a  SOS-  ss'   M3     M     [        U5       HC  n
U
S:X  a  M  [        X:S-
     5      (       d  [        XS-
  U
5        M1  [        XU
S-
  XX$U5        ME     [!        S	 X6S-
     US  5       5      (       d   eUS   n[        S
 [        USU 5       5       5      (       a  U Vs/ s H  nUS:  d  M  UPM     nn[#        U5      U:w  a$  SUS-
   3n[$        U/UU4nU	R'                  U5        Sn/ n[        U5       H  u  nnUS:w  d  M  UUS-   sUU'   nM     [        USU 5       H  u  nnUS:X  d  M  UR                  U5        M!     U(       a$  SUS-
   3n[(        U/UU4nU	R'                  U5        XS  Vs/ s H  nUS:w  d  M  UPM     nnU(       a$  SUS-
   3n[*        U/UU4nU	R'                  U5        U	$ s  sn
f s  snnf s  snf s  snf )zF
Plans the actual execution steps.
Results
-------
the execution plan
r   r}   Nr   r   c                    U S:  $ )Nr   rU   )xs    r&   r   plan_einsum.<locals>.<lambda>  s    AFr(   Tr   c              3  .   #    U  H  o(       + v   M     g 7fr   rU   )rV   maskeds     r&   rX   plan_einsum.<locals>.<genexpr>  s     C(Bfzz(Br   c              3  .   #    U  H  u  pX:g  v   M     g 7fr   rU   )rV   rN   rO   s      r&   rX   r    s     
;$:29$:r   )r   r{   rE   r/   r0   r   r   rD   r   rj   r[   filterr   r   r   r   r   r8   r   r   r   r   )r1   re   rt   r   rg   r   r   r   r   r   rQ   op_namesrn   supportdrM   
down_countr_   mask	to_reducerO   r  r   rN   r   r   r   unsqueeze_dimssqueeze_dimss                                r&   plan_einsumr  q  s    h-Cvay>D#g,D 6D"'*-*Q"QC*H-T\\8	./ tv. V0 DK8
8 Q#U$8 	 
 "*-HAuJ%J . 1 U3Z<	"%d5k4;"HCV
SD #I 6"2I>?d; i(DABBx-Q"WDHJqBw!A-J ) =  3Z 6& :!e$%%Tq5!,a!eQGg7 B C
7(;DE(BCCCCC":D

;Id5Dk$:
;;;#0tsaxt0$<437)nGwi$6DMM$t_EBBw #S1WR# % tET{+EBBw%%b) , 37)nGwi.@DMM$#';<;C#)C;L<sQwi.	7L8dKC .
z 1$ =s#   M6'(M;
N*N3
NNc           	     r  ^ SnSn/ n[        [        S5      [        S5      5       Vs1 s H  n[        U5      iM     snm[        U R	                  S5      U5       H[  u  px[        UR                  5      [        UR                  SS5      5      -
  n	[        XI5      nU H  nTR                  U5        M     M]     [        U R	                  S5      U5       H  u  pxSU;   ak  UR                  S5      n
U[        UR                  5      [        UR                  SS5      5      -
  -
  n[        U[        U5       Vs/ s H  oU
-   PM	     snS9nUR                  U5        M     SR                  U4S	 j[        U5       5       5      nUb$  U R                  SU5      n UR                  SU5      nXU4$ s  snf s  snf )
zM
we replace ... as unused variables to simplify the EinsumOp implementation.
Nr   r`   zr*   r   r   )axisc              3  D   >#    U  H  nTR                  5       v   M     g 7fr   )r\   )rV   _unused_variabless     r&   rX   #replace_ellipsis.<locals>.<genexpr>  s     O!/3355s    )rE   ordchrrD   r.   r   r    r   r   discardindexr   r[   rZ   )left_equationr9   r1   ellipsis_stringsmax_ndimnew_operandsr#   equr"   r$   start_unsqueeze_idxto_squeeze_numrQ   r  s                @r&   replace_ellipsisr&    s    H!#L(-c#hC(AB(A1A(ABM//4h?GMM"SUB)?%@@x'A$$Q'  @ M//4h?C<"%))E"2%GMM"SUB)?%@@N  7<^7LM7L!--7LMG 	G$ @ wwOuXOO#%--e5EFkk%!12|++1 C Ns   F/8F4c           	        U R                  SS5      n [        U5      nUS:  d
   SU 35       eU R                  5       R                  S5      tp4[        U5      S:  d   S5       e[	        X15      nU(       a  US   OSnUc  [        U5      n[        UR                  S	5      5      [        U5      :X  d/   S
[        U5       S[        UR                  S	5      5       S35       eSU;   a  SU;  a   S5       e[        X4/UQ76 u  p4nX4XV4$ )z?
check equation / raise error, default right labels generation
 r   r   z:Required at least one operand in Einsum API, but received ->r   +Invalid equation: multiple `->` were found.Nr*   r+   r,   r-   r   r5   )r   r   lowerr.   r3   rhs_inferencer&  )equationr1   r   lhsr9   r^   r"  s          r&   
preprocessr/    s'    R(H
h-C7 
DSEJ7
  &&t,ICs8a<FFF<#(F#a&TC
{C syy~#h-/ 
6s8}o F3())I	K/
 c!1 >2 .cBBClV))r(   c                       \ rS rSr% S\S'   Srg)Shapedi0  	list[int]r    rU   N)r   r   r   r   __annotations__r  rU   r(   r&   r1  r1  0  s    r(   r1  c                j    S U R                  S5       5       nSS jn[        [        XCX!5      5      nU$ )z

this shape is just used for operands planning. may differ with the original shape.
for example:
... is replaced by 1
-1  is replaced by 1
Results
-------
list of shape

c              3  @   #    U  H  oR                  5       v   M     g 7fr   )strip)rV   r  s     r&   rX   #parse_fake_shape.<locals>.<genexpr>B  s     <(;1WWYY(;s   r*   c                   [        UR                  5      [        U5      :X  d)   S[        UR                  5       S[        U5       35       e[        [        XR                  5      5       VVVs/ s H
  u  nu  pEUPM     nnnn[	        [        [        U5      5      nSU ;   a!  UR                  U R                  S5      S5        [        U5      $ s  snnnf )z
1. ori_label is the original labels, not aligned by '....'
2. if the '...' is evaluated to empty list, there is no '.' in label
zClength of shape and length of label must be the same, but received z != r   r   )
r   r    rj   rD   r/   r0   absinsertr  r1  )	ori_labellabelr}   rQ   rW   rM   fakess          r&   
fake_shape$parse_fake_shape.<locals>.fake_shapeD  s    
 288}E
* 	
QRUVXV^V^R_Q``dehineodpq	
* %.c%.B$CD$Cyq&1$CDSe_%)LL-q1e}	 Es   .C)r;  strr<  r@  r}   r   r   r1  )r.   r/   r0   )r-  r1   r^   origin_labelsr>  outs         r&   parse_fake_shaperC  4  s4     =s(;<M s:f?
@CJr(   c           
        ^ U4S jn[         R                  " U 5      mSU ;   a  SOSnUSR                  [        U[	        TR                  5       5      5      5      -   nU$ )Nc                D   > TR                  U 5      S:H  =(       a    U S;  $ )Nr   )r   r*   )get)keycnts    r&   is_freerhs_inference.<locals>.is_freeW  s     wws|q :S
%::r(   r   r   )collectionsCounterrZ   r
  r8   elements)r.  rI  r9   rH  s      @r&   r,  r,  V  sQ    ; 

c
"CC<%RC
ws||~(>?@
@CJr(   c                    SS jn[         R                  " U 5      nU" U5      nUc  [        U 5      nU R                  SU5      n UR                  SU5      nU S-   U-   U4$ )z+
1. gen rhs if rhs is None
2. '...' -> 'A'
c                    [        U R                  5       5      n[        R                   H  nX!;  d  M
  Us  $    [	        S5      e)NzSYou have used all `a` - `z`, there can't find a unused char for einsum optimization)r6   rM  stringascii_lowercase
ValueError)counterusedr#   s      r&   get_used_label2gen_equation_for_opteinsum.<locals>.get_used_labelf  sA    7##%&''A} ( a
 	
r(   r   r)  )r   r@  )rK  rL  r,  r   )r.  r9   rU  rH  broadcast_labels        r&   gen_equation_for_opteinsumrX  `  sf    
 

c
"C$S)O
{C 
++e_
-C
++e_
-C:_,,r(   c                   [        U5      n[        U /UQ76 u  p4pVUS::  a  [        US-   U-   /UQ76 $ [        X6U5      n[	        X45      u  p[
        R                  " U/UQ7SS06u  pUnU Hf  nUtu  pn
nnX:  d   S5       eUR                  U5      UR                  U5      /nUR                  U	S5      nUR                  [        U/UQ76 5        Mh     [        U5      S:X  d   S[        U5       S	35       eUS
   $ )z
einsum v2 implementation.
1. Implement C++ EinsumOp.
2. V2 create the EinsumOp to calculate, so just a little verify work in python.
3. V2 use opt_einsum.contract_path to optimize the multivariable einsum.
r   r)  einsum_callTzUAssume the first var_idx is smaller than the second_idx. opt_einsum can guarantee it.r   r   z1There must be one elements in list, but received r   r   )
r   r/  gen_einsum_oprC  rX  
opt_einsumcontract_pathr\   r   r[   )r-  r1   n_opr.  r9   r^   r"  shapesopt_equationrW  r  consvar_listpathr`   ra   eq__var_ss                      r&   	einsum_v2rg  x  s"    x=D%/%D8%D"CfqyS4Z#-===c8F$>s$H!L&&|OfO$OGAH!2u 	
c	
u a(,,q/2ZZ/b1512  x=A 
;CM?!L A;r(   c                   [        5       (       a  [        R                  " X5      S   $ S[        U5      s=::  a  S::  d   S5       e   S5       eU H  n[	        USSS/S5        M     [        U S	[        S5        [        S0 [        5       D6nUR                  US   R                  S
9n0 nXS	'   [        [        U5      5       Vs/ s H  nUR                  US   R                  S
9PM!     nn[        [        U5      5       Vs/ s H  nUR                  US   R                  S
9PM!     nnUR                  SSU0XGUS.US9  U$ s  snf s  snf )z
EinsumOp Python Interface:
r   r   r   z&Only support two operands in EinsumOp.dtypefloat32float64einsumr-  )ri  Operands)Out
InnerCacheXShape)typeinputsoutputsattrs)rl  )r
   r   rl  r   r	   r   r@  r   locals"create_variable_for_type_inferenceri  rE   	append_op)	r-  r1   inphelperrB  rt  rQ   cachesxshapes	            r&   r[  r[    su   
 }}X033CM&Q&P(PP&P(PP&C$Wy)4h  	8Zh72277hqk>O>O7P$j 3x=)
) 55HQK<M<M5N) 	 
 3x=)
) 55HQK<M<M5N) 	 
 	)H	 	 	
 


s   &E&Ec           	        SSK n[        UR                  R                  SS5      5      (       a  [	        U /UQ76 $ [        U5      nUS:  d   S5       eU R                  5       R                  SS5      R                  S5      tpE[        U5      S	:  d   S
5       eU(       a  US   OSn[        XA5      n[        [        [        [        Xa5      6 5      u  pa[        S U 5       5      n[        XeU5      u  pp[!        XU Vs/ s H  oR"                  PM     sn5      u  p[%        XXX5      nUR'                  5       nU$ s  snf )a  

einsum(equation, *operands)

The current version of this API should be used in dynamic graph only mode.

Einsum offers a tensor operation API which allows using the Einstein summation
convention or Einstein notation. It takes as input one or multiple tensors and
produces as output one tensor.

Einsum is able to perform a variety of tensor operations. Following lists a few:

    - for single operand
        - trace
        - diagonal
        - transpose
        - sum
    - for double operands
        - dot
        - outer
        - broadcasting and elementwise multiply
        - matrix multiply
        - batched matrix multiply
    - for many operads
        - broadcasting multiply
        - chained matrix multiply

**The summation notation**

    - The tensor dimensions are labeled using uncased English letters. E.g., `ijk`
      relates to a three dimensional tensor whose dimensions are labeled i, j, and k.
    - The equation is `,` separated into terms, each being a distinct input's
      dimension label string.
    - Ellipsis `...` enables broadcasting by automatically converting the unlabeled
      dimensions into broadcasting dimensions.
    - Singular labels are called free labels, duplicate are dummy labels. Dummy labeled
      dimensions will be reduced and removed in the output.
    - Output labels can be explicitly specified on the right hand side of `->` or omitted.
        In the latter case, the output labels will be inferred from the input labels.
            - Inference of output labels
                - Broadcasting label `...`, if present, is put on the leftmost position.
                - Free labels are reordered alphabetically and put after `...`.
            - On explicit output labels
                - If broadcasting is enabled, then `...` must be present.
                - The output labels can be an empty, an indication to output as a scalar
                    the sum over the original output.
                - Non-input labels are invalid.
                - Duplicate labels are invalid.
                - For any dummy label which is present for the output, it's promoted to
                    a free label.
                - For any free label which is not present for the output, it's lowered to
                    a dummy label.

    - Examples
        - '...ij, ...jk', where i and k are free labels, j is dummy. The output label
          string is '...ik'
        - 'ij -> i', where i is a free label and j is a dummy label.
        - '...ij, ...jk -> ...ijk', where i, j and k are all free labels.
        - '...ij, ...jk -> ij', an invalid equation since `...` is not present for
          the output.

**The summation rule**

The summation procedure can be outlined as follows, although the actual steps taken
may vary significantly due to implementation specific optimization.

    - Step 1: preparation for broadcasting, that is, transposing and unsqueezing
      the input operands to have each resulting dimension identically labeled across
      all the input operands.
    - Step 2: broadcasting multiply all the resulting operands from step 1.
    - Step 3: reducing dummy labeled dimensions.
    - Step 4: transposing the result tensor to match the output labels.

**On trace and diagonal**

The trace and diagonal are planned yet unimplemented features.

Args:
    equation (`str`):
        The summation terms using the Einstein summation notation.
    operands (`list|Tensor`):
        The input tensors over which to compute the Einstein summation. The number of
        operands should equal the number of input terms in the equation.

Returns:
    result (`Tensor`), the result tensor.

Examples:
    .. code-block:: python

        >>> import paddle
        >>> paddle.seed(102)
        >>> x = paddle.rand([4])
        >>> y = paddle.rand([5])

        >>> # sum
        >>> print(paddle.einsum('i->', x))
        Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
        1.81225157)

        >>> # dot
        >>> print(paddle.einsum('i,i->', x, x))
        Tensor(shape=[], dtype=float32, place=Place(cpu), stop_gradient=True,
        1.13530672)

        >>> # outer
        >>> print(paddle.einsum("i,j->ij", x, y))
        Tensor(shape=[4, 5], dtype=float32, place=Place(cpu), stop_gradient=True,
               [[0.26443148, 0.05962684, 0.25360870, 0.21900642, 0.56994802],
                [0.20955276, 0.04725220, 0.20097610, 0.17355499, 0.45166403],
                [0.35836059, 0.08080698, 0.34369346, 0.29680005, 0.77240014],
                [0.00484230, 0.00109189, 0.00464411, 0.00401047, 0.01043695]])

        >>> A = paddle.rand([2, 3, 2])
        >>> B = paddle.rand([2, 2, 3])

        >>> # transpose
        >>> print(paddle.einsum('ijk->kji', A))
        Tensor(shape=[2, 3, 2], dtype=float32, place=Place(cpu), stop_gradient=True,
               [[[0.50882483, 0.56067896],
                 [0.84598064, 0.36310029],
                 [0.55289471, 0.33273944]],
                [[0.04836850, 0.73811269],
                 [0.29769155, 0.28137168],
                 [0.84636718, 0.67521429]]])

        >>> # batch matrix multiplication
        >>> print(paddle.einsum('ijk, ikl->ijl', A,B))
        Tensor(shape=[2, 3, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
               [[[0.36321065, 0.42009076, 0.40849245],
                 [0.74353045, 0.79189068, 0.81345987],
                 [0.90488225, 0.79786193, 0.93451476]],
                [[0.12680580, 1.06945944, 0.79821426],
                 [0.07774551, 0.55068684, 0.44512171],
                 [0.08053084, 0.80583858, 0.56031936]]])

        >>> # Ellipsis transpose
        >>> print(paddle.einsum('...jk->...kj', A))
        Tensor(shape=[2, 2, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
               [[[0.50882483, 0.84598064, 0.55289471],
                 [0.04836850, 0.29769155, 0.84636718]],
                [[0.56067896, 0.36310029, 0.33273944],
                 [0.73811269, 0.28137168, 0.67521429]]])

        >>> # Ellipsis batch matrix multiplication
        >>> print(paddle.einsum('...jk, ...kl->...jl', A,B))
        Tensor(shape=[2, 3, 3], dtype=float32, place=Place(cpu), stop_gradient=True,
               [[[0.36321065, 0.42009076, 0.40849245],
                 [0.74353045, 0.79189068, 0.81345987],
                 [0.90488225, 0.79786193, 0.93451476]],
                [[0.12680580, 1.06945944, 0.79821426],
                 [0.07774551, 0.55068684, 0.44512171],
                 [0.08053084, 0.80583858, 0.56031936]]])

r   NFLAGS_new_einsum1z!At least one operand is expected.r(  r   r)  r   r*  c              3  B   #    U  H  oR                  S 5      v   M     g7f)r   N)r_   )rV   rM   s     r&   rX   einsum.<locals>.<genexpr>n  s     8Zwws||Zs   )osr   environrF  rg  r   r+  r   r.   r3   r/   rD   r0   rz   r   rh   rv   r    r  r   )r-  r1   r  r   r.  r9   r2   r;   rd   re   rf   rg   r}   rt   r   r   results                    r&   rl  rl    s9   x 
2::>>,c233-H--
h-C77777  ((b177=ICs8a<FFF< #a&TC c,J  Sj%K LMJ
 8Z88L, ):)%Hf -h7h88h7G
 'wD \\^FM 8s   >D;)r!   r@  r"   r   r   r@  )r!   r@  r1   Sequence[Tensor]r   z	list[str])r9   r@  r:   Sequence[str]r;   r   r   r   )rI   r@  rJ   r@  r   r2  )r2   r  r9   
str | Noner;   r   r   z4tuple[str, list[list[int]], int, list[Tensor | int]])re   list[list[int]]rd   r@  rk   zSequence[list[int]]r   z"tuple[list[int], list[list[bool]]])r^   r@  r   bool)r^   r@  r"   r   r   ztuple[str, Tensor])
r   r{   r}   r   r   r2  r   r  r   r   )r   r{   r   r   r   r   r   r   )r   r{   re   r  r   r   r   r   r   list[list[bool]]rt   r2  r   r2  r   r2  r   r2  r   r2  r   r   )r   r{   re   r  r   r   r   r   r   r  rt   r2  rg   list[Tensor | int]r   r   r   r   )r   r2  r   ztuple[list[int], list[int]])r   r{   r1   r  r   r  r   r   )r1   r  re   r  rt   r2  r   r  rg   r  r   r   r   r{   )r  r@  r9   r@  r1   r   r   ztuple[str, str, list[Tensor]])r-  r@  r1   r   r   z(tuple[str, str, list[str], list[Tensor]])r-  r@  r1   r  r^   r  r   zlist[Shaped])r.  r@  r   r@  )r.  r@  r9   r  r   ztuple[str, str])r-  r@  r1   r   r   r   )r-  r@  r1   r   r   zTensor | None)=
__future__r   rK  rF   r@   rP  typingr   r   numpyr   r\  paddler   base.data_feederr   r	   base.frameworkr
   base.layer_helperr   linalgr   r   manipulationr   r   r   mathr   r   r   collections.abcr   r   __all__r'   r3   r>   rR   rh   rv   rx   rz   r   r   r   r   r   r   r{   r  r&  r/  r1  rC  r,  rX  rg  r[  rl  rU   r(   r&   <module>r     s   #   	  ,    C 3 + % 5 5
 (
"J<2	)9<	<2j<-<-$.<->A<-9<-~//'*/7J/'/d*&



&/
:>
	
W!
W!W! 
W! 
	W!
 !W! W! W! 	W! 	W! W! 
W!t.K
.K.K 
.K 
	.K
 !.K .K  .K .K 
.Kb
*6E	8 :uuu u !	u
  u u 
up!,!, !,-3!,"!,H * *$ *- *FZ -7DD-0> FWr(   