
    1;ji                     J   d dl Z d dlZd dlZd dlZd dlmZ d dlmZmZmZm	Z	m
Z
mZmZmZmZmZ ej        rd dlZddlmZ ddlmZ ddlmZmZmZ  ed          Zeeeed	f         gef         Ze
eef         Zej        Z d
Z!dZ"dZ#dee         defdZ$dedee         fdZ%d Z&eeee                  eee                  ee         e	eef         eee                  ef         Z'eeeef         d	f         Z(eeeef                  Z) G d d          Z*de*dee         de)de'fdZ+  e j,        d          e+          Z-de*dedede(def
dZ.de*dedede(def
dZ/ e j,        d           d!ed"ed#eed	f         d$ede*f
d%            Z0d!ed"ed#eed	f         de	ee*f         fd&Z1de
eee         f         d!ed'ede def
d(Z2de
eee         f         d!ede defd)Z3de
eee         f         d!ede defd*Z4d+ed!ede5fd,Z6d- Z7eZ8dede8fd.Z9d/ Z: e j,        d           d!edefd0            Z;ej<        ded!edefd1            Z=ej<        d2ed3ed!edefd4            Z=ej<        d2ed3ed5ed!edef
d6            Z=ej<        d2ed3ed5ed7ed!edefd8            Z=d9e
eef         defd:Z=dS );    N)OrderedDict)
SetTupleListDictUnionCallableOptionalTypeVarcastAny   )EinopsError)get_backend)ParsedExpression	_ellipsisAnonymousAxisTensor.)minmaxsummeanprodanyalliiaysequencereturnc                     d}| D ]}||z  }|S )zSminimalistic product that works both with numbers and symbols. Supports empty listsr    )r   resultelements      G/root/voice-cloning/.venv/lib/python3.11/site-packages/einops/einops.py_productr#      s'    F  'M    reduction_typereduced_axesc                    t          |          r || t          |                    S |t          v sJ |dk    r$|                    |           st	          d          |                    | |t          |                    S )Nr   z5reduce_mean is not available for non-floating tensors)callabletuple_reductionsis_float_typeNotImplementedErrorreduce)tensorr%   r&   backends       r"   _reduce_axesr0   %   s     	K~feL&9&9::: ,,,,V##((00 c)*abbb~~fneL6I6IJJJr$   c                 |    t                    t                    z   t                     k    sJ t          t                              t          t                    dz
            d d d         D ]}|         dz   |dz            k    rp|dz                      } d           dz   d          z     dz
  xx         |z  cc<   d |dz            t          d |dz   d          D                       z    fd} |            }t          t                     dz
            d d d         D ]}||         ||dz            ||         dz   ||dz            k    r|dz             }t	          fdt                    D                       }	t          fdD                        d           dz   d          z     dz
  xx         |z  cc<   }
g |
D ]=}||	k    r	||	k     r                    |           %                    |dz
             > |            } |fS )Nr   c              3       K   | ]	}|d z
  V  
dS r   Nr   ).0axiss     r"   	<genexpr>z+_optimize_transformation.<locals>.<genexpr>?   s&      8d8dd8d8d8d8d8d8dr$      c                      i } t          t                              D ]\}|v rd | |<   t          d |                                 D                       }t	                                        |          | |<   ]| S )Nc              3      K   | ]}|d uV  	d S Nr   )r5   xs     r"   r7   zB_optimize_transformation.<locals>.build_mapping.<locals>.<genexpr>H   s&      %T%Tatm%T%T%T%T%T%Tr$   )rangelenr   valueslistindex)init_to_finalr6   after_reductionaxes_reorderinginit_shapesr&   s      r"   build_mappingz/_optimize_transformation.<locals>.build_mappingB   s    #k**++ 	S 	SD|##&*d##"%%T%T]=Q=Q=S=S%T%T%T"T"T&*?&;&;&A&A/&R&Rd##r$   c              3       K   | ]}|vV  	d S r;   r   )r5   r<   r&   s     r"   r7   z+_optimize_transformation.<locals>.<genexpr>V   s(      .b.bq/D.b.b.b.b.b.br$   c              3   2   K   | ]}|k     r|n|d z
  V  dS r4   r   )r5   r6   removed_axiss     r"   r7   z+_optimize_transformation.<locals>.<genexpr>X   s5       d dt)<)<$( d d d d d dr$   )r>   r)   sortedr=   r   append)rE   r&   rD   final_shapesiremoved_lengthrF   init_axis_to_final_axis	init_axisremoved_axis_after_reductionold_reorderingr6   rI   s   ```         @r"   _optimize_transformationrS   2   s    #l"3"33s;7G7GGGGG --..L3|$$q())$$B$/ e e?Q,q1u"555'A.L(6N%m|m4{<RSCSCUCU7VVKq()))^;)))'!a%058d8dl[\_`[`[b[bNc8d8d8d3d3ddL       ,moo3{++a/0026 6 6	"9-5"9q=19"9-15LYYZ]5[[[$q=L(6N+..b.b.b.beT`NaNa.b.b.b+b+b(  d d d dWc d d dddL%m|m4{<RSCSCUCU7VVKq()))^;))),N O& 5 5777888#**40000#**4!84444&3moo#o|CCr$   c                       e Zd ZdZdee         deeef         deeee         ee         f                  dee         dedeeef         deee                  fd	Z	d
S )TransformRecipezi
    Recipe describes actual computation pathway.
    Recipe can be applied to a tensor or variable.
    elementary_axes_lengthsaxis_name2elementary_axisinput_composition_known_unknownaxes_permutationfirst_reduced_axis
added_axesoutput_composite_axesc                 h    || _         || _        || _        || _        || _        || _        || _        d S r;   rV   rW   rX   rY   rZ   r[   r\   )selfrV   rW   rX   rY   rZ   r[   r\   s           r"   __init__zTransformRecipe.__init__{   sB    , 3J$9R&Rq,+;'9*46K"""r$   N)
__name__
__module____qualname____doc__r   intr   strr   r`   r   r$   r"   rU   rU   r   s         L
 "&cL $(S>L *.eDItCy4H.I)JL s)L  L" cN#L(  $DI)L L L L L Lr$   rU   r_   shape	axes_dimsc                 b   d}t          | j                  |D ]\  }}|| j        |         <   t          | j                  D ]-\  }\  }}||         }	t          |          dk    rt          |          dk    r|	|d         <   Cd}
|D ]}|
|         z  }
t          |          dk    rFt          |	t                    r0t          |
t                    r|	|
k    rt          d|	 d|
           nZt          |	t                    r3t          |
t                    r|	|
z  dk    rt          d|	 d|
           |d         }|	|
z  }||<   t          |          t          |          z   dk    rd}/|rd	t          | j	                           nd	}d}g }| j
        D ]G}fd
|D             }|                    t          |                     t          |          dk    rd}Hfd| j                                        D             }t          t          | j        t          | j	                                      }t          |          t          | j	                  z   }| j	        }| j	        t          t          t          | j	                                      k    rd	}|r|nd	}||||||fS )z
    Reconstruct all actual parameters using shape.
    Shape is a tuple that may contain integers, shape symbols (tf, theano) and UnknownSize (tf, previously mxnet)
    known axes can be integers or symbols, but not Nones.
    Fr   r   zShape mismatch, z != z,Shape mismatch, can't divide axis of length z in chunks of TNc                      g | ]
}|         S r   r   )r5   elementary_axisaxes_lengthss     r"   
<listcomp>z4_reconstruct_from_shape_uncached.<locals>.<listcomp>   s    QQQ_<0QQQr$   c                 (    i | ]\  }}||         S r   r   )r5   pospos_in_elementaryrl   s      r"   
<dictcomp>z4_reconstruct_from_shape_uncached.<locals>.<dictcomp>   s3     " " "1G6G\+," " "r$   )r@   rV   rW   	enumeraterX   r>   
isinstancere   r   rY   r\   rK   r#   r[   itemsr=   rZ   )r_   rg   rh   need_init_reshaper6   dim
input_axis
known_axesunknown_axeslengthknown_productunknown_axisinferred_lengthrE   need_final_reshaperL   groupinglengthsr[   r&   n_axes_after_adding_axesrD   _final_shapesrl   s                          @r"    _reconstruct_from_shape_uncachedr      s1     #4#?@@L A A	c=@T3D9::2;D<`2a2a % %.
.Zz"z??aC$5$5$:$:,2La) 	0 	0D\$//MM|!!&#&& R:mS+I+I RfXeNeNe!"PV"P"P"P"PQQQ &#&& x:mS+I+I xfWdNdhiNiNi!"vQW"v"vgt"v"vwww'?L#)]#:O)8L&z??S...!33 $
 Vg'p|4Pc$:O6P6P4P'Q'QlpK L. & &QQQQQQQHW--...w<<1!%" " " "KO?K`K`KbKb" " "J
 d5s4;P7Q7QRRSSL":T5J1K1KK+/+@OU3t/D+E+E%F%F G GGG$6@LLDMz=Rjjjr$   i   reciper.   rl   c                    	 t          ||                     |          |          \  }}}}}	}
n=# t          $ r0 t          ||                     |          |          }|\  }}}}}	}
Y nw xY w||                     ||          }||                     ||          }t          |          dk    rt          ||||           }t          |          dk    r|                     ||
|          }|	|                     ||	          }|S )Nr   )r%   r&   r/   )n_axespos2len)	_reconstruct_from_shaperg   	TypeErrorr   reshape	transposer>   r0   add_axes)r/   r   r.   r%   rl   rE   rD   r&   r[   rL   n_axes_w_added_results               r"   _apply_reciper      s:   i_vGMM&))<`
 `
\_lJnn  i i i267==;P;PR^__ah^o|Z~~~i 55"""6?;;
<1f^R^hoppp
:!!&!TT66Ms   +. 7A('A(c                    t          ||j        |          \  }}}}}	}
||                     ||          }||                     ||          }t	          |          dk    r\t          |          r ||t          |                    }n3|t          v sJ  t          | |          |t          |                    }t	          |          dk    rz|	                                D ]\  }}| 
                    ||          }t          |j                  }|	                                D ]
\  }}|||<   |                     ||          }|	|                     ||	          }|S )Nr   )r6   )r   rg   r   permute_dimsr>   r(   r)   r*   getattrrt   expand_dimsr@   broadcast_to)xpr   r.   r%   rl   rE   rD   r&   r[   rL   r   axis_positionaxis_lengthfinal_shapes                 r"   _apply_recipe_array_apir      s    \sl\ \XK,
L. FK00"99
<1N## 	S#^FE,,?,?@@FF "[00000WR00eL>Q>QRRRF
:*4*:*:*<*< 	@ 	@&M;^^F^??FF6<((*4*:*:*<*< 	5 	5&M;)4K&&55FL11Mr$      pattern	operation
axes_namesndimc           	         !"# |                      d          \  }}t          |          !t          |          #!j        s)#j        r"t          d                    |                     !j        r)!j        r"t          d                    |                     |dk    ry!j        s#j        rt          d          t                              !j	        #j	                  }t          |          dk    r"t          d                    |                    ne|dk    rt                              !j	        #j	                  }t          |          dk    r"t          d	                    |                    t                              d
 #j	        D             h !j	        |          }t          |          dk    r"t          d                    |                    n|t          v st          |          r\t                              #j	        !j	                  }t          |          dk    r#t          d                    ||                    n(t          d                    |t                              !j        rt          !j                  dz
  }||k     rt          d| d| d          ||z
  }	d t          |	          D             }
g }!j        D ]>}|t           k    r|
D ]}|                    |g           )|                    |           ?g }#j        D ]{}|t           k    r|
D ]}|                    |g           )g }|D ]8}|t           k    r|                    |
           #|                    |           9|                    |           |!j	                            |
           !j	                            t                      #j        r9#j	                            |
           #j	                            t                      nN|t          !j                  k    r(t          dt          !j                   d| d          !j        }#j        }t+                      |D ]1}|D ],}t-          |t.                    r|j        |<   "t2          |<   -2g }#j	        D ]E}|vr?t-          |t.                    r|j        |<   n
t2          |<   |                    |           Fd t5                    D              |D ]V}t          j        |          st          d|          |vr"t          d                    |                    t8          |<   Wg }t5          |          D ]\  }}fd|D             }fd|D             }t          |          dk    r"t          d                    |                    t          |          t          |          z   t          |          k    sJ |                     fd|D              fd|D             f           i }t;          j        | D ]}|#j	        v rt          |          ||<    fdt5          |          D             }t?          t;          j        |           "t?          t;          j        |           }#fd"D             }!fd|D             |z   }"fd|D             } !fd t5          |          D             }t          |          t          |          z
  }tA          t?          !                                           fd!|D             |||||"          S )#zPerform initial parsing of pattern and provided supplementary info
    axes_lengths is a tuple of tuples (axis_name, axis_length)
    ->z?Ellipsis found in right side, but not left side of a pattern {}z?Ellipsis inside parenthesis in the left side is not allowed: {}	rearrangezQNon-unitary anonymous axes are not supported in rearrange (exception is length 1)r   zBIdentifiers only on one side of expression (should be on both): {}repeatz5Unexpected identifiers on the left side of repeat: {}c                 <    h | ]}t          |t                    |S r   )rs   r   )r5   axs     r"   	<setcomp>z1_prepare_transformation_recipe.<locals>.<setcomp>?  s'    PPPB*R2O2OPRPPPr$   z(Specify sizes for new axes in repeat: {}z9Unexpected identifiers on the right side of reduce {}: {}z'Unknown reduction {}. Expect one of {}.r   zWrong shape: expected >=z dims. Received z-dim tensor.c                 <    g | ]}t           t          |          z   S r   )r   rf   )r5   rM   s     r"   rm   z2_prepare_transformation_recipe.<locals>.<listcomp>P  s#    EEE1IA&EEEr$   zWrong shape: expected c                     i | ]\  }}||	S r   r   )r5   positionnames      r"   rq   z2_prepare_transformation_recipe.<locals>.<dictcomp>  s    aaa^Xt$aaar$   zInvalid name for an axisz Axis {} is not used in transformc                 6    h | ]}|         t           k    |S r   _unknown_axis_lengthr5   r6   axis_name2known_lengths     r"   r   z1_prepare_transformation_recipe.<locals>.<setcomp>  s+    sssD>TUY>Z^r>r>r4>r>r>rr$   c                 6    h | ]}|         t           k    |S r   r   r   s     r"   r   z1_prepare_transformation_recipe.<locals>.<setcomp>  s+    uuud@VW[@\`t@t@tT@t@t@tr$   zCould not infer sizes for {}c                      g | ]
}|         S r   r   r5   r6   axis_name2positions     r"   rm   z2_prepare_transformation_recipe.<locals>.<listcomp>  s    9994 &999r$   c                      g | ]
}|         S r   r   r   s     r"   rm   z2_prepare_transformation_recipe.<locals>.<listcomp>  s     ;i;i;iY]<Nt<T;i;i;ir$   c                 2    g | ]\  }}fd |D             S )c                      g | ]
}|         S r   r   r   s     r"   rm   z=_prepare_transformation_recipe.<locals>.<listcomp>.<listcomp>  s    ===d	D	!===r$   r   )r5   rM   composite_axisr   s      r"   rm   z2_prepare_transformation_recipe.<locals>.<listcomp>  s?     - - -BS!^====n===- - -r$   c                 &    g | ]}|j         v|S r   identifiers)r5   r6   rghts     r"   rm   z2_prepare_transformation_recipe.<locals>.<listcomp>  s&    WWWT$dFV:V:VD:V:V:Vr$   c                 &    g | ]}|j         v |S r   r   )r5   r6   lefts     r"   rm   z2_prepare_transformation_recipe.<locals>.<listcomp>  s&     ` ` `$ttO_G_G_G_G_G_r$   c                 :    g | ]}                     |          S r   )rA   )r5   r6   ordered_axis_lefts     r"   rm   z2_prepare_transformation_recipe.<locals>.<listcomp>  s(    \\\$)//55\\\r$   c                 :    i | ]\  }}|j         v||         S r   r   )r5   rM   	axis_namer   r   s      r"   rq   z2_prepare_transformation_recipe.<locals>.<dictcomp>  s=       AyD,,, 	
i(,,,r$   c                 "    i | ]}||         S r   r   r   s     r"   rq   z2_prepare_transformation_recipe.<locals>.<dictcomp>  s!    "Y"Y"Yd4);D)A"Y"Y"Yr$   r^   )"splitr   has_ellipsisr   formathas_ellipsis_parenthesizedhas_non_unitary_anonymous_axessetsymmetric_differencer   r>   
differencer*   r(   compositionr=   r   rK   extendupdateremover   rs   r   valuer   rr   check_axis_name_expected_axis_length	itertoolschainr@   rU   r?   )$r   r   r   r   left_strrght_strr   axes_without_sizen_other_dimsellipsis_ndimell_axesleft_compositionr   r6   rght_compositiongroupr   repeat_axes_namesrk   input_axes_known_unknownrM   knownunknownaxis_position_after_reductionresult_axes_groupingordered_axis_rghtr&   order_after_transpositionrY   r[   rZ   r   r   r   r   r   s$                                  @@@@@r"   _prepare_transformation_reciper   !  s    !t,,HhH%%DH%%D  m!2 m[bbcjkklll mT< m[bbcjkklllK. 	s$2U 	sqrrr--d.>@PQQ
z??Qbiijtuuvvv 	h		^^D$4d6FGG
z??QU\\]ghhiiiNNPP$*PPP,d,,
 
  !!A%%HOOPabbccc &	k	!	!Xi%8%8	!^^D$4d6FGG
z??QY``ajlvwwxxx  CJJ9Vabbccc %,4+,,q0,iiiW[iiijjj|+EEm0D0DEEE". 	8 	8N**$ 4 4D$++TF33334 !''7777". 	/ 	/N**$ 4 4D$++TF33334 * + +Dy((X....T**** ''....)))	*** 	/##H---##I...3t'((((ps4;K7L7Lpp^bpppqqq++ DO==* I I' 	I 	II)]33 I4=O&y114H&y11		I % 0 0	222)]33 I4=O&y114H&y1$$Y///aayI_?`?`aaa & H H/@@ 	K8/JJJ"888@GGXXYYY2G//!&'788 
 
>ssssNsssuuuunuuuw<<!<CCGLLMMM7||c%jj(C,?,????? ''99995999;i;i;i;iah;i;i;ij	
 	
 	
 	
 57!_&67 Z Z	(((7:;X7Y7Y))4- - - -W`aqWrWr- - - Y_.>?@@Y_.>?@@WWWW%6WWWL ` ` ` `2C ` ` `co o\\\\B[\\\    %&788  J 677#l:K:KK $%;%B%B%D%D E E"Y"Y"Y"Yj"Y"Y"Y(@)-2   r$   c                                            d          \  }}t          |          t          j                  g}j        rfdt          d          D             } fd|D             S )z
    Internal function, used in layers.
    Layer makes all recipe creation when it is initialized, thus to keep recipes simple we pre-compute for all dims
    r   c                 D    g | ]}t          j                  d z
  |z   S )r   )r>   r   )r5   ellipsis_dimsr   s     r"   rm   z1_prepare_recipes_for_all_dims.<locals>.<listcomp>  s.    XXXmD$%%)M9XXXr$      c           	      8    i | ]}|t          |           S ))r   )r   )r5   r   r   r   r   s     r"   rq   z1_prepare_recipes_for_all_dims.<locals>.<dictcomp>  s/    mmm`dD0)ZVZ[[[mmmr$   )r   r   r>   r   r   r=   )r   r   r   r   r   dimsr   s   ```   @r"   _prepare_recipes_for_all_dimsr     s     !t,,HhH%%D !!"D YXXXXuUVxxXXXmmmmmmhlmmmmr$   	reductionc                 *   	 t          | t                    rMt          |           dk    rt          d          t	          | d                   }|                    |           } nt	          |           }t          |                                          }|                    |           }t          ||t          |          t          |                    }t          ||t          t          |           ||          S # t          $ r}d                    ||          }	t          | t                    s|	d                    |          z  }	n|	dz  }	|	d                    |          z  }	t          |	d	                    |          z             d
}~ww xY w)a  
    einops.reduce combines rearrangement and reduction using reader-friendly notation.

    Some examples:

    ```python
    >>> x = np.random.randn(100, 32, 64)

    # perform max-reduction on the first axis
    # Axis t does not appear on RHS - thus we reduced over t
    >>> y = reduce(x, 't b c -> b c', 'max')

    # same as previous, but using verbose names for axes
    >>> y = reduce(x, 'time batch channel -> batch channel', 'max')

    # let's pretend now that x is a batch of images
    # with 4 dims: batch=10, height=20, width=30, channel=40
    >>> x = np.random.randn(10, 20, 30, 40)

    # 2d max-pooling with kernel size = 2 * 2 for image processing
    >>> y1 = reduce(x, 'b c (h1 h2) (w1 w2) -> b c h1 w1', 'max', h2=2, w2=2)

    # same as previous, using anonymous axes,
    # note: only reduced axes can be anonymous
    >>> y1 = reduce(x, 'b c (h1 2) (w1 2) -> b c h1 w1', 'max')

    # adaptive 2d max-pooling to 3 * 4 grid,
    # each element is max of 10x10 tile in the original tensor.
    >>> reduce(x, 'b c (h1 h2) (w1 w2) -> b c h1 w1', 'max', h1=3, w1=4).shape
    (10, 20, 3, 4)

    # Global average pooling
    >>> reduce(x, 'b c h w -> b c', 'mean').shape
    (10, 20)

    # subtracting mean over batch for each channel;
    # similar to x - np.mean(x, axis=(0, 2, 3), keepdims=True)
    >>> y = x - reduce(x, 'b c h w -> 1 c 1 1', 'mean')

    # Subtracting per-image mean for each channel
    >>> y = x - reduce(x, 'b c h w -> b c 1 1', 'mean')

    # same as previous, but using empty compositions
    >>> y = x - reduce(x, 'b c h w -> b c () ()', 'mean')

    ```

    Parameters:
        tensor: tensor: tensor of any supported library (e.g. numpy.ndarray, tensorflow, pytorch).
            list of tensors is also accepted, those should be of the same type and shape
        pattern: string, reduction pattern
        reduction: one of available reductions ('min', 'max', 'sum', 'mean', 'prod', 'any', 'all').
            Alternatively, a callable f(tensor, reduced_axes) -> tensor can be provided.
            This allows using various reductions like: np.max, np.nanmean, tf.reduce_logsumexp, torch.var, etc.
        axes_lengths: any additional specifications for dimensions

    Returns:
        tensor of the same type as input
    r   z9Rearrange/Reduce/Repeat can't be applied to an empty list)r   r   )r%   rl   z2 Error while processing {}-reduction pattern "{}".z
 Input tensor shape: {}. z
 Input is list. zAdditional info: {}.z
 {}N)rs   r@   r>   r   r   stack_on_zeroth_dimensionr)   rt   rg   r   r   r   r   r   r   )
r.   r   r   rl   r/   hashable_axes_lengthsrg   r   emessages
             r"   r-   r-     s   x7fd## 	*6{{a [\\\!&),,G66v>>FF!&))G %l&8&8&:&: ; ;f%%/uUaObObilmrisistttVT&&11)Zo
 
 
 	
  7 7 7FMMiY`aa&$'' 	,4;;EBBBGG++G)00>>>'GNN1$5$556667s   C:C= =
FBFFc                 "    t          | |fddi|S )a  
    einops.rearrange is a reader-friendly smart element reordering for multidimensional tensors.
    This operation includes functionality of transpose (axes permutation), reshape (view), squeeze, unsqueeze,
    stack, concatenate and other operations.

    Examples:

    ```python
    # suppose we have a set of 32 images in "h w c" format (height-width-channel)
    >>> images = [np.random.randn(30, 40, 3) for _ in range(32)]

    # stack along first (batch) axis, output is a single array
    >>> rearrange(images, 'b h w c -> b h w c').shape
    (32, 30, 40, 3)

    # stacked and reordered axes to "b c h w" format
    >>> rearrange(images, 'b h w c -> b c h w').shape
    (32, 3, 30, 40)

    # concatenate images along height (vertical axis), 960 = 32 * 30
    >>> rearrange(images, 'b h w c -> (b h) w c').shape
    (960, 40, 3)

    # concatenated images along horizontal axis, 1280 = 32 * 40
    >>> rearrange(images, 'b h w c -> h (b w) c').shape
    (30, 1280, 3)

    # flattened each image into a vector, 3600 = 30 * 40 * 3
    >>> rearrange(images, 'b h w c -> b (c h w)').shape
    (32, 3600)

    # split each image into 4 smaller (top-left, top-right, bottom-left, bottom-right), 128 = 32 * 2 * 2
    >>> rearrange(images, 'b (h1 h) (w1 w) c -> (b h1 w1) h w c', h1=2, w1=2).shape
    (128, 15, 20, 3)

    # space-to-depth operation
    >>> rearrange(images, 'b (h h1) (w w1) c -> b h w (c h1 w1)', h1=2, w1=2).shape
    (32, 15, 20, 12)

    ```

    When composing axes, C-order enumeration used (consecutive elements have different last axis).
    Find more examples in einops tutorial.

    Parameters:
        tensor: tensor of any supported library (e.g. numpy.ndarray, tensorflow, pytorch).
                list of tensors is also accepted, those should be of the same type and shape
        pattern: string, rearrangement pattern
        axes_lengths: any additional specifications for dimensions

    Returns:
        tensor of the same type as input. If possible, a view to the original tensor is returned.

    r   r   r-   r.   r   rl   s      r"   r   r   !  s"    n &'II[ILIIIr$   c                 "    t          | |fddi|S )a  
    einops.repeat allows reordering elements and repeating them in arbitrary combinations.
    This operation includes functionality of repeat, tile, and broadcast functions.

    Examples for repeat operation:

    ```python
    # a grayscale image (of shape height x width)
    >>> image = np.random.randn(30, 40)

    # change it to RGB format by repeating in each channel
    >>> repeat(image, 'h w -> h w c', c=3).shape
    (30, 40, 3)

    # repeat image 2 times along height (vertical axis)
    >>> repeat(image, 'h w -> (repeat h) w', repeat=2).shape
    (60, 40)

    # repeat image 2 time along height and 3 times along width
    >>> repeat(image, 'h w -> (h2 h) (w3 w)', h2=2, w3=3).shape
    (60, 120)

    # convert each pixel to a small square 2x2. Upsample image by 2x
    >>> repeat(image, 'h w -> (h h2) (w w2)', h2=2, w2=2).shape
    (60, 80)

    # pixelate image first by downsampling by 2x, then upsampling
    >>> downsampled = reduce(image, '(h h2) (w w2) -> h w', 'mean', h2=2, w2=2)
    >>> repeat(downsampled, 'h w -> (h h2) (w w2)', h2=2, w2=2).shape
    (30, 40)

    ```

    When composing axes, C-order enumeration used (consecutive elements have different last axis).
    Find more examples in einops tutorial.

    Parameters:
        tensor: tensor of any supported library (e.g. numpy.ndarray, tensorflow, pytorch).
            list of tensors is also accepted, those should be of the same type and shape
        pattern: string, rearrangement pattern
        axes_lengths: any additional specifications for dimensions

    Returns:
        Tensor of the same type as input. If possible, a view to the original tensor is returned.

    r   r   r   r   s      r"   r   r   [  s"    ^ &'FFXFFFFr$   r<   c                    t          |d          }t          |                               |           }|                                rt	          d| d|           t          |          t          |j                  k    rZ|j        r>t          |          t          |j                  dz
  k     rt	          d| d|           nt	          d| d|           |j        rn|j                            t                    }|j        d|         d	gt          |          t          |j                  z
  dz   z  z   |j        |dz   d         z   }n|j        }i }t          ||          D ]y\  }}t          |          d
k    r|dk    rt	          d| d|           4|\  }	t          |	t                    r|	d	k    r|||	<   Y|	j        |k    rt	          d| d|           z|S )a  
    Parse a tensor shape to dictionary mapping axes names to their lengths.

    ```python
    # Use underscore to skip the dimension in parsing.
    >>> x = np.zeros([2, 3, 5, 7])
    >>> parse_shape(x, 'batch _ h w')
    {'batch': 2, 'h': 5, 'w': 7}

    # `parse_shape` output can be used to specify axes_lengths for other operations:
    >>> y = np.zeros([700])
    >>> rearrange(y, '(b c h w) -> b c h w', **parse_shape(x, 'b _ h w')).shape
    (2, 10, 5, 7)

    ```

    For symbolic frameworks may return symbols, not integers.

    Parameters:
        x: tensor of any supported framework
        pattern: str, space separated names for axes, underscore means skip axis

    Returns:
        dict, maps axes names to their lengths
    Tallow_underscorez'Can't parse shape with composite axes:  r   z2Can't parse shape with this number of dimensions: z7Can't parse shape with different number of dimensions: N_r   zLength of axis is not 1: z)Length of anonymous axis does not match: )r   r   rg   has_composed_axesRuntimeErrorr>   r   r   rA   r   ziprs   rf   r   )
r<   r   exprg   ellipsis_idxr   r    axesr   r6   s
             r"   parse_shaper    s>   4 7T
:
:
:CNN  ##E
 XVWVVuVVWWW
5zzS)))) 	l5zzC001444"#iX_#i#ibg#i#ijjj 5 jY`jjchjjkkk
 &,,Y77OM\M*es5zzC$8$881<=>olQ.0012 	 oF e44 f fkt99>>a"#Pw#P#P#P#PQQQ   FT$$$ f3;;#.F4L:,,&'dSZ'd'd]b'd'deee -Mr$   c           	      &   t          |           }|                    |           }g }t          |          D ]Z\  }}dgt          |          z  }|||<   |                    |                    |                    d|          |                     [|S )aa  
    For an n-dimensional tensor, returns tensors to enumerate each axis.
    ```python
    x = np.zeros([2, 3, 4]) # or any other tensor
    i, j, k = _enumerate_directions(x)
    result = i + 2*j + 3*k
    ```

    `result[i, j, k] = i + 2j + 3k`, and also has the same shape as result
    Works very similarly to numpy.ogrid (open indexing grid)
    r   r   )r   rg   rr   r>   rK   r   arange)r<   r/   rg   r    axis_idr   s         r"   _enumerate_directionsr    s     !nnGMM!EF )% 0 0 N Nc%jj $ggoognnQ&D&DeLLMMMMMr$   c                 F    t          |                               |           S )z
    Convert a tensor of an imperative framework (i.e. numpy/cupy/torch/jax/etc.) to `numpy.ndarray`

    Parameters:
        tensor: tensor of any known imperative framework

    Returns:
        `numpy.ndarray`, converted to numpy
    )r   to_numpy)r.   s    r"   asnumpyr    s      v''///r$   c                 r   t          |           dk    rt          d          t          |           dk    rt          d          | d         } t          | t                    rt          d          t          |           dk    rt	          d          t          | t
                    st	          d          d S )Nr   z2Singleton () axes are not yet supported in einsum.r   z3Shape rearrangement is not yet supported in einsum.z/Anonymous axes are not yet supported in einsum.z&Encountered empty axis name in einsum.z%Axis name in einsum must be a string.)r>   r,   rs   r   r   rf   )r   s    r"   _validate_einsum_axis_namer
    s    
9~~!"VWWW
9~~!"WXXX!I)]++ U!"STTT
9~~CDDDi%% DBCCCD Dr$   c                    d| vrt          d          |                     d          \  }}d |                    d          D             }t          |d          }t          j        }d}i }g }|D ]}	d}
|	j        D ]k}|t          k    r|
d	z  }
t          |           |d         }||vr2|t          |          k    rt          d
          ||         ||<   |dz  }|
||         z  }
l|
                    |
           d                    |          dz   }|j        D ]O}|t          k    r|d	z  }t          |           |d         }||vrt          d| d|  d          |||         z  }P|S )Nr   z!Einsum pattern must contain '->'.c                 2    g | ]}t          |d d           S )T)r   allow_duplicates)r   )r5   r   s     r"   rm   z2_compactify_pattern_for_einsum.<locals>.<listcomp>  s)    sssVZdTDQQQsssr$   ,Tr   r    z...zToo many axes in einsum.r   zUnknown axis z on right side of einsum .)
ValueErrorr   r   stringascii_lettersr   r   r
  r>   r   rK   joinr   )r   	lefts_str	right_strleftsrightoutput_axis_namesrM   axis_name_mappingleft_patternsr   left_patternraw_axis_namer   compact_patterns                 r"   _compactify_pattern_for_einsumr    s   7 <==="==..Iyss^g^m^mnq^r^rsssEY>>>E ,	AM + +!- 	9 	9M	))%&}555%a(I 111-....&'ABBB/@/C!),Q-i88LL\****hh}--4O* 8 8I%%u$O"=111!!$	---\i\\RY\\\]]],Y77r$   c                    d S r;   r   )r.   r   s     r"   einsumr!  9  s    7:sr$   tensor1tensor2c                    d S r;   r   )r"  r#  r   s      r"   r!  r!  =  s    ILr$   tensor3c                    d S r;   r   )r"  r#  r%  r   s       r"   r!  r!  A  s    Z]Z]r$   tensor4c                    d S r;   r   )r"  r#  r%  r'  r   s        r"   r!  r!  E  s    knknr$   tensors_and_patternc                     t          |           dk    rt          d          | d         }t          |t                    st          d          | dd         }t	          |          } t          |d                   j        |g|R  S )a  
    einops.einsum calls einsum operations with einops-style named
    axes indexing, computing tensor products with an arbitrary
    number of tensors. Unlike typical einsum syntax, here you must
    pass tensors first, and then the pattern.

    Also, note that rearrange operations such as `"(batch chan) out"`,
    or singleton axes `()`, are not currently supported.

    Examples:

    For a given pattern such as:
    ```python
    >>> x, y, z = np.random.randn(3, 20, 20, 20)
    >>> output = einsum(x, y, z, "a b c, c b d, a g k -> a b k")

    ```
    the following formula is computed:
    ```tex
    output[a, b, k] =
        \sum_{c, d, g} x[a, b, c] * y[c, b, d] * z[a, g, k]
    ```
    where the summation over `c`, `d`, and `g` is performed
    because those axes names do not appear on the right-hand side.

    Let's see some additional examples:
    ```python
    # Filter a set of images:
    >>> batched_images = np.random.randn(128, 16, 16)
    >>> filters = np.random.randn(16, 16, 30)
    >>> result = einsum(batched_images, filters,
    ...                 "batch h w, h w channel -> batch channel")
    >>> result.shape
    (128, 30)

    # Matrix multiplication, with an unknown input shape:
    >>> batch_shape = (50, 30)
    >>> data = np.random.randn(*batch_shape, 20)
    >>> weights = np.random.randn(10, 20)
    >>> result = einsum(weights, data,
    ...                 "out_dim in_dim, ... in_dim -> ... out_dim")
    >>> result.shape
    (50, 30, 10)

    # Matrix trace on a single tensor:
    >>> matrix = np.random.randn(10, 10)
    >>> result = einsum(matrix, "i i ->")
    >>> result.shape
    ()

    ```

    Parameters:
        tensors_and_pattern:
            tensors: tensors of any supported library (numpy, tensorflow, pytorch, jax).
            pattern: string, einsum pattern, with commas
                separating specifications for each tensor.
                pattern should be provided after all tensors.

    Returns:
        Tensor of the same type as input, after processing with einsum.

    r   zd`einops.einsum` takes at minimum two arguments: the tensors (at least one), followed by the pattern.r2   z^The last argument passed to `einops.einsum` must be a string, representing the einsum pattern.Nr   )r>   r  rs   rf   r  r   r!  )r)  r   tensorss      r"   r!  r!  I  s    @ 1$$r
 
 	
 ""%Ggs## 
l
 
 	
 "#2#&G,W55G);wqz"")'<G<<<<r$   )>	functoolsr   r  typingcollectionsr   r   r   r   r   r   r	   r
   r   r   r   TYPE_CHECKINGnumpynpr  r   	_backendsr   parsingr   r   r   r   re   ReductionCallablerf   	ReductionSizer*   r   r   r#   r0   rS   CookedRecipeHashableAxesLengthsFakeHashableAxesLengthsrU   r   	lru_cacher   r   r   r   r   r-   r   r   dictr  r  
np_ndarrayr  r
  r  overloadr!  r   r$   r"   <module>r>     su             # # # # # # X X X X X X X X X X X X X X X X X X X X X X X X	        " " " " " " ? ? ? ? ? ? ? ? ? ?			feCHo6>? #(()	zA   tCy S    
K 
K$s) 
K 
K 
K 
K4D 4D 4Dn Xd3i((49*=tCy$sTWx.ZbcghkclZmorrs
 E#s(OS01 uS#X/ &L &L &L &L &L &L &L &LREk
Ek"&s)Ek8OEkEk Ek Ek EkP 4-)-d334TUU $.4FO_r   2)/AJZm   D SXXX c3hX 	X
 X X X Xvnn&n49#s(On	#
n n n nR75f-. R7 R7 R7dh R7ms R7 R7 R7 R7j7JeFDL01 7JC 7JQU 7JZ` 7J 7J 7J 7Jt/G5f-. /G /Gd /GW] /G /G /G /Gd;6 ;C ;D ; ; ; ;~  . 

0F 
0z 
0 
0 
0 
0D D D  S2C 2C 2 2 2 2j  :6 :C :v : : :  :  LF LV Lc L L L L  L  ]F ]V ]f ]s ]RX ] ] ]  ]  nF nV nf nv nX[ nci n n n  nK=vs{!3 K= K= K= K= K= K= K=r$   