§
    �Å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dS )é    N)ÚAnyÚDictÚListÚOptional)ÚEinopsError)Ú_product)ÚParsedExpressionÚ	_ellipsisÚaxesÚreport_messagec                 óp   — t          | ¦  «        dk    r"t          |                     | ¦  «        ¦  «        ‚d S )Nr   )Úlenr   Úformat)r   r   s     úFC:\Projects\Historical\venv\Lib\site-packages\einops/layers/_einmix.pyÚ_report_axesr   
   s4   € Ý
ˆ4�y„y�1‚}€}Ý˜.×/Ò/°Ñ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                 óL
  ‡‡‡‡— |                      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|› d�¦  «        ‚Œt          t                               t          ‰¦  «        h |j        £|j        £¦  «        d¦  «         t          t                               |j        h |j        £‰j        £¦  «        d¦  «         t          |j        ¦  «        dk    rt          j        d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(          ¦  «         t1          |¦  «        }d&„ t3          t4          j        |¦  «        D ¦   «         Šd'‰t(          <   d(t          fˆfd)„} ||¦  «        › 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ÐO°AˆqÔ/Ð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,   è è € Ð=Ð= 5�s�5‰zŒz˜QŠÐ=Ð=Ð=Ð=Ð=Ð=r   c                 ó,   — g | ]}|t           k    r|nd ‘ŒS ©ú...©r
   ©r#   Únames     r   ú
<listcomp>z2_EinmixMixin.initialize_einmix.<locals>.<listcomp>_   ó&   € ÐLÐLÐL¸d˜T¥YÒ.Ð.�T�T°EÐLÐLÐLr   ú z-> c                 ó$   •— i | ]\  }}|‰v ¯	||“ŒS © r8   )r#   r3   ÚlengthÚnamess      €r   ú
<dictcomp>z2_EinmixMixin.initialize_einmix.<locals>.<dictcomp>b   s+   ø€ Ð"jÐ"jÐ"j±L°D¸&Ð\`ÐdiÐ\iÐ\i 4¨Ð\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,   è è € Ð>Ð> 5�s�5‰zŒz˜QŠÐ>Ð>Ð>Ð>Ð>Ð>r   c                 ó,   — g | ]}|t           k    r|nd ‘ŒS r/   r1   r2   s     r   r4   z2_EinmixMixin.initialize_einmix.<locals>.<listcomp>h   r5   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)é   )Ú
stacklevelc                 ó$   •— g | ]\  }‰|         ‘ŒS r8   r8   )r#   Úaxisr   s     €r   r4   z2_EinmixMixin.initialize_einmix.<locals>.<listcomp>{   s    ø€ ÐNÐNÐN±°˜ dÔ+ÐNÐNÐNr   c                 ó6   •— g | ]\  }|‰j         v¯‰|         ‘ŒS r8   )Úidentifiers)r#   rA   r   Úrights     €€r   r4   z2_EinmixMixin.initialize_einmix.<locals>.<listcomp>}   s/   ø€ ÐrÐrÐr±7°DÐTXÐ`eÔ`qÐTqÐTq˜L¨Ô.ÐTqÐTqÐTqr   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 r8   r8   )r#   ÚletterÚks      r   r;   z2_EinmixMixin.initialize_einmix.<locals>.<dictcomp>ª   s   € ÐfÐfÐf©¨°˜1˜fÐfÐfÐfr   r0   r   c                 óø   •— g }| j         D ][}t          |t          ¦  «        r"|                     ˆfd„|D ¦   «         ¦  «         Œ9|t          k    sJ ‚|                     d¦  «         Œ\d                     |¦  «        S )Nc                 ó    •— g | ]
}‰|         ‘ŒS r8   r8   )r#   rA   Úmapping2letterss     €r   r4   zO_EinmixMixin.initialize_einmix.<locals>.write_flat_remapped.<locals>.<listcomp>±   s   ø€ Ð"SÐ"SÐ"S¸T ?°4Ô#8Ð"SÐ"SÐ"Sr   r0   Ú )ÚcompositionÚ
isinstanceÚlistÚextendr
   ÚappendÚjoin)r   ÚresultÚcomposed_axisrK   s      €r   Úwrite_flat_remappedz;_EinmixMixin.initialize_einmix.<locals>.write_flat_remapped­   sŒ   ø€ ØˆFØ!%Ô!1ð )ð )�Ý˜m­TÑ2Ô2ð )Ø—M’MÐ"SÐ"SÐ"SÐ"SÀ]Ð"SÑ"SÔ"SÑTÔTÐTÐTà(­IÒ5Ð5Ð5Ð5Ø—M’M %Ñ(Ô(Ð(Ð(Ø—7’7˜6‘?”?Ð"r   ú,)Úsplitr	   r   ÚsetÚ
differencerC   Úhas_ellipsisr   Úhas_ellipsis_parenthesizedÚanyrM   rR   ÚitemsÚ_create_rearrange_layersr   ÚwarningsÚwarnr   rN   Ústrr
   rQ   Ú_create_parametersÚremoveÚ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-   rM   rA   Ú_weight_shapeÚ_fan_inÚbiasÚ_bias_shapeÚused_non_trivial_sizer   Úweight_boundÚ
bias_boundÚmapped_identifiersrU   rK   r:   rD   s       `                    @@@r   r   z_EinmixMixin.initialize_einmixC   s{  øøøø€ Ø&-§m¢m°DÑ&9Ô&9Ñ#ˆ�mÝ Ñ-Ô-ˆÝ  Ñ/Ô/ˆÝ! ,Ñ/Ô/ˆÝÝ�NŠN˜5Ô,Ð.V°Ô0@Ð.VÀ6ÔCUÐ.VÑWÔWØEñ	
ô 	
ð 	
ð Ôð 	mÝÐkÑlÔlÐlØÔð 	c Ô 2ð 	cØÔ%ð \¨%Ô*<ð \Ý!Ð"ZÐQXÐ"ZÐ"ZÑ[Ô[Ð[ØÔ.ð cÝ!Ð"aÐX_Ð"aÐ"aÑbÔbÐbÝÐOÐO¸$ÀÀvÐ9NÐOÑOÔOÑOÔOð 	TÝÐRÑSÔSÐSØ�,ÐÐ #¨Ð"5Ð"5ÝÐ[È\Ð[Ð[Ñ\Ô\Ð\à"ÐØ"ÐØ#ÐÝÐ=Ð=¨DÔ,<Ð=Ñ=Ô=Ñ=Ô=ð 	kØ!ˆEØÔ)ð ð �Ø˜‘��ØLÐLÀeÐLÑLÔLˆEØŸ(š( 5™/œ/ˆKØ%1Ð"CÐ"C°kÐ"CÐ"CÐØ"jÐ"jÐ"jÐ"jÀL×DVÒDVÑDXÔDXÐ"jÑ"jÔ"jÐåÐ>Ð>¨EÔ,=Ð>Ñ>Ô>Ñ>Ô>ð 	FÀ%ÔBbð 	FØˆEØÔ*ð ð �Ø˜‘��ØLÐLÀeÐLÑLÔLˆEØŸ(š( 5™/œ/ˆKØ&1Ð#EÐ#E°mÐ#EÐ#EÐ à×%Ò%Ð&9Ð;NÐPdÐfhÑiÔiÐiàÔ&ð 	Uð 	UˆDØ˜<Ð'Ð'Ý!Ð"S¨tÐ"SÐ"SÐ"SÑTÔTÐTð (åÝ�NŠN�3˜|Ñ,Ô,Ð.V°Ô0@Ð.VÀ6ÔCUÐ.VÑWÔWØ-ñ	
ô 	
ð 	
õ 	Ý�NŠN˜6Ô-Ð/V°Ô1AÐ/VÀEÔDUÐ/VÑWÔWÐYwñ	
ô 	
ð 	
õ ˆvÔ!Ñ"Ô" aÒ'Ð'ÝŒMÐ_ÐlmÐnÑnÔnÐnàNÐNÐNÐN¸6Ô;MÐNÑNÔNˆåÐrÐrÐrÐrÐr¸fÔ>PÐrÑrÔrÑsÔsˆØÑ!å˜j­#Ñ.Ô.ð gÝ!Ð"eÑfÔfÐfÝ# JÑ/Ô/ˆDÝÝ—’˜tÔ/°Ô1BÑCÔCØ4ñô ð õ Ý—’˜tÔ/µ°\Ñ1BÔ1BÑCÔCØ5ñô ð ð
 ˆKØ$)Ð!ØÔ)ð 2ð 2�Ø�9Ò$Ð$Ø,ð hÝ)Ð*fÑgÔgÐgðhð !%ð 2ð 2˜Ø¥9Ò,Ð,Ø4ð pÝ&1Ð2nÑ&oÔ&oÐ oðpà! TÔ%5Ð5Ð5Ø'×.Ò.¨|¸DÔ/AÑBÔBÐBØ48Ð1Ð1à'×.Ò.¨qÑ1Ô1Ð1Ð1ð2ð2ð  ˆKà˜G™¨Ñ+ˆØ˜'‘k cÑ)ˆ
Ø×Ò ¨|¸[È*ÑUÔUÐUð Z˜tÔ/ÐY°%Ô2CÐYÀfÔFXÐYÐÝÐ*Ð*Ð*Ø×%Ò%¥iÑ0Ô0Ð0Ý#Ð$6Ñ7Ô7ÐØfÐfµc½&Ô:PÐRdÑ6eÔ6eÐfÑfÔfˆØ%*ˆ�	Ñ"ð	#Õ&6ð 	#ð 	#ð 	#ð 	#ð 	#ð 	#ð #Ð" 4Ñ(Ô(ÐfÐfÐ+>Ð+>¸vÑ+FÔ+FÐfÐfÐJ]ÐJ]Ð^cÑJdÔJdÐfÐfð 	ÔÐÐr   rm   rn   ro   Úpost_reshape_lengthsc                 ó    — t          d¦  «        ‚)Nú.Should be defined in framework implementations©ÚNotImplementedError©r   rm   rn   ro   rx   s        r   r^   z%_EinmixMixin._create_rearrange_layers»   s   € õ "Ð"RÑSÔSÐSr   c                 ó    — t          d¦  «        ‚)zShape and implementationsrz   r{   ©r   r   ru   r   rv   s        r   rb   z_EinmixMixin._create_parametersÄ   s   € å!Ð"RÑSÔSÐSr   c                 óè   — t          | j        ¦  «        }|d| j        › d�z  }| j        �|d| j        › d�z  }| j                             ¦   «         D ]\  }}|d|› d|› �z  }Œ| j        j        › d|› d�S )Nz, 'ú'z, ú=r&   r'   )Úreprr   r   r   r   r]   r   Ú__name__)r   ÚparamsrA   r9   s       r   Ú__repr__z_EinmixMixin.__repr__È   s¥   € Ý�d”lÑ#Ô#ˆØÐ,˜Ô)Ð,Ð,Ð,Ñ,ˆØŒ?Ð&ØÐ.˜DœOÐ.Ð.Ð.Ñ.ˆFØ Ô-×3Ò3Ñ5Ô5ð 	+ð 	+‰LˆD�&ØÐ*˜4Ð*Ð* &Ð*Ð*Ñ*ˆFˆFØ”.Ô)Ð5Ð5¨FÐ5Ð5Ð5Ð5r   r!   )r„   Ú
__module__Ú__qualname__ra   r   r   r   Údictr   r   r^   rb   r†   Ú__classcell__)r   s   @r   r   r      s  ø€ € € € € ð1
ð 1
 ð 1
°3ð 1
ÀHÈSÄMð 1
Ðjmð 1
ð 1
ð 1
ð 1
ð 1
ð 1
ðfv
¨ð v
¸Cð v
ÈXÐVYÌ]ð v
Ðjnð v
ð v
ð v
ð v
ðpTà% cœ]ðTð & dœ^ðTð ' sœmð	Tð
 ' tœnðTð Tð Tð TðTð Tð Tð6ð 6ð 6ð 6ð 6ð 6ð 6r   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 mixinrm   rn   ro   rx   c                 ó>   — || _         || _        || _        || _        d S r!   )rm   rn   ro   rx   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   rb   z"_EinmixDebugger._create_parametersá   s   € Ø".ˆÔØ *ˆÔÐÐr   N)	r„   r‡   rˆ   Ú__doc__r   ra   r   r^   rb   r8   r   r   rŒ   rŒ   Ò   ss   € € € € € Ø!Ð!ð
9à% cœ]ð
9ð & dœ^ð
9ð ' sœmð	
9ð
 ' tœnð
9ð 
9ð 
9ð 
9ð+ð +ð +ð +ð +r   rŒ   )rf   r_   Útypingr   r   r   r   Úeinopsr   Úeinops.einopsr   Úeinops.parsingr	   r
   rX   ra   r   r   rŒ   r8   r   r   ú<module>r–      sþ   ðØ €€€Ø €€€Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,à Ð Ð Ð Ð Ð Ø "Ð "Ð "Ð "Ð "Ð "Ø 6Ð 6Ð 6Ð 6Ð 6Ð 6Ð 6Ð 6ð7�sð 7¨Cð 7ð 7ð 7ð 7ð
@6ð @6ð @6ð @6ð @6ñ @6ô @6ð @6ðF+ð +ð +ð +ð +�lñ +ô +ð +ð +ð +r   