
    oi`!                         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s  J	r
  S SKJr  S SKJrJr   " S S\5      r " S S\R"                  \5      rg)	    N)AnyOptionalUnion)Conv1D)BaseTunerLayercheck_adapters_to_mergec                       \ rS rSrSrSrS\R                  SS4S jr SS\	4S	 jjr
\R                  " 5       S
 5       rS\R                  4S jrSrg)FourierFTLayer   )fourierft_spectrum)fourierft_n_frequencyfourierft_scalingfourierft_random_loc_seed
base_layerreturnNc                 L   Xl         0 U l        0 U l        [        R                  " 0 5      U l        0 U l        0 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 [        U[         5      (       aU  [#        UR$                  S5      (       a  UR$                  R&                  OUR$                  R(                  u  U l        U l        g [+        S[-        U5       35      e)NFds_shapezUnsupported layer type )r   r   r   nnParameterDictr   indicesr   _disable_adaptersmerged_adapterskwargsget_base_layer
isinstanceLinearin_featuresout_featuresr   hasattrweightr   shape
ValueErrortype)selfr   r   s      U/home/james-whalen/.local/lib/python3.13/site-packages/peft/tuners/fourierft/layer.py__init__FourierFTLayer.__init__    s    $%'"!#"$"2"22"6)+&!&!((*
j")),,2<2H2H*JaJa/Dd/
F++.5j6G6G.T.T
!!**ZdZkZkZqZq 0Dd/ 6tJ7G6HIJJ    inference_modec                    US::  a  [        SU 35      eX R                  U R                  -  :  a(  [        SU SU R                  U R                  -   35      eX R                  U'   XPR                  U'   [
        R                  " U R                  U R                  -  [
        R                  " 5       R                  U R                  U   5      S9S U U R                  U'   [
        R                  " U R                  U   U R                  -  U R                  U   U R                  -  /SS9U R                  U'   X0R                  U'   [        R                  " [
        R                  " U5      SS9U R                  U'   U(       a  U R!                  U5        U R#                  U5        U R%                  U R&                  US	9  g )
Nr   zI`n_frequency` should be a positive integer value but the value passed is zu`n_frequency` should be less than or equal to the product of the input and output dimensions but the value passed is z and the product is )	generator)dimT)requires_grad)r)   )r"   r   r   r   r   torchrandperm	Generatormanual_seedr   stackr   r   	Parameterrandnr   reset_fourier_parameters%_move_adapter_to_device_of_base_layerset_adapteractive_adapters)r$   adapter_namen_frequencyscalinginit_weightsrandom_loc_seedr)   r   s           r%   update_layerFourierFTLayer.update_layer6   s    !hithuvww))D,=,===++6-7KDL\L\_c_p_pLpKqs  4?""<07F&&|4%*^^ 0 00oo'33D4R4RS_4`a&
 ;&\" &+[[\\,'4+;+;;T\\,=WZ^ZjZj=jkqr&
\" 07|,02U[[=Uei0j-)),722<@--nMr(   c                     XR                   R                  5       ;   a-  [        R                  R	                  U R                   U   5        g g N)r   keysr   initzeros_)r$   r9   s     r%   r5   'FourierFTLayer.reset_fourier_parametersS   s7    227799GGNN422<@A :r(   c                    U R                   U   nU R                  U   R                  UR                  5      n[        R
                  " U R                  U R                  UR                  S9nUR                  5       XCSS S 24   USS S 24   4'   [        R                  R                  U5      R                  U R                  U   -  nUR                  UR                  5      $ )N)devicer      )r   r   torG   r.   zerosr   r   floatfftifft2realr   dtype)r$   adapterspectrumr   dense_spectrumdelta_weights         r%   get_delta_weightFourierFTLayer.get_delta_weightX   s    **73,,w'**8??;T%6%68H8HQYQ`Q`a7?~~7Gq!t}gadm34yy~6;;d>T>TU\>]]x~~..r(   )r   r   r   r   r   r   r   r   r   r   r   )F)__name__
__module____qualname____firstlineno__adapter_layer_namesother_param_namesr   Moduler&   boolr>   r.   no_gradr5   TensorrT   __static_attributes__ r(   r%   r
   r
      sj    1cK299 K4 K. inNaeN: ]]_B B/5<< /r(   r
   c                     ^  \ rS rSr     SS\S\S\S\S\\\4   S\SS	4U 4S
 jjjr	SS\S\
\\      SS	4S jjrSS jrS\R                  4U 4S jjrS\R                  S\S\S\R                  4S jrS\4U 4S jjrSrU =r$ )FourierFTLinearb   r9   r:   r;   fan_in_fan_outr<   r=   r   Nc                    > [         T	U ]  5         [        R                  " X40 UD6  XPl        X l        U R                  X#XFU5        g rA   )superr&   r
   re   _active_adapterr>   )
r$   r   r9   r:   r;   re   r<   r=   r   	__class__s
            r%   r&   FourierFTLinear.__init__d   sA     	;F;,+,WO\r(   
safe_mergeadapter_namesc                 >   [        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XPR                  U5      -  n[        R                  " U5      R                  5       (       d  [        SU S35      eXTR                  l        O.UR                  =R
                  U R                  U5      -  s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   rB   r   r    dataclonerT   r.   isfiniteallr"   r   append)r$   rk   rl   active_adapterr   orig_weightss         r%   mergeFourierFTLinear.mergeu   s     0D+N!8!8!=!=!??!002
 $.#4#4#9#9#?#?#AL $9$9.$IIL >>,7;;==(OP^O__rs  .:%%*%%**d.C.CN.SS*$$++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   rB   r   r    rn   rT   )r$   rs   s     r%   unmergeFourierFTLinear.unmerge   s     {{MM<=$&&'!+!11557N!8!8!=!=!??##%,,11T5J5J>5ZZ1 $&&'!+r(   c                 "   > [         TU ]  U5      $ rA   )rg   rT   )r$   rP   ri   s     r%   rT    FourierFTLinear.get_delta_weight   s    w'00r(   xargsr   c                 <   UR                   nU R                  (       a8  U R                  (       a  U R                  5         U R                  " U/UQ70 UD6nOU 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
                   Hg  nX`R                  R                  5       ;  a  M"  U R                  U5      nUR                  UR                   5      nU[        R                  " X5      -   nMi     UR                  U5      nU$ rA   )rO   disable_adaptersrx   r}   r   r8   r   rB   rT   rI   Flinear)r$   r   r   r   previous_dtyperesultrs   delta_ws           r%   forwardFourierFTLinear.forward   s      {{__Q888F[[__Q888F__Q888F"&"6"6!)@)@)E)E)GG//?DD'!((1"66 #7 >*r(   c                 *   > [         TU ]  5       nSU-   $ )Nz
fourierft.)rg   __repr__)r$   repri   s     r%   r   FourierFTLinear.__repr__   s    g c!!r(   )rh   re   )i  g     b@FFi	  )FN)r   N)rV   rW   rX   rY   strintrK   r]   r   r&   r   listru   r}   r.   r_   rT   r   r   r   r`   __classcell__)ri   s   @r%   rc   rc   b   s      $)."] ] 	]
 ] ] D#I&] ] 
] ]"#< #<Xd3i=P #<\` #<J
[15<< 1 c S U\\ ,"# " "r(   rc   )ry   typingr   r   r   r.   torch.nnr   torch.nn.functional
functionalr   transformers.pytorch_utilsr   peft.tuners.tuners_utilsr   r   r
   r\   rc   ra   r(   r%   <module>r      sE     ' '     - LE/^ E/P_"bii _"r(   