
    oi                    R   S SK Jr  S SKrS SKrS SKrS SKJr  S SKJrJ	r	J
r
  S SKrS SKJr  S SKJs  Jr  S SKJr  S SKJrJr  Sq\S 5       rS r " S	 S
\5      r " S S\R4                  5      r " S S\5      r " S S\R4                  \5      r " S S\R4                  \5      rg)    )annotationsN)contextmanager)AnyOptionalUnion)Function)BaseTunerLayercheck_adapters_to_mergec               +    #    0 nU R                  5        HZ  u  p#UR                  5       nU[        R                  ;   a  [        R                  U   X'   [	        U5      [        R                  U'   M\     Sv   U  HO  nUR                  5       nX!;   a  X   [        R                  U'   M/  [        R                  R                  US5        MQ     g7f)a  
A context manager that will add each keyword argument passed to `os.environ` and remove them when exiting.

Will convert the values in `kwargs` to strings and upper-case all the keys.

Example:

```python
>>> import os
>>> from accelerate.utils import patch_environment

>>> with patch_environment(FOO="bar"):
...     print(os.environ["FOO"])  # prints "bar"
>>> print(os.environ["FOO"])  # raises KeyError
```
N)itemsupperosenvironstrpop)kwargsexisting_varskeyvalues       P/home/james-whalen/.local/lib/python3.13/site-packages/peft/tuners/boft/layer.pypatch_environmentr   &   s     $ Mlln
iik"**!#CMe*

3	 % 
iik+0BJJsOJJNN3% s   CCc                    [         b  [         $ SSKJn   [        R                  R                  [        5      n [        SSS9   U " SU S3U S3/SS	9nS S S 5        Uq [         $ ! , (       d  f       Wq [         $ = f! [         aC  n[        R                  " S
U S35        [        R                  " S5        S n S nAUq [         $ S nAff = f)Nr   )loadgcc)CCCXXfbd_cudaz/fbd/fbd_cuda.cppz/fbd/fbd_cuda_kernel.cuT)namesourcesverbosez#Failed to load the CUDA extension: z, check if ninja is available.zHSetting boft_n_butterfly_factor to 1 to speed up the finetuning process.)	_FBD_CUDAtorch.utils.cpp_extensionr   r   pathdirname__file__r   	Exceptionwarningswarn)r   curr_dirr   es       r   get_fbd_cudar+   J   s      /wwx(H%U3$:%67H:E\9]^H 4 I 43 I  ;A3>\]^`aIs5   
A; A#A; #
A8-A; 8A; ;
C2CCc                  8    \ rS rSrSr\S 5       r\S 5       rSrg)FastBlockDiagg   z
Implements a custom autograd Function for a fast block diagonal operation using CUDA.

This function is optimized for 4D tensors where the last two dimensions are equal, representing block diagonal
matrices for efficient computation on CUDA devices.
c                `    [        5       R                  U5      S   nU R                  U5        U$ )a  
The forward method for FastBlockDiag.

Computes the block diagonal operation on the input tensor using a CUDA-optimized function. This method assumes
that the input is a 4D tensor where the last two dimensions are equal, which represent the blocks to be
diagonalized.

Parameters:
ctx: A context object that can be used to stash information for backward computation.
input (Tensor): The input tensor of shape (N, D, H, H), where `N` is the batch size,
                `D` represents one additional dimension (In BOFT, the number of BOFT blocks), and `H` is the
                size of the square blocks along the last two dimensions (In BOFT, the block size).

Returns:
Tensor: The resulting tensor after applying the block diagonal operation,
        will have the shape (N, DxH, DxH).
r   )r+   forwardsave_for_backward)ctxinputoutputs      r   r0   FastBlockDiag.forwardo   s.    & ''.q1e$    c                Z    U R                   u  n[        5       R                  X5      S   nU$ )Nr   )saved_tensorsr+   backward)r2   grad_outputr3   
grad_inputs       r   r9   FastBlockDiag.backward   s,    $$!^,,[@C
r6    N)	__name__
__module____qualname____firstlineno____doc__staticmethodr0   r9   __static_attributes__r=   r6   r   r-   r-   g   s/      ,  r6   r-   c                  6   ^  \ rS rSrSrSU 4S jjrS rSrU =r$ )MultiplicativeDropoutLayer   z7
Implements the multiplicative dropout layer for BOFT.
c                .   > [         TU ]  5         Xl        g)z
Initializes the multiplicative dropout layer.

Parameters:
p (float): The probability of dropping out a block. Defaults to 0.0.
N)super__init__p)selfrK   	__class__s     r   rJ   #MultiplicativeDropoutLayer.__init__   s     	r6   c                   U R                   (       GaX  UR                  S   UR                  S   :w  a  [        S5      eUR                  u  p#pE[        R                  " SUS5      R                  5       n[        U R                  U-  5      nX7-
  n[        R                  " [        R                  " XqR                  S9[        R                  " XR                  S9/5      n	U	[        R                  " U5         R                  SUSS5      n	[        R                  " X#SSUR                  S9n
XU'   [        R                  " XAR                  S9R                  X#SS5      nSU
-
  U-  X-  -   nU$ )a[  
Applies multiplicative dropout to the input tensor.

Parameters:
x (Tensor): The input tensor of shape (N, D, H, H), where `N` is the batch size, `D` represents
            one additional dimension (In BOFT, the number of BOFT blocks), and `H` is the size of the square
            blocks along the last two dimensions (In BOFT, the block size).
z4The last two dimensions of input should be the same!r   )   devicerR   )trainingshape
ValueErrortorchrandintitemintrK   catonesrT   zerosrandpermvieweyerepeat)rL   xNDH_n_randomnum_to_replace	num_zerosmask	full_mask
eye_matrixs               r   r0   "MultiplicativeDropoutLayer.forward   s,    ===wwr{aggbk) !WXXJA! }}Q40557H !!_N*I 99ejjI5;;W`iqiqKrstD q)*//1a;DA!Qqxx@I"&h 1XX6==aAqIJY!#i&<<Ar6   rK   )        )	r>   r?   r@   rA   rB   rJ   r0   rD   __classcell__rM   s   @r   rF   rF      s    # #r6   rF   c                  v    \ rS rSrSrSrSrSS jrS rSS jr	SSS	 jjr
 S SS
 jjrS rS rSS jrS rSrg)	BOFTLayer   z
Implements the BOFT layer.
)boft_Rboft_s)boft_block_sizeboft_block_numboft_dropoutc                F   Xl         0 U l        0 U l        [        R                  " 0 5      U l        [        R                  " 0 5      U l        [        R                  " 0 5      U l        SU l	        / U l
        SU l        X l        U R                  5       n[        U[        R                  5      (       a  UR                   UR"                  pCON[        U[        R$                  5      (       a  UR&                  UR(                  pCO[+        S[-        U5       35      eX0l        X@l        g)z
Initializes the BOFT layer.

Note, currently only support linear layer and convolutional layer, with further support for other layers to be
added soon.

Parameters:
base_layer: the pretrained model layer
FTzUnsupported layer type N)
base_layerrx   ry   nn
ModuleDictrz   ParameterDictrv   rw   _disable_adaptersmerged_adapterscast_input_dtype_enabledr   get_base_layer
isinstanceLinearin_featuresout_featuresConv2din_channelsout_channelsrW   type)rL   r|   r   r   r   s        r   rJ   BOFTLayer.__init__   s     %! MM"-&&r*&&r*!&!(,%((*
j")),,(2(>(>
@W@W
BII..(2(>(>
@W@W6tJ7G6HIJJ&(r6   c                P    XR                   ;  a  g [        R                  " S5        g )NGScaling operation for BOFT not supported! Automatically set scale to 1.)scalingr'   r(   )rL   adapterscales      r   	set_scaleBOFTLayer.set_scale   s    ,,&_`r6   c                    US:X  a  g U R                    H8  nX R                  R                  5       ;  a  M"  [        R                  " S5        M:     g )NrR   r   active_adaptersrv   keysr'   r(   rL   r   active_adapters      r   scale_layerBOFTLayer.scale_layer   s?    A:"22N[[%5%5%77MMcd	 3r6   Nc                    U R                    H8  nX R                  R                  5       ;  a  M"  [        R                  " S5        M:     g )Nz?Unscaling operation for BOFT not supported! Keeping scale to 1.r   r   s      r   unscale_layerBOFTLayer.unscale_layer   s5    "22N[[%5%5%77MM[\	 3r6   c           	        [        5       (       d
  SU l        SnOSU l        US-
  nUS:  a  [        SUS-    S35      eUS:  a
  [        US9n	O[        R
                  " 5       n	U R                  R                  [        R                  " X05      5        US:X  a  US:w  a  U R                  U-  S:w  a  [        S	U R                   S
U S35      eUS:w  aY  U[        [        R                  " U5      5      :  a  [        SUS-    SU S35      eUSU-  -  S:w  a  [        SU SUS-    S35      e[        U R                  U-  5      nOUS:w  a  US:X  a  U R                  U-  S:w  a  [        S	U R                   SU S35      eUS:w  as  U R                  USU-  -  :  a"  [        SU R                   SUS-    SU S35      eU R                  USU-  -  -  S:w  a"  [        SU R                   SUS-    SU S35      e[        U R                  U-  5      nO[        S5      eUS:w  a0  US-  S:w  a  [        SU S35      eUS-  S:w  a  [        SU S35      e[        R                  " US-   U R                  U R                  45      n
[        US-   5       HQ  nU R!                  U R                  [        USU-  -  5      [        US-  5      U5      nU R#                  U5      nXU'   MS     U R%                  SU
SS9  [        R&                  " [        R(                  " US-   X2U5      5      U R*                  U'   [        R&                  " [        R,                  " [        U R.                  5      S5      5      U R0                  U'   U R3                  X5        X R4                  U'   X0R6                  U'   U R9                  U5        U R;                  U R<                  US9  g)zV
Update the linear layer with trainable BOFT weights. Override for other layer types.
FrR   Tr   -You can only specify boft_n_butterfly_factor ! to be a positive integer number.rp   ro   zin_features (') must be divisible by boft_block_num ()!0Invalid combination of boft_n_butterfly_factor () and boft_block_num (   boft_block_num (J) must be a multiple of 2 raised to the power of boft_n_butterfly_factor (() must be divisible by boft_block_size (z$Invalid combination of in_features (), boft_n_butterfly_factor () and boft_block_size (ZSomething went wrong, please report this error: https://github.com/huggingface/peft/issues) must be an even number!boft_block_size (boft_P
persistentinference_modeN)r+   fbd_cuda_availablerW   rF   r}   Identityrz   updater~   r   r[   mathlog2rX   emptyrangeblock_butterfly_permperm2matregister_buffer	Parameterr^   rv   r]   r   rw   reset_boft_parametersrx   ry   %_move_adapter_to_device_of_base_layerset_adapterr   )rL   adapter_namerx   ry   boft_n_butterfly_factorrz   init_weightsr   r   boft_dropout_layerPipermperm_mats                 r   update_layerBOFTLayer.update_layer  s    ~~&+D#&'#&*D# #:A"="Q&?@WZ[@[?\\}~ 
 #!;l!K!#  /Q!RSaNa$7.0A5 #D$4$4#55\]k\llno  '!+*S>1J-KK$JKbefKfJgg}  M  ~N  NP  Q  "Q(?%?@AE$*>*:  ;E  F]  `a  Fa  Eb  bd  e  "$"2"2n"DEO!n&9/1Q6 #D$4$4#55]^m]nnpq  '!+##!=T:T'UV$>t?O?O>PPl  nE  HI  nI  mJ  Ja  bq  ar  rt  u  ##!=T:T'UVZ[[$>t?O?O>PPl  nE  HI  nI  mJ  Ja  bq  ar  rt  u  !!1!1_!DEN l 
 #a'!Q& #3N3CC\!]^^"a' #4_4EE^!_`` KK014d6F6FHXHXYZ.23A,,  #na&A"BCZ[H[D\^uD }}T*HaD 4 	XqU;$&LLKK/!3^Vef%
L! %'LLC@Q@Q<RTU1V$WL!""<> .=\*,:L)22<@--nMr6   c                   USL aY  [         R                  R                  U R                  U   SSS9  [         R                  R                  U R                  U   SSS9  gXR                  R                  5       ;   am  USL aY  [         R                  R                  U R                  U   5        [         R                  R                  U R                  U   5        g[        SU< 35      eg)	z
Reset the BOFT parameters.
Frp   皙?)meanstdg      ?NTz$Unknown initialization init_weights=)	r}   initnormal_rv   rw   r   zeros_ones_rW   )rL   r   r   s      r   r   BOFTLayer.reset_boft_parametersu  s     5 GGOODKK5CSOIGGOODKK5CSOI;;++--t#t{{<89dkk,78 #H</!JKK .r6   c                ~    [        U5      n[        R                  " X"45      n[        U5       H  u  pESX4U4'   M     U$ )zt
Convert permutation indices to permutation matrix.

Args:
indices: A list of indices representing the permutation.
rR   )lenrX   r^   	enumerate)rL   indicesnr   r   idxs         r   r   BOFTLayer.perm2mat  sE     L ;;v&  (FA HV ) r6   c                   US:X  a  [         R                  " U5      $ X#-  S-  U:  a  [        S5      e[        X-  5      n[         R                  " U5      nS nU" XS5      n[	        SX5       H  n	X-   n
XiU
 nX   XiU
& M     U$ )a   
Define the permutation matrix for the block butterfly permutation.

Args:
n: size of the permutation matrix
b: desired number of blocks after multiplying with the permutation matrix
r: base block size of the block diagonal matrix, e.g. 2x2, 3x3, 5x5 etc.
r   r   zInvalid number of blocks!c                   X-  n[         R                  " U 5      n[         R                  " U [         R                  S9n[         R                  " SUS5      n[         R                  " SUS5      n[         R                  " XV4SS9n[        U5       H?  u  pU[        X-  5      [        X-  U-   5       U[        X-  5      [        X-  U-   5      & MA     U$ )N)dtyper   r   rR   )dim)rX   aranger   longr\   r   r[   )
brstepinitial_ordersorted_orderevensodds
sorted_seqr   poss
             r   
sort_block2BOFTLayer.block_butterfly_perm.<locals>.sort_block  s    5D!LLOM ;;q

;LLLD!,E<<4+DE=a8J#J/<I#cg,Y\]`]dgh]hYi<jSZ#aeai.9 0r6   )rX   r   rW   r[   r   )rL   r   r   r   n_butterfly_factor
block_sizer   r   r   r   	block_endtmp_indicess               r   r   BOFTLayer.block_butterfly_perm  s     "<<?"519q=899[
,,q/
	  "*0q!(AI!I.K#.#<Gi  ) r6   c                   UR                   u  p#nSXR                  SS5      -
  -  n[        R                  " X1R                  S9R                  S5      R                  X#U5      n[        R                  R                  Xe-   Xe-
  SS9nU$ )z
Perform the Cayley parametrization on a batch of skew-symmetric matrices.

Args:
    data: A batch of skew-symmetric matrices of shape (b, r, c).
g      ?rR   r   rS   r   F)left)	rV   	transposerX   ra   rT   	unsqueezeexpandlinalgsolve)rL   datar   r   cskew_matid_matQs           r   cayley_batchBOFTLayer.cayley_batch  s{     **a$1!5561[[1;;A>EEaAN LLv0&2C%Pr6   )r   r|   rv   ry   rx   rz   rw   r   r   r   r   r   r   )r|   	nn.ModulereturnNone)r   floatr  r  Nr  r  Fr   bool)   rR   )r>   r?   r@   rA   rB   adapter_layer_namesother_param_namesrJ   r   r   r   r   r   r   r   r   rD   r=   r6   r   rt   rt      s\    
 /M!)Fae]  %lN lN\L"&%Nr6   rt   c                     ^  \ rS rSrSr       S
                 SU 4S jjjrSSS jjrSS jrSS jrSS jr	SU 4S jjr
S	rU =r$ )r   i  z$
BOFT implemented in a dense layer.
c
                   > [         TU ]  5         [        R                  " X40 U
D6  Xpl        X l        U R                  X#XEXh5        Xl        g r  )rI   rJ   rt   fan_in_fan_out_active_adapterr   is_target_conv_1d_layer)rL   r|   r   rx   ry   r   rz   r  r   r  r   rM   s              r   rJ   Linear.__init__  sM     	46v6,+>T`	
 (?$r6   c                   [        X5      nU(       d  gU GHI  nX0R                  R                  5       ;   d  M#  U R                  5       nUR                  R
                  nU(       Ga  UR                  R                  R                  5       nU R                  U5      u  px[        R                  " USS5      n[        R                  " XvR                  UR
                  5      5      n[        R                  " USS5      nXh-  n[        R                  " U5      R                  5       (       d  [        SU S35      eUR!                  5       R                  U5      U R"                  R                  l        OU R                  U5      u  pxUR                  R                  R                  5       n[        R                  " USS5      n[        R                  " XvR                  UR
                  5      5      n[        R                  " USS5      nXh-  nUR!                  5       R                  U5      U R"                  R                  l        U R$                  R'                  U5        GML     g)  
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`.
Nr   rR   z1NaNs detected in the merged weights. The adapter z seems to be broken)r
   rv   r   r   weightr   r   cloneget_delta_weightrX   r   mmtoisfiniteallrW   
contiguousr|   r   append	rL   
safe_mergeadapter_namesr   r|   
orig_dtypeorig_weightbutterfly_oft_matrw   s	            r   mergeLinear.merge  s    0D+N!1!1!33!002
'..44
 #-"3"3"8"8">">"@K040E0En0U-%"'//+q!"DK"'((+<nnM^MdMd>e"fK"'//+q!"DK"-"6K >>+6::<<(OP^O__rs  3>2H2H2J2M2Mj2YDOO**/040E0En0U-%","3"3"8"8">">"@K"'//+q!"DK"'((+<nnM^MdMd>e"fK"'//+q!"DK"-"6K2=2H2H2J2M2Mj2YDOO**/$$++N;= ,r6   c                   U R                   (       d  [        R                  " S5        g[        U R                  5      S:  GaE  U R                  R                  5       nU R                  5       nUR                  R                  nXR                  R                  5       ;   a  U R                  U5      u  pEUR                  R                  R                  5       n[        R                  " USS5      n[        R                   " UR#                  5       UR%                  UR                  5      5      n[        R                  " USS5      nUSU-  -  R%                  U5      UR                  l        [        U R                  5      S:  a  GMD  ggzG
This method unmerges all merged adapter layers from the base weights.
z Already unmerged. Nothing to do.Nr   rR   )mergedr'   r(   r   r   r   r   r  r   rv   r   r  r   r  rX   r   r  tr  rL   r   r|   r   r"  rw   r!  s          r   unmergeLinear.unmerge!  s*    {{MM<=$&&'!+!11557N,,.J#**00J!1!1!33,0,A,A.,Q)!(//44::<#ook1a@#hh'8':':'<knnM^MdMd>ef#ook1a@*5V*D)H)H)T
!!& $&&'!++r6   c                   U R                   U   nU R                  U   nUR                  u  pEpgUR                  XE-  Xf5      nU R	                  U5      nUR                  XEXf5      nU R
                  (       a  [        R                  U5      n	OIUR                  S5      n[        R                  " [        R                  " U5      6 n	U	R                  S5      n	U R                  R                  U	R                  5      n
[        R                   " XR#                  SSS5      5      n[        R                   " X5      nUS   n[%        SUR                  S   5       H
  nX   U-  nM     X4$ )
Compute the delta weight for the given adapter.

Args:
    adapter (str):
        The name of the adapter for which the delta weight should be computed.
r   r   rR   )rv   rw   rV   r`   r   r   r-   applysqueezerX   
block_diagunbindr   r   r  rT   bmmpermuter   rL   r   rv   rw   rd   re   rf   rg   orth_rotate_butterflyblock_diagonal_butterflyr   butterfly_oft_mat_batchr"  r   s                 r   r  Linear.get_delta_weight7  sE    W%W%\\
aQUA) $ 1 1& 9 5 : :1 F""'4':':;P'Q$$9$A$A!$D!','7'7F[9\']$'?'I'I!'L$ 8 ? ?@"')),DnnUVXY[\F]"^"'))F"L3A6q177:;A 7 :=N N < !((r6   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OU R                  (       a  U R                  " U/UQ70 UD6nGOt[
        R                  " U R                  UR                  US9n[
        R                  " [        U R                  5      S4UR                  US9nU R                   GH  nXR                  R                  5       ;  a  M#  U R                  U   n	U R                  U   n
U R                   U   nU	R"                  u  ppU	R%                  X-  X5      n	U R'                  U	5      nUR%                  XX5      nU" U5      nU R(                  (       a  [*        R-                  U5      nOIUR/                  S5      n[
        R0                  " [
        R2                  " U5      6 nUR5                  S5      nU R6                  R9                  U5      nUR9                  U5      n[
        R:                  " UUR=                  SSS5      5      n[
        R:                  " UU5      nUS   n[?        SUR"                  S   5       H  nUU   U-  nM     UU-  nX-  nGM     UR9                  U RA                  5       RB                  RD                  R                   5      nU RA                  5       RB                  RD                  n[
        RF                  " USS5      nUR9                  U5      nUR9                  U5      n[
        RH                  " UU5      n[
        RF                  " USS5      nUU-  nUR9                  U5      nU R                  RJ                  b4  U R                  RJ                  R9                  U5      U R                  l%        [L        RN                  " UUU R                  RJ                  S9nUR9                  U5      nU$ )NrT   r   rR   r   r   )r3   r  bias)(r   disable_adaptersr'  r*  r|   rX   ra   r   rT   r]   r[   r   r   rv   r   rw   rz   rV   r`   r   r   r-   r.  r/  r0  r1  r   r   r  r2  r3  r   r   r  r   r   r  r;  Flinear)rL   rc   argsr   previous_dtyperesultboft_rotation
boft_scaler   rv   rw   dropoutrd   re   rf   rg   r5  r6  r   r7  r"  r   r!  rotated_weightscaled_rotated_weights                            r   r0   Linear.forwardW  sT     {{__Q888F[[__Q888F!IId&6&6qxx~^MS):):%;Q$?XfgJ"&"6"6!)9)9);;^4^4++N;#\\
aQUA1(,(9(9&(A%(=(B(B1(N%(/0E(F%**/</B/BCX/Y,,A,I,I!,L)/4/?/?NcAd/e,/G/Q/QRS/T, *+C+F+Fq+I(*/))4Lfnn]^`acdNe*f'*/))F<S*T'$;A$>!q"9"?"?"BCA(?(BEV(V% D !2M A#0
= #7@ T((*1166<<=A--/66;;K//+q!<K),,^<M%..8K"XXm[AN"__^QBN$2Z$?!$9$<$<^$L!##/'+';';'>'>~'N$XXA.C$//J^J^_F>*r6   c                *   > [         TU ]  5       nSU-   $ Nzboft.rI   __repr__rL   reprM   s     r   rK  Linear.__repr__      g }r6   )r  r  r  )   r   r   r   FTF)r   r   rx   r[   ry   r[   r   r[   rz   r  r  r  r   Union[bool, str]r  r  r  r  FNr  r  r  zOptional[list[str]]r  r  r  r  z!tuple[torch.Tensor, torch.Tensor]rc   torch.Tensorr?  r   r   r   r  rV  r  r   )r>   r?   r@   rA   rB   rJ   r#  r*  r  r0   rK  rD   rq   rr   s   @r   r   r     s      !'(!$)-(-? ? 	?
 ? "%? ? ? '? "&? 
? ?00<dU,)@>@ r6   r   c                     ^  \ rS rSrSr     S               SU 4S jjjr S SS jjrSSS jjrSS jrSS jr	SS jr
SU 4S	 jjrS
rU =r$ )r   i  z%
BOFT implemented in a Conv2d layer.
c                ~   > [         T	U ]  5         [        R                  X5        X l        U R	                  X#XEXg5        g r  )rI   rJ   rt   r  r   )
rL   r|   r   rx   ry   r   rz   r   r   rM   s
            r   rJ   Conv2d.__init__  s:     	4,+>T`	
r6   c           	        [        5       (       d
  SU l        SnOSU l        US-
  nUS:  a  [        SUS-    S35      eUS:  a
  [        US9n	O[        R
                  " 5       n	U R                  R                  [        R                  " X05      5        U R                  5       n
U R                  U
R                  S   -  U
R                  S   -  nUS:X  a  US:w  a  X-  S:w  a  [        S	U S
U S35      eUS:w  aY  U[        [        R                  " U5      5      :  a  [        SUS-    SU S35      eUSU-  -  S:w  a  [        SU SUS-    S35      e[        X-  5      nOUS:w  a}  US:X  aw  X-  S:w  a  [        S	U SU S35      eUS:w  aI  XSU-  -  :  a  [        SU SUS-    SU S35      eXSU-  -  -  S:w  a  [        SU SUS-    SU S35      e[        X-  5      nO[        S5      eUS:w  a0  US-  S:w  a  [        SU S35      eUS-  S:w  a  [        SU S35      e[        R                   " US-   X45      n[#        US-   5       HG  nU R%                  U[        USU-  -  5      [        US-  5      U5      nU R'                  U5      nXU'   MI     U R)                  SUSS9  [        R*                  " [        R,                  " US-   X2U5      5      U R.                  U'   [        R*                  " [        R0                  " S[        U R2                  5      5      5      U R4                  U'   U R7                  X5        X R8                  U'   X0R:                  U'   U R=                  U5        U R?                  U R@                  US9  g)z6
Update the conv2d layer with trainable BOFT weights.
FrR   Tr   r   r   rp   ro   z Convolutional kernel dimension (r   r   r   r   r   r   r   r   z7Invalid combination of convolutional kernel dimension (r   r   r   r   r   r   r   r   N)!r+   r   rW   rF   r}   r   rz   r   r~   r   r   kernel_sizer[   r   r   rX   r   r   r   r   r   r   r^   rv   r]   r   rw   r   rx   ry   r   r   r   )rL   r   rx   ry   r   rz   r   r   r   r   r|   conv_filter_dimr   r   r   r   s                   r   r   Conv2d.update_layer  s     ~~&+D#&'#&*D# #:A"="Q&?@WZ[@[?\\}~ 
 #!;l!K!#  /Q!RS ((*
**Z-C-CA-FFI_I_`aIbb aNa$7/14 66GGno}n~  A  B  '!+*S>1J-KK$JKbefKfJgg}  M  ~N  NP  Q  "Q(?%?@AE$*>*:  ;E  F]  `a  Fa  Eb  bd  e  "/"CDO!n&90A5 66GGop  pA  AC  D  '!+"<S9S&TU$QRaQbb~  @W  Z[  @[  \  \s  tC  sD  DF  G  #<S9S&TUYZZ$QRaQbb~  @W  Z[  @[  \  \s  tC  sD  DF  G  !!CDN l 
 #a'!Q& #3N3CC\!]^^"a' #4_4EE^!_`` KK014oWX.23A,,^qQx%@!A3YZGZC[]tD }}T*HaD 4 	XqU;$&LLKK/!3^Vef%
L! %'LLAs4CTCT?U1V$WL!""<> .=\*,:L)22<@--nMr6   c                |   [        X5      nU(       d  gU GH"  nX0R                  R                  5       ;   d  M#  U R                  5       nUR                  R
                  nU(       Ga\  UR                  R                  R                  5       nU R                  U5      u  pxUR                  U R                  U R                  UR                  S   -  UR                  S   -  5      n[        R                  " USS5      n[        R                  " XvR!                  UR
                  5      5      n[        R                  " USS5      nXh-  nUR                  U R                  U R                  UR                  S   UR                  S   5      nUR#                  5       R!                  U5      U R$                  R                  l        GOZU R                  U5      u  pxUR                  R                  R                  5       nUR                  U R                  U R                  UR                  S   -  UR                  S   -  5      n[        R                  " USS5      n[        R                  " XvR!                  UR
                  5      5      n[        R                  " USS5      nXh-  nUR                  U R                  U R                  UR                  S   UR                  S   5      nUR#                  5       R!                  U5      U R$                  R                  l        U R&                  R)                  U5        GM%     g)r  Nr   rR   )r
   rv   r   r   r  r   r   r  r  r`   r   r   r\  rX   r   r  r  r  r|   r   r  r  s	            r   r#  Conv2d.merge(  s    0D+N!1!1!33!002
'..44
 #-"3"3"8"8">">"@K040E0En0U-%"-"2"2))4+;+;j>T>TUV>W+WZdZpZpqrZs+s#K #(//+q!"DK"'((+<nnM^MdMd>e"fK"'//+q!"DK"-"6K"-"2"2))4+;+;Z=S=STU=VXbXnXnopXq#K 3>2H2H2J2M2Mj2YDOO**/040E0En0U-%","3"3"8"8">">"@K"-"2"2))4+;+;j>T>TUV>W+WZdZpZpqrZs+s#K #(//+q!"DK"'((+<nnM^MdMd>e"fK"'//+q!"DK"-"6K"-"2"2))4+;+;Z=S=STU=VXbXnXnopXq#K 3>2H2H2J2M2Mj2YDOO**/$$++N;O ,r6   c                (   U R                   (       d  [        R                  " S5        g[        U R                  5      S:  Ga  U R                  R                  5       nU R                  5       nUR                  R                  nXR                  R                  5       ;   GaU  U R                  U5      u  pEUR                  R                  R                  5       nUR                  U R                  U R                   UR"                  S   -  UR"                  S   -  5      n[$        R&                  " USS5      n[$        R(                  " UR+                  5       UR-                  UR                  5      5      n[$        R&                  " USS5      nUSU-  -  nUR                  U R                  U R                   UR"                  S   UR"                  S   5      nUR-                  U5      UR                  l        [        U R                  5      S:  a  GM  ggr&  )r'  r'   r(   r   r   r   r   r  r   rv   r   r  r   r  r`   r   r   r\  rX   r   r  r(  r  r)  s          r   r*  Conv2d.unmergec  s    {{MM<=$&&'!+!11557N,,.J#**00J!1!1!33,0,A,A.,Q)!(//44::<)..%%$$z'='=a'@@:CYCYZ[C\\ $ook1a@#hh'8':':'<knnM^MdMd>ef#ook1a@)QZ8)..%%$$**1-**1-	 *5
)C
!!&/ $&&'!++r6   c                   U R                   U   nU R                  U   R                  SS5      nUR                  u  pEpgUR	                  XE-  Xf5      nU R                  U5      nUR	                  XEXf5      nU R                  (       a  [        R                  U5      n	OIUR                  S5      n[        R                  " [        R                  " U5      6 n	U	R                  S5      n	U R                  R                  U	R                   5      n
[        R"                  " XR%                  SSS5      5      n[        R"                  " X5      nUS   n['        SUR                  S   5       H
  nX   U-  nM     X4$ )r-  r   rR   r   )rv   rw   r   rV   r`   r   r   r-   r.  r/  rX   r0  r1  r   r   r  rT   r2  r3  r   r4  s                 r   r  Conv2d.get_delta_weight  sR    W%W%//15\\
aQUA) $ 1 1& 9 5 : :1 F""'4':':;P'Q$$9$A$A!$D!','7'7F[9\']$'?'I'I!'L$ 8 ? ?@"')),DnnUVXY[\F]"^"'))F"L3A6q177:;A 7 :=N N < !((r6   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OU R                  (       a  U R                  " U/UQ70 UD6nGO^[
        R                  " U R                  U R                  R                  S   -  U R                  R                  S   -  UR                  UR                   S9n[
        R                  " [        U R                  5      S4UR                  UR                   S9nU R                   GH  nXR                  R                  5       ;  a  M#  U R                  U   n	U R                   U   R#                  SS5      n
U R$                  U   nU	R&                  u  ppU	R)                  X-  X5      n	U R+                  U	5      nUR)                  XX5      nU" U5      nU R,                  (       a  [.        R1                  U5      nOIUR3                  S5      n[
        R4                  " [
        R6                  " U5      6 nUR9                  S5      nU R:                  R=                  U5      nUR=                  U5      n[
        R>                  " UURA                  SSS5      5      n[
        R>                  " UU5      nUS   n[C        SUR&                  S   5       H  nUU   U-  nM     UU-  nX-  nGM     UR=                  U R                  RD                  RF                  R                   5      nU R                  RD                  RF                  nUR)                  U R                  U R                  U R                  R                  S   -  U R                  R                  S   -  5      n[
        R"                  " USS5      n[
        RH                  " UU5      n[
        R"                  " USS5      nUU-  nUR)                  U R                  U R                  U R                  R                  S   U R                  R                  S   5      nU RK                  UUR                   5      nU RK                  U R                  RL                  UR                   5      n[N        RP                  " UUUU R                  RR                  S   U R                  RT                  S   S9nUR=                  U5      nU$ )Nr   r:  rR   r   )r3   r  r;  paddingstride)+r   r<  r'  r*  r|   rX   ra   r   r\  rT   r]   r[   r   r   rv   r   rw   r   rz   rV   r`   r   r   r-   r.  r/  r0  r1  r   r   r  r2  r3  r   r  r   r  _cast_input_dtyper;  r=  conv2drf  rg  )rL   rc   r?  r   r@  rA  rB  rC  r   rv   rw   rD  rd   re   rf   rg   r5  r6  r   r7  r"  r   r!  rE  rF  r;  s                             r   r0   Conv2d.forward  s"     {{__Q888F[[__Q888F!II  4??#>#>q#AADOOD_D_`aDbbxxggM
 S):):%;Q$?XYX_X_`J"&"6"6!)9)9);;^4^4>>q!D++N;#\\
aQUA1(,(9(9&(A%(=(B(B1(N%(/0E(F%**/</B/BCX/Y,,A,I,I!,L)/4/?/?NcAd/e,/G/Q/QRS/T,*+C+F+Fq+I(*/))4Lfnn]^`acdNe*f'*/))F<S*T'$;A$>!q"9"?"?"BCA(?(BEV(V% D !2M A#0
; #7> T__++00667A//0055K%**!!  4??#>#>q#AADOOD_D_`aDbbK  //+q!<K"XXm[AN"__^QBN$2Z$?!$9$>$>!!4#3#3T__5P5PQR5SUYUdUdUpUpqrUs%! &&q*?*E*EFA))$//*>*>@U@[@[\DXX,//2--a0F >*r6   c                *   > [         TU ]  5       nSU-   $ rI  rJ  rL  s     r   rK  Conv2d.__repr__  rO  r6   )r  r   )rP  r   r   r   T)r|   r   r   r   rx   r[   ry   r[   r   r[   rz   r  r   rQ  r  r  r  r  rR  rS  r  rT  rU  rW  )r>   r?   r@   rA   rB   rJ   r   r#  r*  r  r0   rK  rD   rq   rr   s   @r   r   r     s      !'(!)-

 
 	

 
 "%
 
 '
 

 
6  %rN rNh9<vD@)BKZ r6   r   )
__future__r   r   r   r'   
contextlibr   typingr   r   r   rX   torch.nnr}   torch.nn.functional
functionalr=  torch.autogradr   peft.tuners.tuners_utilsr	   r
   r!   r   r+   r-   ModulerF   rt   r   r   r=   r6   r   <module>rv     s   $ #  	  % ' '     # L 	  &  &F:#H #L2 2jM M`GRYY	 GTWRYY	 Wr6   