o
    Ni`!                     @   s   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  m	Z
 d dlmZ d dlmZmZ G dd deZG dd dejeZdS )	    N)AnyOptionalUnion)Conv1D)BaseTunerLayercheck_adapters_to_mergec                   @   sZ   e Zd ZdZdZdejddfddZ	dd	efd
dZ	e
 dd Zde
jfddZdS )FourierFTLayer)fourierft_spectrum)fourierft_n_frequencyfourierft_scalingfourierft_random_loc_seed
base_layerreturnNc                 K   s   || _ i | _i | _ti | _i | _i | _d| _g | _	|| _
|  }t|tjr3|j|j| _| _d S t|trLt|jdrB|jjn|jj\| _| _d S 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    r!   O/home/ubuntu/.local/lib/python3.10/site-packages/peft/tuners/fourierft/layer.py__init__    s    
zFourierFTLayer.__init__Finference_modec                 K   s
  |dkrt d| || j| j kr!t d| d| j| j  || j|< || j|< tj| j| j t | j| dd | | j	|< tj
| j	| | j | j	| | j gdd| j	|< || j|< tjt|dd| j|< |rv| | | | | j| j|d	 d S )
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   r!   r!   r"   update_layer6   s6   




 


zFourierFTLayer.update_layerc                 C   s(   || j  v rtj| j |  d S d S N)r	   keysr   initzeros_)r    r3   r!   r!   r"   r/   S   s   z'FourierFTLayer.reset_fourier_parametersc                 C   s~   | j | }| j| |j}tj| j| j|jd}| ||dd d f |dd d f f< tj	
|j| j|  }||jS )N)devicer      )r	   r   tor=   r(   zerosr   r   floatfftifft2realr   dtype)r    adapterspectrumr   dense_spectrumdelta_weightr!   r!   r"   get_delta_weightX   s   
(zFourierFTLayer.get_delta_weight)F)__name__
__module____qualname__adapter_layer_namesother_param_namesr   Moduler#   boolr8   r(   no_gradr/   TensorrJ   r!   r!   r!   r"   r      s    

r   c                       s   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dZddede	e
e  ddfddZd ddZdejf fddZdejdededejfddZdef fddZ  ZS )!FourierFTLinear       b@F	  r3   r4   r5   fan_in_fan_outr6   r7   r   Nc           	         s@   t    tj| |fi | || _|| _| ||||| d S r9   )superr#   r   rX   _active_adapterr8   )	r    r   r3   r4   r5   rX   r6   r7   r   	__class__r!   r"   r#   d   s
   
zFourierFTLinear.__init__
safe_mergeadapter_namesc                 C   s   t | |}|s	dS |D ]A}|| j v rL|  }|r;|jj }|| |7 }t	|
 s6td| d||j_n|j j| |7  _| j| qdS )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clonerJ   r(   isfiniteallr   r   append)r    r]   r^   active_adapterr   orig_weightsr!   r!   r"   mergeu   s$   


zFourierFTLinear.mergec                 C   sj   | j s
td dS t| jdkr3| j }|| j v r*|  j	 j
| |8  _
t| jdksdS dS )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   r_   rJ   )r    rd   r!   r!   r"   unmerge   s   

zFourierFTLinear.unmergec                    s   t  |S r9   )rY   rJ   )r    rF   r[   r!   r"   rJ      s   z FourierFTLinear.get_delta_weightxargsr   c                 O   s   |j }| jr| jr|   | j|g|R i |}n=| jr*| j|g|R i |}n-| j|g|R i |}| jD ]}|| j vrCq9| |}|	|j }|t
|| }q9|	|}|S r9   )rE   disable_adaptersrg   rl   r   r2   r	   r:   rJ   r?   Flinear)r    rm   rn   r   previous_dtyperesultrd   delta_wr!   r!   r"   forward   s    


zFourierFTLinear.forwardc                    s   t   }d| S )Nz
fourierft.)rY   __repr__)r    repr[   r!   r"   rv      s   
zFourierFTLinear.__repr__)rU   rV   FFrW   )FN)r   N)rK   rL   rM   strintrA   rQ   r   r#   r   listrf   rl   r(   rS   rJ   r   ru   rv   __classcell__r!   r!   r[   r"   rT   b   s4    

 
%rT   )rh   typingr   r   r   r(   torch.nnr   torch.nn.functional
functionalrp   transformers.pytorch_utilsr   peft.tuners.tuners_utilsr   r   r   rP   rT   r!   r!   r!   r"   <module>   s   H