Ë
    ÛÍ:jC+  ã                   óŽ   — d dl Z d dlZd dlmZmZmZmZ d dlmZ d dl	m
Z
 d dlmZmZ dedefd„Z G d	„ d
«      Z G d„ de«      Zy)é    N)ÚAnyÚDictÚListÚOptional)ÚEinopsError)Ú_product)ÚParsedExpressionÚ	_ellipsisÚaxesÚreport_messagec                 óT   — t        | «      dkD  rt        |j                  | «      «      ‚y )Nr   )Úlenr   Úformat)r   r   s     új/home/mcse/projects/srt_converter/srt-converter-venv/lib/python3.12/site-packages/einops/layers/_einmix.pyÚ_report_axesr   
   s(   € Ü
ˆ4ƒy�1‚}Ü˜.×/Ñ/°Ó5Ó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 )Ú_EinmixMixinÚpatternÚweight_shapeÚ
bias_shapeÚaxes_lengthsc                 ó„   •— t         ‰| �  «        || _        || _        || _        || _        | j                  ||||¬«       y)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__   sL   ø€ ôT 	‰ÑÔØˆŒØ(ˆÔØ$ˆŒØ(ˆÔØ×ÑØ¨,À:Ð\hð 	õ 	
r   c                 óÚ
  ‡— |j                  d«      \  }}t        |«      }t        |«      }t        |«      }	t        t        j	                  |j
                  h |j
                  £|	j
                  £«      d«       |	j                  rt        d«      ‚|j                  s|j                  r@|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 «       «      rrg }|j                  D ]  }||z  }Œ	 |D �cg c]  }|t        k7  r|nd‘Œ }}dj                  |«      }|› d|› �}
|j                  «       D ��ci c]  \  }}||v sŒ||“Œ }}}t        d„ |j                  D «       «      s|j                  rJg }|j                  D ]  }||z  }Œ	 |D �cg c]  }|t        k7  r|nd‘Œ }}dj                  |«      }|› d|› �}| j                  |
||i «       |	j
                  D ]  }||vsŒt        d|› d�«      ‚ t        t        j	                  t        |«      h |j
                  £|	j
                  £«      d«       t        t        j	                  |	j
                  h |j
                  £|j
                  £«      d«       t        |	j
                  «      dk(  rt!        j"                  dd¬«       |	j                  D �cg c]	  \  }||   ‘Œ }}t%        |	j                  D �cg c]  \  }||j
                  vsŒ||   ‘Œ c}«      }|��t'        |t(        «      st        d«      ‚t        |«      }t        t        j	                  |j
                  |j
                  «      d«       t        t        j	                  |j
                  t        |«      «      d«       g }d}|j                  D ]m  }|t        k(  r|sŒt        d«      ‚|D ]O  }|t        k(  r|sŒt        d«      ‚||j
                  v r|j+                  ||   «       d}Œ?|j+                  d«       ŒQ Œo nd }d |z  d!z  }d|z  d!z  }| j-                  ||||«       h |j
                  £|j
                  £|	j
                  £}t        |v r|j/                  t        «       t1        |«      }t3        t4        j6                  |«      D ��ci c]  \  }}||“Œ
 c}}Šd‰t        <   d"t        fˆfd#„} ||«      › d$ ||	«      › d ||«      › �| _        y c c}w c c}}w c c}w c c}w c c}w c c}}w )%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   ó4   K  — | ]  }|j                   –— Œ y ­w©N)Úhas_non_unitary_anonymous_axes)Ú.0Úxs     r   ú	<genexpr>z1_EinmixMixin.initialize_einmix.<locals>.<genexpr>S   s   è ø€ ÒO°Aˆq×/Õ/ÑOùs   ‚z2Anonymous axes (numbers) are not allowed in EinMixú(ú)z,Parenthesis is not allowed in weight shape: c              3   ó8   K  — | ]  }t        |«      d k7  –— Œ y­w©é   N©r   ©r#   Úgroups     r   r%   z1_EinmixMixin.initialize_einmix.<locals>.<genexpr>[   s   è ø€ Ò= 5Œs�5‹z˜Q�Ñ=ùó   ‚ú...ú z-> c              3   ó8   K  — | ]  }t        |«      d k7  –— Œ y­wr)   r+   r,   s     r   r%   z1_EinmixMixin.initialize_einmix.<locals>.<genexpr>d   s   è ø€ Ò> 5Œs�5‹z˜Q�Ñ>ùr.   z ->z
Dimension z 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)é   )Ú
stacklevelzAbias 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      à?r   c                 óô   •— g }| j                   D ]Q  }t        |t        «      r#|j                  |D �cg c]  }‰|   ‘Œ	 c}«       Œ6|t        k(  sJ ‚|j                  d«       ŒS dj                  |«      S c c}w )Nr/   Ú )ÚcompositionÚ
isinstanceÚlistÚextendr
   ÚappendÚjoin)r   ÚresultÚcomposed_axisÚaxisÚmapping2letterss       €r   Úwrite_flat_remappedz;_EinmixMixin.initialize_einmix.<locals>.write_flat_remapped­   ss   ø€ ØˆFØ!%×!1Ñ!1ò )�Ü˜m¬TÔ2Ø—M‘MÀ]Ö"S¸T ?°4Ó#8Ò"SÕTà(¬IÒ5Ð5Ð5Ø—M‘M %Õ(ð)ð —7‘7˜6“?Ð"ùò	 #Ts   ²A5
ú,)Úsplitr	   r   ÚsetÚ
differenceÚidentifiersÚhas_ellipsisr   Úhas_ellipsis_parenthesizedÚanyr7   r
   r<   ÚitemsÚ_create_rearrange_layersr   ÚwarningsÚwarnr   r8   Ústrr;   Ú_create_parametersÚremoveÚsortedÚzipÚstringÚascii_lowercaseÚeinsum_pattern) r   r   r   r   r   Úleft_patternÚright_patternÚleftÚrightÚweightÚpre_reshape_patternÚpre_reshape_lengthsÚpost_reshape_patternÚnamesr-   Únamer7   Úlengthr?   Ú_weight_shapeÚ_fan_inÚbiasÚ_bias_shapeÚused_non_trivial_sizer   Úweight_boundÚ
bias_boundÚmapped_identifiersÚletterÚkrA   r@   s                                   @r   r   z_EinmixMixin.initialize_einmixC   s˜  ø€ Ø&-§m¡m°DÓ&9Ñ#ˆ�mÜ Ó-ˆÜ  Ó/ˆÜ! ,Ó/ˆÜÜ�N‰N˜5×,Ñ,Ð.V°×0@Ñ0@Ð.VÀ6×CUÑCUÐ.VÓWØEô	
ð ×ÒÜÐkÓlÐlØ×Ò × 2Ò 2Ø×%Ò%¨%×*<Ò*<Ü!Ð$PÐQXÐPYÐ"ZÓ[Ð[Ø×.Ò.Ü!Ð$WÐX_ÐW`Ð"aÓbÐbÜÑO¸$ÀÀvÐ9NÔOÔOÜÐRÓSÐSØ�,Ñ #¨Ñ"5ÜÐ LÈ\ÈNÐ[Ó\Ð\à"ÐØ"ÐØ#ÐÜÑ=¨D×,<Ñ,<Ô=Ô=Ø!ˆEØ×)Ñ)ò �Ø˜‘‘ðàFKÖL¸d˜T¤YÒ.‘T°EÑ9ÐLˆEÐLØŸ(™( 5›/ˆKØ%1 N°#°k°]Ð"CÐØDP×DVÑDVÓDX×"j±L°D¸&Ð\`ÐdiÒ\i 4¨¡<Ð"jÐÑ"jäÑ>¨E×,=Ñ,=Ô>Ô>À%×BbÒBbØˆEØ×*Ñ*ò �Ø˜‘‘ðàFKÖL¸d˜T¤YÒ.‘T°EÑ9ÐLˆEÐLØŸ(™( 5›/ˆKØ&1 ]°#°m°_Ð#EÐ à×%Ñ%Ð&9Ð;NÐPdÐfhÔià×&Ñ&ò 	UˆDØ˜<Ò'Ü! J¨t¨fÐ4RÐ"SÓTÐTð	Uô 	Ü�N‰Nœ3˜|Ó,Ð.V°×0@Ñ0@Ð.VÀ6×CUÑCUÐ.VÓWØ-ô	
ô 	Ü�N‰N˜6×-Ñ-Ð/V°×1AÑ1AÐ/VÀE×DUÑDUÐ/VÓWÐYwô	
ô ˆv×!Ñ!Ó" aÒ'Ü�M‰MÐ_ÐlmÕnà;A×;MÑ;MÖN±°˜ dÓ+ÐNˆÐNä¸f×>PÑ>PÖr±7°DÐTXÐ`e×`qÑ`qÒTq˜L¨Ó.ÒrÓsˆØÑ!ä˜j¬#Ô.Ü!Ð"eÓfÐfÜ# JÓ/ˆDÜÜ—‘˜t×/Ñ/°×1BÑ1BÓCØ4ôô Ü—‘˜t×/Ñ/´°\Ó1BÓCØ5ôð
 ˆKØ$)Ð!Ø×)Ñ)ò 2�Øœ9Ò$Ú,Ü)Ð*fÓgÐgð !%ò 2˜Ø¤9Ò,Ú4Ü&1Ð2nÓ&oÐ oØ! T×%5Ñ%5Ñ5Ø'×.Ñ.¨|¸DÑ/AÔBØ48Ñ1à'×.Ñ.¨qÕ1ñ2ñ2ð  ˆKà˜G™¨Ñ+ˆØ˜'‘k cÑ)ˆ
Ø×Ñ ¨|¸[È*ÔUð Z˜t×/Ñ/ÐY°%×2CÑ2CÐYÀf×FXÑFXÐYÐÜÐ*Ñ*Ø×%Ñ%¤iÔ0Ü#Ð$6Ó7ÐÜ69¼&×:PÑ:PÐRdÓ6e×f©¨°˜1˜f™9ÓfˆØ%*ˆœ	Ñ"ð	#Ô&6õ 	#ñ # 4Ó(Ð)¨Ñ+>¸vÓ+FÐ*GÀrÑJ]Ð^cÓJdÐIeÐfð 	Õùòq Mùó #kùò Mùò& OùârùóZ gs0   ÅUÆUÆ*UÇ6UÌUÌ?U"ÍU"ÔU'r[   r\   r]   Úpost_reshape_lengthsc                 ó   — t        d«      ‚)Nú.Should be defined in framework implementations©ÚNotImplementedError©r   r[   r\   r]   rk   s        r   rK   z%_EinmixMixin._create_rearrange_layers»   s   € ô "Ð"RÓSÐSr   c                 ó   — t        d«      ‚)zShape and implementationsrm   rn   ©r   r   rf   r   rg   s        r   rO   z_EinmixMixin._create_parametersÄ   s   € ä!Ð"RÓSÐSr   c                 ó"  — t        | j                  «      }|d| j                  › d�z  }| j                  �|d| j                  › d�z  }| j                  j                  «       D ]  \  }}|d|› d|› �z  }Œ | j                  j                  › d|› d�S )Nz, 'ú'z, ú=r&   r'   )Úreprr   r   r   r   rJ   r   Ú__name__)r   Úparamsr?   r`   s       r   Ú__repr__z_EinmixMixin.__repr__È   s£   € Ü�d—l‘lÓ#ˆØ�C˜×)Ñ)Ð*¨!Ð,Ñ,ˆØ�?‰?Ð&Ø˜˜DŸO™OÐ,¨AÐ.Ñ.ˆFØ ×-Ñ-×3Ñ3Ó5ò 	+‰LˆD�&Ø˜˜4˜&  & Ð*Ñ*‰Fð	+à—.‘.×)Ñ)Ð*¨!¨F¨8°1Ð5Ð5r   r!   )rw   Ú
__module__Ú__qualname__rN   r   r   r   Údictr   r   rK   rO   ry   Ú__classcell__)r   s   @r   r   r      s¢   ø„ ñ1
 ð 1
°3ð 1
ÀHÈSÁMð 1
Ðjmõ 1
ðfv
¨ð v
¸Cð v
ÈXÐVYÉ]ð v
Ðjnó v
ðpTà% c™]ðTð & d™^ðTð ' s™mð	Tð
 ' t™nóTòTö6r   r   c            	       óF   — e Zd ZdZdee   dee   dee   dee   fd„Zd„ Zy)	Ú_EinmixDebuggerzUsed only to test mixinr[   r\   r]   rk   c                 ó<   — || _         || _        || _        || _        y r!   )r[   r\   r]   rk   rp   s        r   rK   z(_EinmixDebugger._create_rearrange_layersÕ   s$   € ð $7ˆÔ Ø#6ˆÔ Ø$8ˆÔ!Ø$8ˆÕ!r   c                 ó    — || _         || _        y r!   )Úsaved_weight_shapeÚsaved_bias_shaperr   s        r   rO   z"_EinmixDebugger._create_parametersá   s   € Ø".ˆÔØ *ˆÕr   N)	rw   rz   r{   Ú__doc__r   rN   r   rK   rO   © r   r   r   r   Ò   sE   „ Ù!ð
9à% c™]ð
9ð & d™^ð
9ð ' s™mð	
9ð
 ' t™nó
9ó+r   r   )rS   rL   Útypingr   r   r   r   Úeinopsr   Úeinops.einopsr   Úeinops.parsingr	   r
   rD   rN   r   r   r   r…   r   r   ú<module>rŠ      sF   ðÛ Û ß ,Ó ,å Ý "ß 6ð7�sð 7¨Có 7÷
@6ñ @6ôF+�lõ +r   