o
    8wiM:                     @   s   d dl Z 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mZ G dd deZG dd dejeZdS )    N)AnyOptionalUnion)BaseTunerLayercheck_adapters_to_mergec                   @   s   e Zd ZdZdZdejddfddZded	e	d
e
ddfddZdefddZdefddZdefddZdeddfddZddddZdS )	BoneLayer)
bone_block)bone_r
base_layerreturnNc                 K   sl   || _ i | _ti | _d| _g | _d| _|| _| 	 }t
|tjr-|j|j| _| _d S tdt| )NFTzUnsupported layer type )r
   r	   nnParameterDictr   _disable_adaptersmerged_adapterscast_input_dtype_enabledkwargsget_base_layer
isinstanceLinearin_featuresout_features
ValueErrortype)selfr
   r    r   S/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/peft/tuners/bone/layer.py__init__   s   zBoneLayer.__init__adapter_namerinit_weightsc                 K   s   |dkrt d| || j|< |  }t|tjr*tjt|| j	dd| j
|< n
tdt|j |dkrQ| j| dksF| j	| dkrJt d| || n|rZ| || n| | | | | | j dS )	zInternal function to create bone adapter

        Args:
            adapter_name (`str`): Name for the adapter to add.
            r (`int`): Rank for the added adapter.
            init_weights (`bool`): Whether to initialize weights.
        r   z?`r` should be a positive integer value but the value passed is Trequires_gradz0Bone is not implemented for base layers of type batz=The weight matrix must be fully divisible into [r, r] blocks.N)r   r	   r   r   r   r   	Parametertorchzerosr   r   	TypeErrorr   __name__r   reset_bat_parametersreset_bone_parametersreset_bone_parameters_random%_move_adapter_to_device_of_base_layerset_adapteractive_adapters)r   r   r   r   r   r
   r   r   r   update_layer0   s    
 

zBoneLayer.update_layerc                 C   s"   t jt|| jdd| j|< d S NTr    r   r#   r$   r%   r   r   r   r   r   r   r   r   r)   X   s   "zBoneLayer.reset_bone_parametersc                 C   s(   t jt| j| ||dd| j|< d S r/   r0   r1   r   r   r   r(   [   s   (zBoneLayer.reset_bat_parametersc                 C   s    t jj| j| tdd d S )N   )a)r   initkaiming_uniform_r   mathsqrt)r   r   r   r   r   r*   ^   s    z&BoneLayer.reset_bone_parameters_randomscalec                 C   s6   |dkrd S | j D ]}|| j vrq	td q	d S )N   zGScaling operation for Bone not supported! Automatically set scale to 1.r-   r   keyswarningswarnr   r8   active_adapterr   r   r   scale_layera   s   
zBoneLayer.scale_layerc                 C   s*   | j D ]}|| j vrqtd qd S )Nz?Unscaling operation for Bone not supported! Keeping scale at 1.r:   r>   r   r   r   unscale_layerk   s
   
zBoneLayer.unscale_layerNr   N)r'   
__module____qualname__adapter_layer_namesother_param_namesr   Moduler   strintboolr.   r)   r(   r*   floatr@   rA   r   r   r   r   r      s$    
(
r   c                	       s   e Zd ZdZ		ddededeeef 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!dedejfddZd!dedej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 )"
BoneLinearz,
    Bone implemented in a dense layer.
    r   Tr   r   r   r   Nc                    sD   t    tj| |fi | || _| j|||fi | || _d S rB   )superr   r   _active_adapterr.   bone_fn)r   r
   r   r   r   r   	__class__r   r   r   x   s
   

zBoneLinear.__init__F
safe_mergeadapter_namesc                 C   s  t | |}|s	dS |D ]{}|| j v r|  }|jj}|rV|jj }| jdkr4| 	||}||7 }n| 
|| jjj}|}t| sNtd| d|||j_n*| jdkrp| 	|| jjj}|j j||7  _n| 
|| jjj}|||j_| j| qdS )ab  
        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`.
        Nr"   z1NaNs detected in the merged weights. The adapter z seems to be broken)r   r   r;   r   weightdtypedataclonerP   get_delta_weightget_delta_weight_boner
   r$   isfiniteallr   tor   append)r   rS   rT   r?   r
   
orig_dtypeorig_weightdelta_weightr   r   r   merge   s6   




zBoneLinear.mergec                 C   s   | j s
td dS t| jdkrS| j }|  }|jj}|| j	
 v rJ|  jj }| jdkr;| j||dd}n| j||dd}|||j_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   r"   T)re)mergedr<   r=   lenr   popr   rU   rV   r   r;   rW   rX   rP   rY   rZ   r]   )r   r?   r
   r_   r`   ra   r   r   r   unmerge   s   


zBoneLinear.unmergerc   c                 C   sd  | j | j}| j | j}|jdko|tjkp|tjk}| j | }|r&| }||j}|	d}|rw|
|	d| ||	d| |dddd}	t|	d|j}
t|
| }||j}|	| | }|ddddj
|j }n(|
|	d| ||	d| |dddd| | }|ddddj
|j }|r|j|d}||| j | _|S )
        Compute the delta weight for the given adapter.

        Args:
            adapter (str):
                The name of the adapter for which the delta weight should be computed.
        cpur   r9         rV   )r   devicerV   r   r$   float16bfloat16rL   r]   sizereshapepermuteeyeinverseshaperW   )r   adapterr`   rc   rn   rV   cast_to_fp32weight_boner   ooneinv_I_plus_bwoutput_tensorr   r   r   rY      s4   

0.zBoneLinear.get_delta_weightc                 C   st  | j | j}| j | j}|jdko|tjkp|tjk}| j | }|r&| }|d}|d}	||	 dkr||	 }
||	 }||	 }|r|ddd|f 	d||	
ddd| 
dddj	|ddd|f j |ddd|f< |dd|df |ddddd|
f  |dd|df< nO|ddd|f 	d||	
ddd| 
dddj	|ddd|f j |ddd|f< |dd|df |ddddd|
f  |dd|df< |}n@|r|	d|d|	 |	
ddd| }|
dddj	|j }n|	d|d|	 |	
ddd| }|
dddj	|j }|r8|j|d}||| j | _|S )rh   ri   rj   r   Nr9   rk   rm   )r   rn   rV   r   r$   ro   rp   rL   rq   rr   rs   rv   	transposer]   rW   )r   rw   r`   rc   rn   rV   rx   ry   r   r   	last_sizen_blockn_block_sizer~   r}   r   r   r   rZ      sJ   


*
.*
.&&z BoneLinear.get_delta_weight_bonexargsr   c                 O   s  |j }| jr| jr|   | j|g|R i |}n| jr*| j|g|R i |}n| jdkrg| jjj }| j	D ]}|| j
 vrCq9| ||}|| }q9| ||j }| | jj|j }	tj|||	d}nf| j|g|R i |}| j	D ]V}|| j
 vrqv| j
| }
|
d}|d| dkr||d|  | }t|d|f}| ||
j }|tj|jg |jd d |d| |R  dd|
  }qv||}|S )Nr"   )inputrU   biasr   rj   )dim)rV   disable_adaptersrd   rg   r
   rP   rU   rW   rX   r-   r   r;   rY   _cast_input_dtyper   Flinearrq   padr$   sumrr   rv   r]   )r   r   r   r   previous_dtyperesultr`   r?   ra   r   boner   padding_sizer   r   r   forward8  s<   





@
zBoneLinear.forwardc                    s   t   }d| S )Nzbone.)rN   __repr__)r   reprQ   r   r   r   ]  s   
zBoneLinear.__repr__)r   T)FNrC   )F)r'   rD   rE   __doc__rI   rJ   r   rK   r   r   listrb   rg   r$   TensorrY   rZ   r   r   r   __classcell__r   r   rQ   r   rM   s   s&    
 
0.?%rM   )r6   r<   typingr   r   r   r$   torch.nnr   torch.nn.functional
functionalr   peft.tuners.tuners_utilsr   r   r   rH   rM   r   r   r   r   <module>   s   Z