o
    Nis,                     @  s   d dl mZ d dlZd dlmZ d dl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 ddlmZmZ G d	d
 d
eZG dd de
jeZdddZdS )    )annotationsN)partial)AnyOptional)
BufferDict)BaseTunerLayer   )decompose_weight_matrixreconstruct_weight_matrixc                   @  st   e Zd ZU dZded< dZded< d%d
dZd&ddZd'ddZdd Z	d(ddZ
d)d*dd Zd+d!d"Zd#d$ ZdS ),OSFLayer)osf_svd_paramsztuple[str, ...]adapter_layer_names)_osf_U_high_osf_S_high_osf_V_highother_param_names
base_layer	nn.ModulereturnNonec                 K  s:  || _ i | _ti | _ti | _ti | _ti | _g | _	d| _
g | _|  }t|drAt|jtjrA|jjdkrA|jj\}}nTt|tjrO|j|j}}nFt|drat|dra|j|j}}n4t|drst|drs|j|j}}n"t|drt|d	r|j|j}}nd
\}}tdt| dt || _|| _d S )NFweight   
infeaturesoutfeatures
input_sizeoutput_sizein_featuresout_features)NNzUnsupported layer type 'z/' encountered; could not infer in/out features.)r   effective_ranknn
ModuleDictr   r   r   r   r   hook_handles_disable_adaptersmerged_adaptersget_base_layerhasattr
isinstancer   torchTensorndimshapeLinearr   r   r   r   r   r   warningswarntypeUserWarning)selfr   kwargsr   r    r2   I/home/ubuntu/.local/lib/python3.10/site-packages/peft/tuners/osf/layer.py__init__'   s>   



zOSFLayer.__init__adapter_namestrr   intc                 K  s   |dkrt d| || j|< |  }|jj}t||d}|d | j|< |d | j|< |d | j|< t	
|d |d |d	 d
}|| j|< | | | | j dS )z&Update layer to add a new OSF adapter.r   zL`effective_rank` should be a positive integer value but the value passed is )top_kU_highS_highV_highU_lowS_lowV_low)r<   r=   r>   N)
ValueErrorr   r$   r   datar	   r   r   r   r   ParameterDictr   _attach_hooksset_adapteractive_adapters)r0   r5   r   r1   r   r   svd_dict
svd_paramsr2   r2   r3   update_layerT   s(   


zOSFLayer.update_layerc                 C  sj   || j vrdS | j | }ddd}|d	 t|d	|| d
}|d t|d|| d
}| j||g dS )z,Attach gradient hooks for the given adapter.Nnamer6   adapterlayerr   c                 S  s`   |dkr|j | }||dd|   }| | S |dkr.|j| }| |dd | }| | S | S )Nr<   r   r   r>   )r   	transposer   )gradrH   rI   rJ   r9   projr;   r2   r2   r3   hook   s   

z$OSFLayer._attach_hooks.<locals>.hookr<   )rH   rI   rJ   r>   )rH   r6   rI   r6   rJ   r   )r   register_hookr   r!   extend)r0   r5   
svd_modulerN   handle_uhandle_vr2   r2   r3   rB   x   s   


zOSFLayer._attach_hooksc                 C  s"   | j D ]}|  q| j   dS )zRemove all gradient hooks.N)r!   removeclear)r0   handler2   r2   r3   _detach_hooks   s   

zOSFLayer._detach_hookstorch.Tensorc                 C  sV   || j vr
|  jS | j | }| j| | j| | j| |d |d |d d}t|S )z@Reconstruct weight matrix from SVD components for given adapter.r<   r=   r>   )r9   r:   r;   r<   r=   r>   )r   r$   r   r   r   r   r
   )r0   r5   rQ   rE   r2   r2   r3   _reconstruct_weight   s   


zOSFLayer._reconstruct_weightFN
safe_mergebooladapter_namesOptional[list[str]]c                 C  s   |du r| j }|D ]A}|| j v rJ|  }|r;|jj }| |}t	|
 s2td| d||j|j_n	| |}||j_| 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)rD   r   keysr$   r   r@   clonerY   r'   isfiniteallr?   todtyper#   append)r0   rZ   r\   active_adapterr   orig_weight
new_weightr2   r2   r3   merge   s$   


zOSFLayer.mergec                 C  s"   | j s
td dS td dS )zW
        This method unmerges all merged adapter layers from the base weights.
        z Already unmerged. Nothing to do.NzJOSF does not support unmerging. Original weights are permanently modified.)mergedr,   r-   r0   r2   r2   r3   unmerge   s   
zOSFLayer.unmergec                 C  s   |    dS )zCleanup hooks on deletion.N)rW   rj   r2   r2   r3   __del__   s   zOSFLayer.__del__)r   r   r   r   )r5   r6   r   r7   )r5   r6   )r5   r6   r   rX   )FN)rZ   r[   r\   r]   r   r   )r   r   )__name__
__module____qualname__r   __annotations__r   r4   rG   rB   rW   rY   rh   rk   rl   r2   r2   r2   r3   r   !   s   
 

-
$

%r   c                      s:   e Zd Z	dd fdd	ZdddZd fddZ  ZS )r+   Nr5   r6   r   r7   r   r   c                   sV   t    tj| |fi | |d u rt| j| jd }|| _| j||fi | d S )Nr   )superr4   r   minr   r   _active_adapterrG   )r0   r   r5   r   r1   	__class__r2   r3   r4      s   
zLinear.__init__xrX   argsr   r1   c           	      O  s   | j r| j|g|R i |}|S | jr"| j|g|R i |}|S |  }|j}| jr1| jd nd }|rH|| jv rH| |}t	|||}|S | j|g|R i |}|S )Nr   )
disable_adaptersr   ri   r$   biasrD   r   rY   Flinear)	r0   rv   rw   r1   resultr   ry   re   r   r2   r2   r3   forward   s   
zLinear.forwardc                   s   t   }d| S )Nzosf.)rq   __repr__)r0   reprt   r2   r3   r~     s   
zLinear.__repr__N)r5   r6   r   r7   r   r   )rv   rX   rw   r   r1   r   r   rX   )r   r6   )rm   rn   ro   r4   r}   r~   __classcell__r2   r2   rt   r3   r+      s
    
r+   targettorch.nn.Moduler5   r6   r   Optional[torch.nn.Module]c                 K  s@   d }t | tr|  }n| }t |tjjrt| |fi |}|S r   )r&   r   r$   r'   r   r+   )r   r5   
osf_configr1   
new_moduletarget_base_layerr2   r2   r3   dispatch_default  s   

r   )r   r   r5   r6   r   r   )
__future__r   r,   	functoolsr   typingr   r   r'   torch.nnr   torch.nn.functional
functionalrz   peft.tuners._buffer_dictr   peft.tuners.tuners_utilsr   utilsr	   r
   r   Moduler+   r   r2   r2   r2   r3   <module>   s    ?-