o
    8wi!                     @   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                   @   sP   e Zd ZdZdZdejddfddZ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!   X/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/peft/tuners/fourierft/layer.py__init__    s    
zFourierFTLayer.__init__c                 C   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 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   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"   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    r2   r!   r!   r"   r.   Q   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_weightV   s   
(zFourierFTLayer.get_delta_weight)__name__
__module____qualname__adapter_layer_namesother_param_namesr   Moduler#   r7   r'   no_gradr.   TensorrI   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	  r2   r3   r4   fan_in_fan_outr5   r6   r   Nc           	         s@   t    tj| |fi | || _|| _| ||||| d S r8   )superr#   r   rV   _active_adapterr7   )	r    r   r2   r3   r4   rV   r5   r6   r   	__class__r!   r"   r#   b   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	   r9   r   r   dataclonerI   r'   isfiniteallr   r   append)r    r[   r\   active_adapterr   orig_weightsr!   r!   r"   merges   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	   r9   r   r   r]   rI   )r    rb   r!   r!   r"   unmerge   s   

zFourierFTLinear.unmergec                    s   t  |S r8   )rW   rI   )r    rE   rY   r!   r"   rI      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 r8   )rD   disable_adaptersre   rj   r   r1   r	   r9   rI   r>   Flinear)r    rk   rl   r   previous_dtyperesultrb   delta_wr!   r!   r"   forward   s    


zFourierFTLinear.forwardc                    s   t   }d| S )Nz
fourierft.)rW   __repr__)r    reprY   r!   r"   rt      s   
zFourierFTLinear.__repr__)rS   rT   FFrU   )FN)r   N)rJ   rK   rL   strintr@   boolr   r#   r   listrd   rj   r'   rQ   rI   r   rs   rt   __classcell__r!   r!   rY   r"   rR   `   s4    

 
%rR   )rf   typingr   r   r   r'   torch.nnr   torch.nn.functional
functionalrn   transformers.pytorch_utilsr   peft.tuners.tuners_utilsr   r   r   rO   rR   r!   r!   r!   r"   <module>   s   F