
    oi~!                        S SK Jr  S SKrS SKrS SKJrJrJr  S SKrS SK	J
r
  S SKJrJr  SSKJrJr   " S S\5      r " S	 S
\
R$                  \5      rg)    )annotationsN)AnyLiteralOptional)BaseTunerLayercheck_adapters_to_merge   )BlockCircularConvolutionget_circulant_fastc                  l    \ rS rSrSrSrS
S jrSS jrSSS jjr\	R                  " 5       S 5       rSrg	)C3ALayer   )
c3a_kernel)
block_sizec                N   Xl         0 U l        [        R                  " 0 5      U l        SU l        / U l        X l        U R                  5       n[        U[        R                  5      (       a$  UR                  UR                  sU l        U l        g [        S[        U5       35      e)NFzUnsupported layer type )
base_layerr   nnParameterDictr   _disable_adaptersmerged_adapterskwargsget_base_layer
isinstanceLinearin_featuresout_features
ValueErrortype)selfr   r   s      O/home/james-whalen/.local/lib/python3.13/site-packages/peft/tuners/c3a/layer.py__init__C3ALayer.__init__"   s    $**2.!&!((*
j")),,2<2H2H*JaJa/Dd/6tJ7G6HIJJ    c                X   XR                   R                  5       ;  a  [        SU S35      eU R                  5       R                  nUR
                  nU R                   U   n[        UR                  [        R                  5      5      R                  U5      nXRR                  S5      -  $ )NzAdapter z not found.)r   keysr   r   weightdtyper   totorchfloat32size)r   adapterbase_layer_weightbase_layer_weight_dtyper   delta_weights         r    get_delta_weightC3ALayer.get_delta_weight1   s    //..00xy<== //188"3"9"9__W-
)*--*FGJJKbc44R888r#   c           
        US::  a  [        SU 35      eU R                  U-  S:w  a  [        SU R                   SU 35      eU R                  U-  S:w  a  [        SU R                   SU 35      eX R                  U'   U R	                  5       R
                  n[        R                  " [        R                  " U R                  U-  U R                  U-  U[        R                  UR                  S95      U R                  U'   U R                  X5        U R                  U5        U R                  U R                   US9  g )Nr   zH`block_size` should be a positive integer value but the value passed is zPThe block size should be a factor of the input size. However, the input size is z and the block size is zRThe block size should be a factor of the output size. However, the output size is )r(   device)inference_mode)r   r   r   r   r   r'   r   	Parameterr*   zerosr+   r4   r   reset_c3a_parameters%_move_adapter_to_device_of_base_layerset_adapteractive_adapters)r   adapter_namer   init_weightsr5   r   r'   s          r    update_layerC3ALayer.update_layer;   s_   ?ghrgstuuj(A-bcgcscsbt  uL  MW  LX  Y  z)Q.deievevdw  xO  PZ  O[  \  )3%$$&--(*KK!!Z/  J. mm}}
)
% 	!!,=22<@--nMr#   c                   USL a  g XR                   R                  5       ;   Ga5  US:X  a-  [        R                  R	                  U R                   U   5        g US;   a  U R
                  U R                  pCS[        R                  " S[        X4-   5      -  5      -  n[        R                  " S5      U-  n[        R                  R                  U R                   U   U* U5        g US:X  aa  U R
                  nS[        R                  " S[        U5      -  5      -  n[        R                  R                  U R                   U   U* U5        g [        SU 35      eg )	NTgaussian)xavier_uniformFg      ?g       @g      @kaiming_uniformzUnknown init_weights: )r   r&   r   initnormal_r   r   mathsqrtfloatuniform_r   )r   r<   r=   fan_infan_outstdas          r    r8   C3ALayer.reset_c3a_parametersZ   s   4??//11z) =>!::"&"2"2D4E4EDIIcE&2B,C&CDDIIcNS(  !>AF!22))$))C%-$788  !>AF #9,!HII 2r#   )r   r   r   r   r   r   r   r   N)r   z	nn.ModulereturnNone)rO   torch.Tensor)F)r5   bool)__name__
__module____qualname____firstlineno__adapter_layer_namesother_param_namesr!   r1   r>   r*   no_gradr8   __static_attributes__ r#   r    r   r      s;    )'K9N> ]]_J Jr#   r   c                  n   ^  \ rS rSr        SU 4S jjrS	S
S jjrSS jrSS jrSU 4S jjrSr	U =r
$ )	C3ALinearo   c                   > [         TU ]  5         [        R                  " X40 UD6  X l        U R	                  X#U5        g )N)superr!   r   _active_adapterr>   )r   r   r<   r   r=   r   	__class__s         r    r!   C3ALinear.__init__q   s9     	$5f5+,LAr#   c                X   [        X5      nU(       d  gU GH  nX0R                  R                  5       ;   d  M#  U R                  5       nU(       a  UR                  R
                  R                  5       nU R                  U5      nXV-   n[        R                  " U5      R                  5       (       d  [        SU S35      eXTR                  l        O9U R                  U5      nUR                  R
                  U-   UR                  l        U R                  R                  U5        GM     g)a  
Merge the active adapter weights into the base weights

Args:
    safe_merge (`bool`, *optional*):
        If True, the merge operation will be performed in a copy of the original weights and check for NaNs
        before merging the weights. This is useful if you want to check if the merge operation will produce
        NaNs. Defaults to `False`.
    adapter_names (`list[str]`, *optional*):
        The list of adapter names that should be merged. If None, all active adapters will be merged. Defaults
        to `None`.
Nz1NaNs detected in the merged weights. The adapter z seems to be broken)r   r   r&   r   r'   datacloner1   r*   isfiniteallr   r   append)r   
safe_mergeadapter_namesactive_adapterr   orig_weightsr0   s          r    mergeC3ALinear.merge~   s     0D+N!5!5!77!002
 $.#4#4#9#9#?#?#AL#'#8#8#HL#/#>L >>,7;;==(OP^O__rs  .:%%*#'#8#8#HL-7->->-C-Cl-RJ%%*$$++N;) ,r#   c                   U R                   (       d  [        R                  " S5        g[        U R                  5      S:  a  U R                  R                  5       nXR                  R                  5       ;   a<  U R                  5       R                  =R                  U R                  U5      -  sl
        [        U R                  5      S:  a  M  gg)zG
This method unmerges all merged adapter layers from the base weights.
z Already unmerged. Nothing to do.Nr   )mergedwarningswarnlenr   popr   r&   r   r'   re   r1   )r   rl   s     r    unmergeC3ALinear.unmerge   s     {{MM<=$&&'!+!11557N!5!5!77##%,,11T5J5J>5ZZ1 $&&'!+r#   c                   UR                   nU R                  (       a9  U R                  (       a  U R                  5         U R                  " U/UQ70 UD6nGO U R                  (       a  U R                  " U/UQ70 UD6nOU R                  " U/UQ70 UD6nUR                  [        R                  5      nU R                   H  nX`R                  R                  5       ;  a  M"  U R                  U   R                  [        R                  5      n[        R                  " X5      UR                  S5      -  nXQR                  UR                   5      -  nM     UR                  U5      nU$ )Nr%   )r(   disable_adaptersrq   rv   r   r)   r*   r+   r;   r   r&   r
   applyr,   )r   xargsr   previous_dtyperesultrl   r   s           r    forwardC3ALinear.forward   s     {{__Q888F[[__Q888F__Q888FU]]#A"&"6"6!)=)=)??!__^<??N
,221AAFF2JN$$v||,, #7 >*r#   c                *   > [         TU ]  5       nSU-   $ )Nzc3a.)r`   __repr__)r   reprb   s     r    r   C3ALinear.__repr__   s    g |r#   )ra   )r<   strr   intr=   z?bool | Literal['gaussian', 'kaiming_uniform', 'xavier_uniform']rO   rP   )FN)rj   rR   rk   zOptional[list[str]]rO   rP   )rO   rP   )r{   rQ   r|   r   r   r   rO   rQ   )rO   r   )rS   rT   rU   rV   r!   rn   rv   r   r   rZ   __classcell__)rb   s   @r    r]   r]   o   sQ    B B 	B
 VB 
B&<P
[, r#   r]   )
__future__r   rF   rr   typingr   r   r   r*   torch.nnr   peft.tuners.tuners_utilsr   r   utilsr
   r   r   Moduler]   r[   r#   r    <module>r      sG    #   ) )   L ?PJ~ PJf[		8 [r#   