
    1;jiu+                         d dl mZmZmZmZ d dlmZ d dlmZm	Z	 d dl
Z
d dlZddlmZ dedefd	Z G d
 d          Z G d de          ZdS )    )AnyListOptionalDict)EinopsError)ParsedExpression	_ellipsisN   )_productaxesreport_messagec                 p    t          |           dk    r"t          |                    |                     d S )Nr   )lenr   format)r   r   s     O/root/voice-cloning/.venv/lib/python3.11/site-packages/einops/layers/_einmix.py_report_axesr   
   s4    
4yy1}}.//55666 }    c            	            e Zd Zddededee         def fdZdededee         defdZdee         d	ee	         d
ee         dee	         fdZ
d Zd Z xZS )_EinmixMixinNpatternweight_shape
bias_shapeaxes_lengthsc                     t                                                       || _        || _        || _        || _        |                     ||||           dS )a	  
        EinMix - Einstein summation with automated tensor management and axis packing/unpacking.

        EinMix is a combination of einops and MLP, see tutorial:
        https://github.com/arogozhnikov/einops/blob/main/docs/3-einmix-layer.ipynb

        Imagine taking einsum with two arguments, one of each input, and one - tensor with weights
        >>> einsum('time batch channel_in, channel_in channel_out -> time batch channel_out', input, weight)

        This layer manages weights for you, syntax highlights a special role of weight matrix
        >>> EinMix('time batch channel_in -> time batch channel_out', weight_shape='channel_in channel_out')
        But otherwise it is the same einsum under the hood. Plus einops-rearrange.

        Simple linear layer with a bias term (you have one like that in your framework)
        >>> EinMix('t b cin -> t b cout', weight_shape='cin cout', bias_shape='cout', cin=10, cout=20)
        There is no restriction to mix the last axis. Let's mix along height
        >>> EinMix('h w c-> hout w c', weight_shape='h hout', bias_shape='hout', h=32, hout=32)
        Example of channel-wise multiplication (like one used in normalizations)
        >>> EinMix('t b c -> t b c', weight_shape='c', c=128)
        Multi-head linear layer (each head is own linear layer):
        >>> EinMix('t b (head cin) -> t b (head cout)', weight_shape='head cin cout', ...)

        ... and yes, you need to specify all dimensions of weight shape/bias shape in parameters.

        Use cases:
        - when channel dimension is not last, use EinMix, not transposition
        - patch/segment embeddings
        - when need only within-group connections to reduce number of weights and computations
        - next-gen MLPs (follow tutorial link above to learn more!)
        - in general, any time you want to combine linear layer and einops.rearrange

        Uniform He initialization is applied to weight tensor.
        This accounts for the number of elements mixed and produced.

        Parameters
        :param pattern: transformation pattern, left side - dimensions of input, right side - dimensions of output
        :param weight_shape: axes of weight. A tensor of this shape is created, stored, and optimized in a layer
               If bias_shape is not specified, bias is not created.
        :param bias_shape: axes of bias added to output. Weights of this shape are created and stored. If `None` (the default), no bias is added.
        :param axes_lengths: dimensions of weight tensor
        )r   r   r   r   N)super__init__r   r   r   r   initialize_einmix)selfr   r   r   r   	__class__s        r   r   z_EinmixMixin.__init__   sk    T 	($(,:\h 	 	
 	
 	
 	
 	
r   c                 
   |                     d          \  }}t          |          }t          |          t          |          }t          t                              j        h |j        |j                  d           |j        rt          d          |j        sj        r9|j        rj        st          d|           |j        rt          d|           t          d ||fD                       rt          d          d|v sd	|v rt          d
|           d }	d }
d }t          d |j
        D                       rYg |j
        D ]}|z  d D             d                              }| d| }	fd                                D             }
t          d j
        D                       sj        r9g j
        D ]}|z  d D             d                              }| d| }|                     |	|
|i            |j        D ](}|vr"t          d                    |                    )t          t                              t                    h |j        |j                  d           t          t                              |j        h |j        j                  d           t          |j                  dk    rt!          j        d           fd|j
        D             }t%          fd|j
        D                       }|+t'          |t(                    st          d          t          |          }t          t                              |j        j                  d           t          t                              |j        t                              d           g }d}j
        D ]}}|t*          k    r|rt          d          |D ][}|t*          k    r|rt          d          ||j        v r|                    |                    d}F|                    d            \~nd }d!|z  d"z  }d |z  d"z  }|                     ||||           h |j        j        |j        }t*          |v r|                    t*                     t3          t5          |                    }d# t7          t8          j        |          D             d$t*          <   d%t          ffd&}d'                     ||           ||           |                    | _        d S )(Nz->z7Unrecognized identifiers on the right side of EinMix {}zKEllipsis is not supported in weight, as its shape should be fully specifiedz,Ellipsis in EinMix should be on both sides, z3Ellipsis on left side can't be in parenthesis, got c              3   $   K   | ]}|j         V  d S N)has_non_unitary_anonymous_axes).0xs     r   	<genexpr>z1_EinmixMixin.initialize_einmix.<locals>.<genexpr>S   s%      OOAq/OOOOOOr   z2Anonymous axes (numbers) are not allowed in EinMix()z,Parenthesis is not allowed in weight shape: c              3   <   K   | ]}t          |          d k    V  dS    Nr   r$   groups     r   r&   z1_EinmixMixin.initialize_einmix.<locals>.<genexpr>[   s,      ==5s5zzQ======r   c                 ,    g | ]}|t           k    r|nd S ...r	   r$   names     r   
<listcomp>z2_EinmixMixin.initialize_einmix.<locals>.<listcomp>_   &    LLLdTY..TTELLLr    z-> c                 $    i | ]\  }}|v 	||S  r9   )r$   r4   lengthnamess      r   
<dictcomp>z2_EinmixMixin.initialize_einmix.<locals>.<dictcomp>b   s+    "j"j"jLD&\`di\i\i4\i\i\ir   c              3   <   K   | ]}t          |          d k    V  dS r*   r,   r-   s     r   r&   z1_EinmixMixin.initialize_einmix.<locals>.<genexpr>d   s,      >>5s5zzQ>>>>>>r   c                 ,    g | ]}|t           k    r|nd S r0   r2   r3   s     r   r5   z2_EinmixMixin.initialize_einmix.<locals>.<listcomp>h   r6   r   z ->z*Dimension {} of weight should be specifiedzAxes {} are not used in patternzWeight axes {} are redundantr   zCEinMix: weight has no dimensions (means multiplication by a number)c                 $    g | ]\  }|         S r9   r9   )r$   axisr   s     r   r5   z2_EinmixMixin.initialize_einmix.<locals>.<listcomp>{   s     NNNd+NNNr   c                 6    g | ]\  }|j         v|         S r9   )identifiers)r$   r@   r   rights     r   r5   z2_EinmixMixin.initialize_einmix.<locals>.<listcomp>}   s/    rrr7DTX`e`qTqTqL.TqTqTqr   zAbias shape should be string specifying which axes bias depends onz"Bias axes {} not present in outputz#Sizes not provided for bias axes {}Fz:all bias dimensions should go after ellipsis in the outputTr+      g      ?c                     i | ]\  }}||	S r9   r9   )r$   letterks      r   r<   z2_EinmixMixin.initialize_einmix.<locals>.<dictcomp>   s    fff1ffffr   r1   r   c                     g }| j         D ][}t          |t                    r"|                    fd|D                        9|t          k    sJ |                    d           \d                    |          S )Nc                      g | ]
}|         S r9   r9   )r$   r@   mapping2letterss     r   r5   zO_EinmixMixin.initialize_einmix.<locals>.write_flat_remapped.<locals>.<listcomp>   s    "S"S"ST?4#8"S"S"Sr   r1    )composition
isinstancelistextendr	   appendjoin)r   resultcomposed_axisrJ   s      r   write_flat_remappedz;_EinmixMixin.initialize_einmix.<locals>.write_flat_remapped   s    F!%!1 ) )mT22 )MM"S"S"S"S]"S"S"STTTT(I5555MM%((((776??"r   z	{},{}->{})splitr   r   set
differencerB   has_ellipsisr   has_ellipsis_parenthesizedanyrL   rQ   items_create_rearrange_layersr   r   warningswarnr   rM   strr	   rP   _create_parametersremoverN   sortedzipstringascii_lowercaseeinsum_pattern)r   r   r   r   r   left_patternright_patternleftweightpre_reshape_patternpre_reshape_lengthspost_reshape_patternr.   rL   r@   _weight_shape_fan_inbias_bias_shapeused_non_trivial_sizer   weight_bound
bias_boundmapped_identifiersrT   rJ   r;   rC   s       `                    @@@r   r   z_EinmixMixin.initialize_einmixC   s~   &-mmD&9&9#m-- //!,//NN5,.V0@.V6CU.VWWE	
 	
 	
  	mklll 	c 2 	c% \%*< \!"ZQX"Z"Z[[[. c!"aX_"a"abbbOO$v9NOOOOO 	TRSSS,#"5"5[\[[\\\""#==D,<===== 	k!E)  LLeLLLE((5//K%1"C"Ck"C"C"j"j"j"jLDVDVDXDX"j"j"j>>E,=>>>>> 	F%Bb 	FE*  LLeLLLE((5//K&1#E#Em#E#E %%&9;NPdfhiii& 	] 	]D<''!"N"U"UVZ"["[\\\ (NN3|,,.V0@.V6CU.VWW-	
 	
 	
 	NN6-/V1A/VEDU/VWWYw	
 	
 	
 v!""a''M_```NNNN6;MNNNrrrrrf>Prrrss!j#.. g!"efff#J//Dt/1BCC4   t/\1B1BCC5  
 K$)!) 2 29$$, h)*fgggh !% 2 29,,4 p&12n&o&o op!T%555'..|D/ABBB4811'..q111122  KG+'kc)
|[*UUU Zt/Y%2CYfFXY***%%i000!&);"<"<==ffc&:PRd6e6efff%*	"	#&6 	# 	# 	# 	# 	# 	# $/#5#5%%''&&$
 $
r   rk   rl   rm   post_reshape_lengthsc                      t          d          )N.Should be defined in framework implementationsNotImplementedErrorr   rk   rl   rm   rv   s        r   r\   z%_EinmixMixin._create_rearrange_layers   s     ""RSSSr   c                      t          d          )zShape and implementationsrx   ry   r   r   rs   r   rt   s        r   r`   z_EinmixMixin._create_parameters   s    !"RSSSr   c                     t          | j                  }|d| j         dz  }| j        |d| j         dz  }| j                                        D ]\  }}|d                    ||          z  }d                    | j        j        |          S )Nz, ''z, {}={}z{}({}))	reprr   r   r   r   r[   r   r   __name__)r   paramsr@   r:   s       r   __repr__z_EinmixMixin.__repr__   s    dl##,),,,,?&.DO....F -3355 	5 	5LD&i&&tV444FFt~6???r   r"   )r   
__module____qualname__r_   r   r   r   dictr   r   r\   r`   r   __classcell__)r   s   @r   r   r      s       1
 1
 1
3 1
HSM 1
jm 1
 1
 1
 1
 1
 1
fx
 x
C x
XVY] x
jn x
 x
 x
 x
tT%c]T &d^T 'sm	T
 'tnT T T TT T T@ @ @ @ @ @ @r   r   c            	       `    e Zd ZdZdee         dee         dee         dee         fdZd ZdS )	_EinmixDebuggerzUsed only to test mixinrk   rl   rm   rv   c                 >    || _         || _        || _        || _        d S r"   )rk   rl   rm   rv   r{   s        r   r\   z(_EinmixDebugger._create_rearrange_layers   s*     $7 #6 $8!$8!!!r   c                 "    || _         || _        d S r"   )saved_weight_shapesaved_bias_shaper}   s        r   r`   z"_EinmixDebugger._create_parameters   s    ". *r   N)	r   r   r   __doc__r   r_   r   r\   r`   r9   r   r   r   r      ss        !!
9%c]
9 &d^
9 'sm	
9
 'tn
9 
9 
9 
9+ + + + +r   r   )typingr   r   r   r   einopsr   einops.parsingr   r	   r]   rd   r   rV   r_   r   r   r   r9   r   r   <module>r      s   , , , , , , , , , , , ,       6 6 6 6 6 6 6 6        7s 7C 7 7 7 7
B@ B@ B@ B@ B@ B@ B@ B@J+ + + + +l + + + + +r   