
    |j                       d dl mZ d dlZd dlZd dlZd dlZd dlmZmZ d dl	Z
d dl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mZ d	dlmZmZmZ d	dlmZmZ erd dl m!Z! d dlm"Z" g Z#dbdZ$dcdZ%dddZ&ded#Z'dfd'Z(dgd.Z)dhd1Z*did3Z+djd9Z,dkd<Z-dldDZ.dmdHZ/dndKZ0dodMZ1 G dN d5          Z2dpdOZ3dqdRZ4drdUZ5 G dV dWe          Z6dsdYZ7dtd[Z8dud]Z9dvd^Z:dvd_Z;dwdaZ<dS )x    )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)Tensorlabelstrstroperandr   returnc                   |                      dd          D ]$}|                                sJ d| d            %|                      ddd                              d          dk    s
J d            t          |j                  }|                      dd|t          |           z
  d	z   z            }t          |          |k    sJ d
|  d            |S )a  
    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)r   r   cndimsfull_labelstrs        d/lsinfo/ai/hellotax_ai/data_center/backend/venv/lib/python3.11/site-packages/paddle/tensor/einsum.pyparse_op_labelsr)   -   s   " c2&& 
 
yy{{ 	
 	
SSSS	
 	
{ 	
 E2q))..s33r999@ :99 E$$UC53x==3H13L,MNNM}&&&MxMMM '&&     operandsSequence[Tensor]	list[str]c                   |                      d          }t          |          t          |          k    s+J dt          |           dt          |           d            t          t          t          ||                    S )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   r+   
nop_labelss      r(   parse_labelsr7   R   s      $$Jz??c(mm+++	Gs8}} 	G 	G__	G 	G 	G ,++
 OZ::;;;r*   rhsinput_labelsSequence[str]n_bcast_dimsintNonec                <   |dk    rd| v s
J d            |                      dd          } t          |           }d|vsJ |                    |          }|rJ dt          |           d            t	          |           t	          |          k    s
J d            d	S )
z?
    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#   )r8   r9   r;   rhs_setnon_input_labelss        r(   validate_rhsrE   k   s     a|||B || ++eR
 
 C#hhG l"""" )),77  	J/00	J 	J 	J 
 s88s7||###> $####r*   	in_labels
out_labels	list[int]c           	        dgt          |          z  }t          j        d|          }||                                |                                }}t          j        d|           }|rmt          t          ||          ddd         t          |                                |                                          ddd                   D ]
\  }}|||<   t          j        t          |          t          |t          |                              }	n)t          t          t          |                              }	|	D ] }
| 
                    ||
                   ||
<   !|S )a9  
    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"   )rF   rG   inv_maprrL   rM   saxdimitis              r(   
build_viewrZ      s<   8 dS__$G 		&*%%A}WWYYsIfi(( 	"eS!!$$B$'qwwyy!%%'')B)B44R4)H  " "C "_U5\\5c*oo+F+FGG%J(()) 3 3^^JqM22

Nr*   r6   
str | None4tuple[str, list[list[int]], int, list[Tensor | int]]c                "   t          d                    |                               dd                    }g g }}t          dg||          D ]F\  }}||k    r+|                    |           |                    d           6|dxx         dz  cc<   G|+t          |||           |                    dd|z            }n3d|z  d                    d t          ||          D                       z   }t          t          |                    ddd         D ]6}	||	         |v r*|                    |	           |                    |	           7d                    |          }
||
z   fd| D             }t          |          }|}|||fS )	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  ,   K   | ]\  }}|d k    |V  dS )r   N ).0lr%   s      r(   	<genexpr>z$build_global_view.<locals>.<genexpr>   s3       4
 4
!QQA4
 4
r*   c                0    g | ]}t          |          S r_   )rZ   )r`   rY   g_labelss     r(   
<listcomp>z%build_global_view.<locals>.<listcomp>   s#    :::!jH%%:::r*   )	rB   joinr    rN   appendrE   rO   r#   pop)r6   r8   r;   concatlabelscountabg_labels_outrY   g_labels_sumg_viewg_noutg_countrd   s                 @r(   build_global_viewrs      s   @ BGGJ''//R8899FEFSN6NF++  166MM!LLOOOO"IIINIIII
S&,///{{5#*<==\)BGG 4
 4
fe,,4
 4
 4
 -
 -
 
 3u::ttt$  !9$$JJqMMMIIaLLL776??Ll*H::::z:::FFGVVW,,r*   rp   list[list[int]]rd   	op_shapesSequence[list[int]]"tuple[list[int], list[list[bool]]]c                B  	 g }g }t          | |          D ]&\  }	|                    	fd|D                        'd t          | D             }d t          |          D             }|rJ d||d                   d            d |D             }d |D             }||fS )	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
    c                0    g | ]}|d k    r|         ndS )r   r   r_   )r`   rW   op_shapes     r(   re   z&build_global_shape.<locals>.<listcomp>  s)    MMMS2XXHSMM1MMMr*   c                4    g | ]}t          |          d hz
  S r   )r@   )r`   sizes_per_axs     r(   re   z&build_global_shape.<locals>.<listcomp>  s4     # # #$0LQC# # #r*   c                >    g | ]\  }}t          |          d k    |S r|   )r#   )r`   rV   sizess      r(   re   z&build_global_shape.<locals>.<listcomp>  s.       r5c%jj1nnnnnr*   zInvalid operands: label r   z- corresponds to non-broadcastable dimensions.c                `    g | ]+}t          |          d k    r|                                nd,S )r   r   )r#   rh   )r`   r   s     r(   re   z&build_global_shape.<locals>.<listcomp>&  s2    MMMc%jj1nnuyy{{{!MMMr*   c                &    g | ]}d  |D             S )c                &    g | ]}|d k    p|dk    S )r   r   r_   r`   rU   s     r(   re   z1build_global_shape.<locals>.<listcomp>.<listcomp>)  s%    ...aQ	!r'...r*   r_   )r`   
view_shapes     r(   re   z&build_global_shape.<locals>.<listcomp>(  s4       3=..:...  r*   )rN   rg   	enumerate)
rp   rd   ru   view_shapesg_masksviewg_set_shapenon_bcastableg_shaperz   s
            @r(   build_global_shaper      s    , $&K "Gfi00 O OhMMMMMMMNNNN# #474E# # #K %k22  M   	88M!,<#= 	8 	8 	8 
 NMMMMG AL  G Gr*   rj   boolc                    |                      dd          } t          |           t          t          |                     k    S )z7
    Returns True if there is any duplicate label.
    r   r   )r    r#   r@   )rj   s    r(   has_duplicated_labelsr   /  s6     ^^C$$Fv;;S[[))))r*   tuple[str, Tensor]c                <    t          |           r
J d            | |fS )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.)r   )rj   r   s     r(   diagonalizer   7  s5     %V,,  - , 7?r*   planPlanopreduce_dimskeepdimc                T    d| }fd}||g||f}|                      |           dS )z 
    Add reduce to the plan
    r   c                (    t          | |          S )Nr   
paddle_sum)vardimsr   s     r(   <lambda>zplan_reduce.<locals>.<lambda>R  s    *S$@@@ r*   Nadd_step)r   r   r   r   varnamefsteps      `   r(   plan_reducer   J  sF     2iiG@@@@Awi+-DMM$r*   op1op2c                `    d| d| g}d }|||d         f}|                      |           d S )Nr   c                &    t          |           |z  S Nr   )var1var2s     r(   r   z"plan_scalar_prod.<locals>.<lambda>Y  s    :d++d2 r*   r   r   )r   r   r   varnamesr   r   s         r(   plan_scalar_prodr   W  sH    S

JJJ'H22Ah#DMM$r*   
g_supportslist[list[bool]]r   IJ1J2Kc
                  "# d| d| }}
fd||fD             \  "#"fd|D             }#fd|D             }t          j        "          ""||z   |	z            }t          j        #          ##||z   |	z            }fd||fD             \  }}t          j        d t          ||          D                       }t          j        d t          ||          D                       }t          j        ||          }t	          t
          |||||	f          \  }}}}}t          |t          j        t          |                    k              r.t          |
g|
t          |          f}| 
                    |           t          |t          j        t          |                    k              r.t          |g|t          |          f}| 
                    |           ||z   dk    rY|dk    rRd	t          j        ||f          vr9g t          ||                   t          j        ||                   t          j        ||	                   }g t          ||                   t          j        ||                   t          j        ||	                   }t          |
g|
|f}| 
                    |           t          |g||f}| 
                    |           t          |
|g|d
df}| 
                    |           t          |||z   |z                      }t          |g||f}| 
                    |           n||cxk    r|cxk    rdk    r(n n%t          |
|g|d
df}| 
                    |           n|rGt          t          ||z   ||z   |z                       }t           |
g|
|f}| 
                    |           |rAt          t          |||z                       }t           |g||f}| 
                    |           |dk    r#t"          |
|g|f}| 
                    |           n&||z   dk    r|dk    rt           |
g|
dgf}| 
                    |           t           |g|d	gf}| 
                    |           t          |
|g|f}| 
                    |           t$          |g|d	dgf}| 
                    |           n||z   dk    r1d	t          j        ||	         ||	         f          vrt'          ||	         ||	         k              sJ t          |
g|
g t          ||                   dt          j        ||	                   f}| 
                    |           t          |g|g t          ||                   dt          j        ||	                   f}| 
                    |           t          |
|g|d
df}| 
                    |           t$          |g|d	dgf}| 
                    |           nRt"          |
|g|f}| 
                    |           t          t          | d                    }t)          | ||d
           ||z   |z   D ]} ||          dk    p||          d	k    || <   |	D ]} d
|| <   t          t          #                    D ]} d	#| <   d}!||z   |z   D ]} |!|!dz   c#| <   }!t          #          |<   dS )z
    plan matmul
    r   c              3  (   K   | ]}|         V  d S r   r_   )r`   r   rp   s     r(   rb   zplan_matmul.<locals>.<genexpr>r  s'      ::&*::::::r*   c                ,    g | ]}|         d k    |S r   r_   )r`   idxop1_views     r(   re   zplan_matmul.<locals>.<listcomp>t  '    	1	1	1#hsmq00#000r*   c                ,    g | ]}|         d k    |S r   r_   )r`   r   op2_views     r(   re   zplan_matmul.<locals>.<listcomp>u  r   r*   c              3  (   K   | ]}|         V  d S r   r_   )r`   r   r   s     r(   rb   zplan_matmul.<locals>.<genexpr>|  s'      >>R*R.>>>>>>r*   c                     g | ]\  }}|r|nd S r|   r_   r`   rU   ms      r(   re   zplan_matmul.<locals>.<listcomp>}  $    LLLTQ=11qLLLr*   c                     g | ]\  }}|r|nd S r|   r_   r   s      r(   re   zplan_matmul.<locals>.<listcomp>~  r   r*   r   r   FTr   r   N)nparrayrN   maximumr5   r#   anyaranger   r4   r   concatenateprodr   r   rO   r   r   r   allr   )$r   rp   r   r   r   r   r   r   r   r   r   r   I1I2op1_dimsop2_dimsop1_maskop2_mask
op1_vshape
op2_vshapevshapei1i2j1j2kr   	op1_shape	op2_shaper$   fillr   rV   rW   r   r   s$    `  `                             @@r(   plan_matmulr   _  s   " cZ#ZZ$D::::Sz:::Hh	1	1	1	1	1	1	1B	1	1	1	1	1	1	1Bx!!HR!$Hx!!HR!$H>>>>C:>>>HhLLS(5K5KLLLMMJLLS(5K5KLLLMMJZ
J//FC"b"b!!455BBA
8ryX///00 4&$X6d
8ryX///00 4&$X6d 	R!EEbnj*%=>>>>
*Q-  
GJrN##
 GJqM""
	

*Q-  
GJrN##
 GJqM""
	 i/di/d d|T5$6d VAFRK())e+d	r				Q				!					d|T5$6d
  	 b2grBw|4455DtfdD0DMM$ 	 b"r'**++DtfdD0DMM$66dD\4/DMM$"W\\a1fftfdRD0DMM$tfdRD0DMM$D$<-DMM$TFD2r(2DMM$"W\\b]JqM*)
 )
 
 
 z!}
156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$dD\4/DMM$uaR||,,Kc;>>>> "frk : :bzA~9r)9  CMM""  
C"frk ) )qccx..F3KKKr*   rr   list[Tensor | int]n_bcastc                \   ||         ||         }	}||         ||         }}
t          |          }|t          |          z
  }dg|z  |z   }t          t          |                    g g g f\  }}}}t          t          ||          ||d         |	|d                   D ]\  }}}|dk    |dk    k    r2|dk    r|                    |           0|                    |           F|dk    rt          |
|                   t          ||                   z   }||k    r2|||         k    r&|                    |           ||xx         |z  cc<   |                    |           ||xx         t          |dz
  d          z  cc<   ||d         |dd<   t          | |||||||||
  
         dS )z)
    Plan various kinds of summation
    r   Nr   r   )r#   r4   rO   rN   rg   r<   maxr   )r   rp   r   r   r   r   rr   r   r   r   r   r   ndimnoutrk   r   r   r   r   rV   dim1dim2folds                          r(   plan_summationr     s     fSkhH#C*S/hHx==D#g,,DC$J Eg''R3LAq"bgthwxx0(7882D  . .D$ BJDBJ''rzz		"		"RZZx|$$s8B<'8'88DTzzdeBi//b			T!				b			S1---			 tuuGAAAJ fc3
GQBJJJJJr*   axestuple[list[int], list[int]]c                    g g }}t          |           D ]6\  }}|dk     r|                    |           !|                    |           7t          d t          |          D                       rg }||fS )Nr   c              3  (   K   | ]\  }}||k    V  d S r   r_   )r`   rY   rW   s      r(   rb   zrearrange.<locals>.<genexpr>2  s*      
2
2318
2
2
2
2
2
2r*   )r   rg   r   )r   permr   rV   rW   s        r(   	rearranger   *  s    R$DT??  C77KKOOOOKK

2
2)D//
2
2
222 :r*   nop_axesc                   t          |          }d t          |          D             t          t          |          |          D ]e\  }}t          |          \  }}|         }|r!t          |g||f}	|                     |	           |r!t          |g||f}	|                     |	           ffd}
|
df}	|                     |	           dS )z
    Plan broadcast across
    c                    g | ]}d | S r   r_   r`   rY   s     r(   re   z"plan_broadcast.<locals>.<listcomp>?      ---QQ---r*   c            	         d                               }t          |t          t          |                               S )Nz * )rf   evaldictrN   )argsexprr   s     r(   r   zplan_broadcast.<locals>.fL  s6    zz(##D$s8T2233444r*   N)r#   rO   rN   r   r   r   r   )r   r+   r   noprY   op_axesr   r   r   r   r   r   s              @r(   plan_broadcastr   8  s     h--C--%**---H%**h// 	  	 
7w''
dqk 	 seS$.DMM$ 	 seS$.DMM$5 5 5 5 5 hDMM$r*   c                  8    e Zd Zd Zd
dZd Zd
dZd
dZd Zd	S )r   c                "    i | _         g | _        d S r   )envsteps)selfs    r(   __init__zPlan.__init__U  s    


r*   r   r=   c                :    | j                             |           d S r   )r   rg   )r  r   s     r(   r   zPlan.add_stepY  s    
$r*   c                2    || j         v r| j         |         nd S r   r   )r  r   s     r(   get_varzPlan.get_var\  s     $+tx$7$7tx  TAr*   c                    || j         |<   d S r   r  )r  r   r   s      r(   set_varzPlan.set_var_  s    r*   c                l    d }| j         D ])^}}}}t          t          ||g||R                      *|S r   )r   printreprr  resr   in_varnamesout_varnamer   s         r(   showz	Plan.showb  sQ    26* 	? 	?.A{K$$Q<<t<<==>>>>
r*   c                    d }| j         D ];^}}}} |g t          | j        |          |R  }|r|                     ||           <|S r   )r   r5   r  r  r  s         r(   executezPlan.executeh  si    26* 	/ 	/.A{K$!;S{33;d;;;C /[#...
r*   N)r   r=   )	__name__
__module____qualname__r  r   r  r  r  r  r_   r*   r(   r   r   T  s                 B B B              r*   c                l   t          |           }t          |d                   }|t          |          z
  }t                      }	d t          |          D             }
t          t	          |	j        |
|                      |st          |	| |           |	S t          ||          D ]T\  }}d t          ||d         ||d                   D             }t          |          D ]\  }}||xx         |z  cc<   Ut          t          |          ||          D ]\  }}}g }t          ||d         ||d         |          D ]%\  }}}|	                    |r|dk    r|nd           &t          t          d |                    }|rt          |	||d	           t          |          D ]3\  }}||z   }||         o|dk    ||<   ||xx         |dk    rdndz  cc<   4t          |          D ]O}|dk    r	t          ||dz
                     st          |	|dz
  |           6t          |	||dz
  |||||           Pt          d
 ||dz
           |d         D                       sJ |d         }t          d t          |d|                   D                       rd |D             }t!          |          |k    r)d|dz
   }t"          |g||f}|	                    |           d}g }t          |          D ]\  }}|dk    r||dz   c||<   }t          |d|                   D ] \  }}|dk    r|	                    |           !|r)d|dz
   }t&          |g||f}|	                    |           d ||d         D             }|r)d|dz
   }t(          |g||f}|	                    |           |	S )zZ
    Plans the actual execution steps.
    Results
    -------
    the execution plan
    r   c                    g | ]}d | S r   r_   r   s     r(   re   zplan_einsum.<locals>.<listcomp>  r   r*   c                >    g | ]\  }}t          |d z   o|           S r|   )r<   )r`   drU   s      r(   re   zplan_einsum.<locals>.<listcomp>  s?     
 
 
1 Q#U$$
 
 
r*   Nr   r   c                    | dk    S )Nr   r_   )xs    r(   r   zplan_einsum.<locals>.<lambda>  s
    AF r*   Tr   c              3     K   | ]}| V  d S r   r_   )r`   maskeds     r(   rb   zplan_einsum.<locals>.<genexpr>  s$      CCf6zCCCCCCr*   c              3  (   K   | ]\  }}||k    V  d S r   r_   )r`   rV   rW   s      r(   rb   zplan_einsum.<locals>.<genexpr>  s*      
;
;S29
;
;
;
;
;
;r*   c                    g | ]
}|d k    |S r   r_   r`   rW   s     r(   re   zplan_einsum.<locals>.<listcomp>  s    000saxxxxxr*   r   c                    g | ]
}|d k    |S )r   r_   r   s     r(   re   zplan_einsum.<locals>.<listcomp>  s    <<<C#))C)))r*   )r#   r   rO   r4   r5   r  r   rN   r   rg   filterr   r   r   r   r   rB   r   r   r   r   )r+   rp   r   r   rr   r   r   r   r   r   op_namesr   support
down_countrY   rk   mask	to_reducerW   r  r   r  rV   r   r   r   unsqueeze_dimssqueeze_dimss                               r(   plan_einsumr*  q  s    h--Cvay>>D#g,,D 66D--%**---HT\8X	.	.///  tXv... VZ00    g
 
DK88
 
 

 "*-- 	  	 HAuAJJJ%JJJJ	  U3ZZ<< . .4	"%d455k4;"H"H 	E 	ECVC

SSDDDD6"2"2I>>?? 	<ad;;;; i(( 	. 	.DAqTBBx-Q"WDHAJJJqBww!!A-JJJJ	. 3ZZ   66& :a!e$%% 	T1q5!,,,,fa!eQ
GWg    CC
37(;DEE(BCCCCCCCC":D

;
;Id5D5k$:$:
;
;
;;;  00t000$<<4$37nnGwi$6DMM$t__ 	- 	-EBBww #S1WR#tETE{++ 	* 	*EBBww%%b))) 	 $37nnGwi.@DMM$<<4;<<<L  sQw..	7L8dKr*   left_equationtuple[str, str, list[Tensor]]c           	        d}d}g }d t          t          d          t          d                    D             t          |                     d          |          D ]g\  }}t	          |j                  t	          |                    dd                    z
  }t          ||          }|D ]}	                    |	           ht          |                     d          |          D ]\  }}d|v rz|	                    d          |t	          |j                  t	          |                    dd                    z
  z
  }
t          |fd	t          |
          D             
          }|                    |           d                    fdt          |          D                       }|,|                     d|          } |                    d|          }| ||fS )zU
    we replace ... as unused variables to simplify the EinsumOp implementation.
    Nr   c                ,    h | ]}t          |          S r_   )chr)r`   r%   s     r(   	<setcomp>z#replace_ellipsis.<locals>.<setcomp>  s    BBB1ABBBr*   rl   zr/   r   r   c                    g | ]}|z   S r_   r_   )r`   rY   start_unsqueeze_idxs     r(   re   z$replace_ellipsis.<locals>.<listcomp>  s    MMM!a--MMMr*   )axisc              3  @   K   | ]}                                 V  d S r   )rh   )r`   _unused_variabless     r(   rb   z#replace_ellipsis.<locals>.<genexpr>  s0      OO!/3355OOOOOOr*   )rO   ordrN   r3   r#   r$   r    r   discardindexr   rg   rf   )r+  r8   r+   ellipsis_stringsmax_ndimnew_operandsequr   r&   r%   to_squeeze_numr3  r7  s              @@r(   replace_ellipsisr@    s    H!#LBBc#hhC(A(ABBBM//44h?? ( (WGM""SUB)?)?%@%@@x'' 	( 	(A$$Q''''	( M//44h?? 
% 
%WC<<"%))E"2"2%GM""SUB)?)?%@%@@N  MMMMu^7L7LMMM  G 	G$$$$wwOOOOuXOOOOO#%--e5EFFkk%!122#|++r*   equation(tuple[str, str, list[str], list[Tensor]]c           	        |                      dd          } t          |          }|dk    sJ d|             |                                                     d          ^}}t          |          dk     s
J d            t	          ||          }|r|d         nd}|t          |          }t          |                    d	                    t          |          k    s>J d
t          |           dt          |                    d	                     d            d|v rd|vr
J d            t          ||g|R  \  }}}||||fS )zG
    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/   r0   r1   r2   r   r?   )r    r#   lowerr3   r7   rhs_inferencer@  )rA  r+   r   lhsr8   rj   r=  s          r(   
preprocessrJ    sz    R((H
h--C777JSJJ 77
   &&t,,IC#s88a<<<F<<<#x((F
!#a&&TC
{C  syy~~#h--///	Ks8}} 	K 	K3((	K 	K 	K 0//
 c!1!1!1> "2!12 .c3BBBBClV\))r*   c                      e Zd ZU ded<   dS )ShapedrH   r$   N)r  r  r  __annotations__r_   r*   r(   rL  rL  0  s         r*   rL  list[Shaped]c                    d |                      d          D             }dd
}t          t          ||||                    }|S )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  >   K   | ]}|                                 V  d S r   )strip)r`   r  s     r(   rb   z#parse_fake_shape.<locals>.<genexpr>B  s*      <<1QWWYY<<<<<<r*   r/   	ori_labelr   labelr   r   r   rL  c                   t          |j                  t          |          k    s/J dt          |j                   dt          |                       d t          t          ||j                            D             }t	          t          t          |                    }d| v r)|                    |                     d          d           t          |          S )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 != c                    g | ]
\  }\  }}|S r_   r_   )r`   rY   ra   rU   s       r(   re   z8parse_fake_shape.<locals>.fake_shape.<locals>.<listcomp>L  s     DDDyq&1aDDDr*   r   r   )
r#   r$   r   rN   r4   r5   absinsertr:  rL  )rR  rS  r   fakess       r(   
fake_shapez$parse_fake_shape.<locals>.fake_shapeD  s    
 28}}E

***qRUVXV^R_R_qqehineoeoqq +** EDIc%.B.B$C$CDDDSe__%%)LL--q111e}}r*   )rR  r   rS  r   r   r   r   rL  )r3   r4   r5   )rA  r+   rj   origin_labelsrY  outs         r(   parse_fake_shaper\  4  sY     =<s(;(;<<<M    s:}fh??
@
@CJr*   rI  c           
         fd}t          j        |           d| v rdnd}|d                    t          |t	                                                                        z   }|S )Nc                >                         |           dk    o| dvS )Nr   )r   r/   )get)keycnts    r(   is_freezrhs_inference.<locals>.is_freeW  s"    wws||q :S
%::r*   r   r   )collectionsCounterrf   r"  rB   elements)rI  rb  r8   ra  s      @r(   rH  rH  V  st    ; ; ; ; ; 
c
"
"CC<<%%RC
ws||~~(>(>??@@
@CJr*   tuple[str, str]c                    dd}t          j        |           } ||          }|t          |           }|                     d|          } |                    d|          }| dz   |z   |fS )z7
    1. gen rhs if rhs is None
    2. '...' -> 'A'
    r   r   c                    t          |                                           }t          j        D ]
}||vr|c S t	          d          )NzSYou have used all `a` - `z`, there can't find a unused char for einsum optimization)r@   re  stringascii_lowercase
ValueError)counterusedr%   s      r(   get_used_labelz2gen_equation_for_opteinsum.<locals>.get_used_labelf  sY    7##%%&&' 	 	A}} a
 
 	
r*   Nr   rE  )r   r   )rc  rd  rH  r    )rI  r8   rn  ra  broadcast_labels        r(   gen_equation_for_opteinsumrp  `  s    
 
 
 
 
c
"
"C$nS))O
{C  
++e_
-
-C
++e_
-
-C:_,,r*   c                Z   t          |          }t          | g|R  \  }}}}|dk    rt          |dz   |z   g|R  S t          |||          }t	          ||          \  }}	t          j        |g|R ddi\  }
}|}|D ]{}|^\  }}}
}}||k    s
J d            |                    |          |                    |          g}|                    |	d          }|	                    t          |g|R             |t          |          dk    sJ dt          |           d	            |d
         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   rE  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#   rJ  gen_einsum_opr\  rp  
opt_einsumcontract_pathrh   r    rg   )rA  r+   n_oprI  r8   rj   r=  shapesopt_equationro  r6  consvar_listpathrl   rm   eq__var_ss                      r(   	einsum_v2r  x  sr    x==D%/%D8%D%D%D"CflqyyS4Z#-=====c<88F$>sC$H$H!L/&|OfOOO$OOGAtH 3 3!A21uuuc uu a(,,q//2ZZ//b151112222x==ALCMMLLL  A;r*   c                j   t                      rt          j        |           d         S dt                    cxk    rdk    sn J d            D ]}t	          |dddgd           t          | d	t          d           t          di t                      	                    d         j
        
          }i }| |d	<   fdt          t                              D             }fdt          t                              D             }                    ddi|||d|           |S )z$
    EinsumOp Python Interface:
    r   r   r   z&Only support two operands in EinsumOp.dtypefloat32float64einsumrA  r  c                R    g | ]#}                     d          j                  $S r   r  "create_variable_for_type_inferencer  r`   rY   helperr+   s     r(   re   z!gen_einsum_op.<locals>.<listcomp>  A     
 
 
 55HQK<M5NN
 
 
r*   c                R    g | ]#}                     d          j                  $S r  r  r  s     r(   re   z!gen_einsum_op.<locals>.<listcomp>  r  r*   Operands)Out
InnerCacheXShape)typeinputsoutputsattrsN)r  )r
   r   r  r#   r	   r   r   r   localsr  r  rO   	append_op)rA  r+   inpr[  r  cachesxshaper  s    `     @r(   rs  rs    s   
  }Xx0033CMM&&&&Q&&&&&(P&&& 	 	C$Wy)4h    	8Zh777222277hqk>O7PP$j
 
 
 
 
3x==))
 
 

 
 
 
 
3x==))
 
 
 	)vHH	 	 	
 	
 	
 
r*   Tensor | Nonec           	        ddl }t          |j                            dd                    rt	          | g|R  S t          |          }|dk    s
J d            |                                                     dd                              d          ^}}t          |          d	k     s
J d
            |r|d         nd}t          ||          }t          t          t          t          ||                     \  }}t          d |D                       }t          |||          \  }}	}
}t!          |	|d |D                       \  }}t#          ||	||||          }|                                }|S )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.rD  r   rE  r   rF  c              3  @   K   | ]}|                     d           V  dS )r   N)rk   r   s     r(   rb   zeinsum.<locals>.<genexpr>n  s,      88qwws||888888r*   c                    g | ]	}|j         
S r_   )r$   )r`   r   s     r(   re   zeinsum.<locals>.<listcomp>  s    77728777r*   )osr<   environr_  r  r#   rG  r    r3   r7   r4   rN   r5   r   r   rs   r   r*  r  )rA  r+   r  r   rI  r8   r6   r;   rd   rp   rq   rr   r   r   r   results                   r(   r  r    s   x III
2:>>,c2233 .-H----
h--C7777777   ((b1177==IC#s88a<<<F<<< 
!#a&&TC c8,,J  Sj(%K%K LMMJ
 88Z88888L, ):C) )%Hffg -77h777 GZ
 &':w D \\^^FMr*   )r   r   r   r   r   r   )r   r   r+   r,   r   r-   )r8   r   r9   r:   r;   r<   r   r=   )rF   r   rG   r   r   rH   )r6   r:   r8   r[   r;   r<   r   r\   )rp   rt   rd   r   ru   rv   r   rw   )rj   r   r   r   )rj   r   r   r   r   r   )
r   r   r   r<   r   rH   r   r   r   r=   )r   r   r   r<   r   r<   r   r=   )r   r   rp   rt   r   r<   r   r<   r   r   r   rH   r   rH   r   rH   r   rH   r   rH   r   r=   )r   r   rp   rt   r   r<   r   r<   r   r   r   rH   rr   r   r   r<   r   r=   )r   rH   r   r   )r   r   r+   r,   r   rt   r   r=   )r+   r,   rp   rt   r   rH   r   r   rr   r   r   r<   r   r   )r+  r   r8   r   r+   r   r   r,  )rA  r   r+   r   r   rB  )rA  r   r+   r,   rj   r:   r   rN  )rI  r   r   r   )rI  r   r8   r[   r   rf  )rA  r   r+   r   r   r   )rA  r   r+   r   r   r  )=
__future__r   rc  rP   rJ   ri  typingr   r   numpyr   rt  paddler   base.data_feederr   r	   base.frameworkr
   base.layer_helperr   linalgr   r   manipulationr   r   r   mathr   r   r   collections.abcr   r   __all__r)   r7   rE   rZ   rs   r   r   r   r   r   r   r   r   r   r   r*  r@  rJ  rL  r\  rH  rp  r  rs  r  r_   r*   r(   <module>r     s   # " " " " "         				  , , , , , , , ,               C C C C C C C C 3 3 3 3 3 3 + + + + + + % % % % % % % % 5 5 5 5 5 5 5 5 5 5       
  ((((((
" " " "J< < < <2   <2 2 2 2j<- <- <- <-~/ / / /d* * * *   &
 
 
 
   W! W! W! W!t.K .K .K .Kb      8       :u u u up!, !, !, !,H *  *  *  *F    Z      D   - - - -0   >       FW W W W W Wr*   