
    bi!                         d dl Z d dlmZmZmZ d dlZd dlmZ d dlmc m	Z
 d dlmZ d dlmZmZ  G d de      Z G d dej"                  e      Zy)	    N)AnyOptionalUnion)Conv1D)BaseTunerLayercheck_adapters_to_mergec                       e Zd ZdZdZdej                  ddfdZd Z e	j                         d        Zde	j                  fd	Zy)
FourierFTLayer)fourierft_spectrum)fourierft_n_frequencyfourierft_scalingfourierft_random_loc_seed
base_layerreturnNc                 0   || _         i | _        i | _        t        j                  i       | _        i | _        i | _        d| _        g | _	        || _
        | j                         }t        |t        j                        r$|j                  |j                  c| _        | _        y t        |t               rPt#        |j$                  d      r|j$                  j&                  n|j$                  j(                  \  | _        | _        y t+        dt-        |             )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      V/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/peft/tuners/fourierft/layer.py__init__zFourierFTLayer.__init__    s    $%'"!#"$"2"22"6)+&!&!((*
j")),2<2H2H*JaJa/Dd/
F+.5j6G6G.T
!!**ZdZkZkZqZq 0Dd/ 6tJ7G6HIJJ    c                    |dk  rt        d|       || j                  | j                  z  kD  r(t        d| d| j                  | j                  z         || j                  |<   || j                  |<   t        j                  | j                  | j                  z  t        j                         j                  | j                  |               d | | j                  |<   t        j                  | j                  |   | j                  z  | j                  |   | j                  z  gd      | j                  |<   || j                  |<   t        j                  t        j                  |      d      | j                  |<   |r| j!                  |       | j#                  |       | j%                  | j&                         y )	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   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_seeds         r$   update_layerz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<@--.r&   c                     || j                   j                         v r-t        j                  j	                  | j                   |          y y N)r   keysr   initzeros_)r#   r6   s     r$   r2   z'FourierFTLayer.reset_fourier_parametersQ   s9    4227799GGNN422<@A :r&   c                    | j                   |   }| j                  |   j                  |j                        }t	        j
                  | j                  | j                  |j                        }|j                         ||dd d f   |dd d f   f<   t        j                  j                  |      j                  | j                  |   z  }|j                  |j                        S )N)devicer      )r   r   torB   r+   zerosr   r   floatfftifft2realr   dtype)r#   adapterspectrumr   dense_spectrumdelta_weights         r$   get_delta_weightzFourierFTLayer.get_delta_weightV   s    **73,,w'**8??;T%6%68H8HQYQ`Q`a7?~~7Gwq!t}gadm34yy~6;;d>T>TU\>]]x~~..r&   )__name__
__module____qualname__adapter_layer_namesother_param_namesr   Moduler%   r;   r+   no_gradr2   TensorrO    r&   r$   r
   r
      s[    1cK299 K4 K,/6 U]]_B B/5<< /r&   r
   c                        e Zd Z	 	 	 	 	 ddededededeeef   deddf fd	Zdd
ede	e
e      ddfdZddZdej                  f fdZdej                  dededej                  fdZdef fdZ xZS )FourierFTLinearr6   r7   r8   fan_in_fan_outr9   r:   r   Nc                     t         	|           t        j                  | |fi | || _        || _        | j                  |||||       y r=   )superr%   r
   r[   _active_adapterr;   )
r#   r   r6   r7   r8   r[   r9   r:   r   	__class__s
            r$   r%   zFourierFTLinear.__init__b   sK     	j;F;,+,WlO\r&   
safe_mergeadapter_namesc                    t        | |      }|sy|D ]  }|| j                  j                         v s | j                         }|r||j                  j
                  j                         }|| j                  |      z  }t        j                  |      j                         st        d| d      ||j                  _        n.|j                  xj
                  | j                  |      z  c_        | j                  j                  |        y)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clonerO   r+   isfiniteallr!   r   append)r#   r`   ra   active_adapterr   orig_weightss         r$   mergezFourierFTLinear.merges   s     0mD+ 	<N!8!8!=!=!??!002
 $.#4#4#9#9#?#?#AL D$9$9.$IIL >>,7;;=(OP^O__rs  .:J%%*%%**d.C.CN.SS*$$++N;#	<r&   c                    | j                   st        j                  d       yt        | j                        dkD  r| j                  j                         }|| j                  j                         v r<| j                         j                  xj                  | j                  |      z  c_
        t        | j                        dkD  ryy)zW
        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   rc   rO   )r#   rh   s     r$   unmergezFourierFTLinear.unmerge   s     {{MM<=$&&'!+!11557N!8!8!=!=!??##%,,11T5J5J>5ZZ1 $&&'!+r&   c                 "    t         |   |      S r=   )r]   rO   )r#   rK   r_   s     r$   rO   z FourierFTLinear.get_delta_weight   s    w'00r&   xargsr   c                    |j                   }| j                  r3| j                  r| j                           | j                  |g|i |}n| j                  r | j                  |g|i |}n | j                  |g|i |}| j
                  D ]d  }|| j                  j                         vr | j                  |      }|j                  |j                         }|t        j                  ||      z   }f |j                  |      }|S r=   )rJ   disable_adaptersrl   rq   r   r5   r   r>   rO   rD   Flinear)r#   rs   rt   r   previous_dtyperesultrh   delta_ws           r$   forwardzFourierFTLinear.forward   s      {{$T__Q888F[[$T__Q888F$T__Q888F"&"6"6 7!)@)@)E)E)GG//?DD'!((1g"667 >*r&   c                 *    t         |          }d|z   S )Nz
fourierft.)r]   __repr__)r#   repr_   s     r$   r~   zFourierFTLinear.__repr__   s    g c!!r&   )i  g     b@FFi	  )FN)r   N)rP   rQ   rR   strintrF   boolr   r%   r   listrj   rq   r+   rW   rO   r   r|   r~   __classcell__)r_   s   @r$   rZ   rZ   `   s      $)."] ] 	]
 ] ] D#I&] ] 
]"#< #<Xd3i=P #<\` #<J
[15<< 1 c S U\\ ,"# " "r&   rZ   )rm   typingr   r   r   r+   torch.nnr   torch.nn.functional
functionalrw   transformers.pytorch_utilsr   peft.tuners.tuners_utilsr   r   r
   rU   rZ   rX   r&   r$   <module>r      sE     ' '     - LC/^ C/L_"bii _"r&   