
    biM:                         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c 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)BaseTunerLayercheck_adapters_to_mergec                       e Zd ZdZdZdej                  ddfdZdede	d	e
ddfd
ZdefdZdefdZdefdZdeddfdZdddZy)	BoneLayer)
bone_block)bone_r
base_layerreturnNc                 T   || _         i | _        t        j                  i       | _        d| _        g | _        d| _        || _        | j                         }t        |t        j                        r$|j                  |j                  c| _        | _        y 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   s      Q/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/peft/tuners/bone/layer.py__init__zBoneLayer.__init__   s    $**2.!&!(,%((*
j")),2<2H2H*JaJa/Dd/6tJ7G6HIJJ    adapter_namerinit_weightsc                    |dk  rt        d|       || j                  |<   | j                         }t        |t        j
                        rCt	        j                  t        j                  || j                        d      | j                  |<   n!t        dt        |      j                         |dk(  rB| j                  |z  dk7  s| j                  |z  dk7  rt        d      | j                  ||       n&|r| j!                  ||       n| j#                  |       | j%                  |       | j'                  | j(                         y)	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   s         r   update_layerzBoneLayer.update_layer0   s'    6^_`^abcc$%L! ((*
j")),,.LLQHYHY9Zjn,oDOOL) NtT^O_OhOhNijkk 5 !#q(D,=,=,AQ,F !`aa%%lA6&&|Q7--l;22<@--.r   c                     t        j                  t        j                  || j                        d      | j
                  |<   y NTr$   r   r'   r(   r)   r   r
   r   r    r!   s      r   r-   zBoneLayer.reset_bone_parametersX   s-    (*U[[DDUDU5Vfj(k%r   c                     t        j                  t        j                  | j                  |z  ||      d      | j
                  |<   y r4   r5   r6   s      r   r,   zBoneLayer.reset_bat_parameters[   s7    (*U[[ARARVWAWYZ\]5^nr(s%r   c                     t         j                  j                  | j                  |   t	        j
                  d             y )N   )a)r   initkaiming_uniform_r
   mathsqrt)r   r    s     r   r.   z&BoneLayer.reset_bone_parameters_random^   s*    
  !>$))A, Or   scalec                     |dk(  ry | j                   D ]4  }|| j                  j                         vr t        j                  d       6 y )N   zGScaling operation for Bone not supported! Automatically set scale to 1.r1   r
   keyswarningswarnr   r?   active_adapters      r   scale_layerzBoneLayer.scale_layera   sH    A:"22 	eNT__%9%9%;;MMcd		er   c                     | j                   D ]4  }|| j                  j                         vr t        j                  d       6 y )Nz?Unscaling operation for Bone not supported! Keeping scale at 1.rB   rF   s      r   unscale_layerzBoneLayer.unscale_layerk   s>    "22 	]NT__%9%9%;;MM[\		]r   Nr   N)r+   
__module____qualname__adapter_layer_namesother_param_namesr   Moduler   strintboolr2   r-   r,   r.   floatrH   rJ    r   r   r	   r	      s    )#K299 K4 K"&/&/ &/ 	&/ 
&/Pl# lt tP Pe e4 e]r   r	   c            	       
    e Zd ZdZ	 	 ddededeeef   ddf fdZdded	e	e
e      ddfd
ZddZddedej                  fdZddedej                  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 )
BoneLinearz,
    Bone implemented in a dense layer.
    r    r!   r"   r   Nc                     t         |           t        j                  | |fi | || _         | j                  |||fi | || _        y rK   )superr   r	   _active_adapterr2   bone_fn)r   r   r    r!   r"   r   	__class__s         r   r   zBoneLinear.__init__x   sM     	46v6+,<B6B#r   
safe_mergeadapter_namesc                    t        | |      }|sy|D ]  }|| j                  j                         v s!| j                         }|j                  j
                  }|r|j                  j                  j                         }| j                  dk(  r| j                  ||      }||z  }n2| j                  || j                  j                  j                        }|}t        j                  |      j                         st        d| d      |j!                  |      |j                  _        n| j                  dk(  r_| j                  || j                  j                  j                        }|j                  xj                  |j!                  |      z  c_        nP| j                  || j                  j                  j                        }|j!                  |      |j                  _        | j"                  j%                  |        y)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
   rC   r   weightdtypedatacloner\   get_delta_weightget_delta_weight_boner   r(   isfiniteallr   tor   append)r   r^   r_   rG   r   
orig_dtypeorig_weightdelta_weights           r   mergezBoneLinear.merge   s    0mD+ 	<N!5!5!77!002
'..44
 #-"3"3"8"8">">"@K||u,'+'<'<^['Y#|3'+'A'A.RVRaRaRhRhRmRm'n&2 >>+6::<(OP^O__rs  .9^^J-GJ%%*||u,'+'<'<^T__McMcMhMh'i"))..,//*2MM.'+'A'A.RVRaRaRhRhRmRm'n1=1L
)).$$++N;9	<r   c                 z   | j                   st        j                  d       yt        | j                        dkD  r | j                  j                         }| j                         }|j                  j                  }|| j                  j                         v r| j                         j                  j                  j                         }| j                  dk(  r| j                  ||d      }n| j                  ||d      }|j!                  |      |j                  _        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   r&   T)re)mergedrD   rE   lenr   popr   ra   rb   r
   rC   rc   rd   r\   re   rf   ri   )r   rG   r   rk   rl   rm   s         r   unmergezBoneLinear.unmerge   s    {{MM<=$&&'!+!11557N,,.J#**00J!5!5!77"113::??EEG<<5(#'#8#8Y]#8#^L#'#=#=nk^b#=#cL)5)D
!!& $&&'!+r   rp   c                    | j                   |   j                  }| j                   |   j                  }|j                  dk(  xr( |t        j
                  k(  xs |t        j                  k(  }| j                   |   }|r|j                         }|j                  |j                        }|j                  d      }|r|j                  |j                  d      |z  ||j                  d      |z  |      j                  dddd      }	t	        j                  |j                  d            j                  |j                        }
t	        j                  |
|z         }|j                  |j                        }|	|z
  |z  } |j                  dddd      j                  |j                   }n{|j                  |j                  d      |z  ||j                  d      |z  |      j                  dddd      |z  |z   } |j                  dddd      j                  |j                   }|r5|j                  |      }|j                  |      | 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   rA         rb   )r
   devicerb   r   r(   float16bfloat16rU   ri   sizereshapepermuteeyeinverseshaperc   )r   adapterrl   rp   r|   rb   cast_to_fp32weight_boner!   ooneinv_I_plus_bwoutput_tensors                 r   re   zBoneLinear.get_delta_weight   s9    )00(.. {{e+c%--1G1b5TYTbTbKboog.%++-K!nn[%6%67R ##K$4$4Q$71$<aAQAQRSATXYAY[\]eefgijlmopqA))K,,R0144[5G5GHC =={):;L'??;+<+<=L[L0A9AIIaAq199;;L;LMM ##K$4$4Q$71$<aAQAQRSATXYAY[\]eefgijlmopq 
 :AIIaAq199;;L;LMM),,5,9M -8NN5,ADOOG$)r   c                    | j                   |   j                  }| j                   |   j                  }|j                  dk(  xr( |t        j
                  k(  xs |t        j                  k(  }| j                   |   }|r|j                         }|j                  d      }|j                  d      }	||	z  dk7  rI||	z  }
||	z  }||	z  }|r |ddd|f   j                  d||	      j                  ddd      |z
  j                  ddd      j                  |ddd|f   j                   |ddd|f<   |dd|df   |j                  dd      ddd|
f   z
  |dd|df<   n |ddd|f   j                  d||	      j                  ddd      |z   j                  ddd      j                  |ddd|f   j                   |ddd|f<   |dd|df   |j                  dd      ddd|
f   z   |dd|df<   |}n|rd|j                  d|j                  d      |	z  |	      j                  ddd      |z
  } |j                  ddd      j                  |j                   }nc|j                  d|j                  d      |	z  |	      j                  ddd      |z   } |j                  ddd      j                  |j                   }|r5|j                  |      }|j                  |      | j                   |   _        |S )rv   rw   rx   r   NrA   ry   r{   )r
   r|   rb   r   r(   r}   r~   rU   r   r   r   r   	transposeri   rc   )r   r   rl   rp   r|   rb   r   r   r   r!   	last_sizen_blockn_block_sizer   r   s                  r   rf   z BoneLinear.get_delta_weight_bone   sS    )00(.. {{e+c%--1G1b5TYTbTbKboog.%++-K!&&r*Q?a#aI!Q&G"Q;L[M\M!12::2wJRRSTVWYZ[^iiWQ1%Wk!]l]*:;AAC A}},-  <= 01[5J5J1a5PRSU_V_U_R_4`` A|},-
[M\M!12::2wJRRSTVWYZ[^iiWQ1%Wk!]l]*:;AAC A}},-  <= 01[5J5J1a5PRSU_V_U_R_4`` A|},- (M ''K,<,<Q,?1,DaHPPQRTUWXY\gg :		!Q 2 : :K<M<M N''K,<,<Q,?1,DaHPPQRTUWXY\gg :		!Q 2 : :K<M<M N),,5,9M -8NN5,ADOOG$)r   xargsr   c           
      
   |j                   }| j                  r4| j                  r| j                           | j                  |g|i |}n%| j                  r | j                  |g|i |}n| j
                  dk(  r| j                  j                  j                  j                         }| j                  D ]6  }|| j                  j                         vr | j                  ||      }||z   }8 | j                  ||j                         }| j                  | j                  j                  |j                         }	t        j                   |||	      }n | j                  |g|i |}| j                  D ]  }|| j                  j                         vr | j                  |   }
|
j#                  d      }|j#                  d      |z  dk7  r2||j#                  d      |z  z
  |z  }t        j$                  |d|f      }| j                  ||
j                         }|t'        j(                   |j*                  g |j,                  d d |j#                  d      |z  | d      |
z  z   } |j/                  |      }|S )Nr&   )inputra   biasr   rx   )dim)rb   disable_adaptersrq   rt   r   r\   ra   rc   rd   r1   r
   rC   re   _cast_input_dtyper   Flinearr   padr(   sumr   r   ri   )r   r   r   r   previous_dtyperesultrl   rG   rm   r   boner!   padding_sizes                r   forwardzBoneLinear.forward8  s@     {{$T__Q888F[[$T__Q888F||u$"oo4499??A&*&:&: =N%T__-A-A-CC #'#8#8#UL"-"<K	= **1k.?.?@--doo.B.BKDUDUV+DI(<T<V<&*&:&: 	mN%T__-A-A-CC ??>:D		!AvvbzA~*()AFF2JN(:a'?EE!a%67..q$**=A#eii			0\1773B<0\PRWX0\Z[0\bd&ehl&llF	m >*r   c                 *    t         |          }d|z   S )Nzbone.)rZ   __repr__)r   repr]   s     r   r   zBoneLinear.__repr__]  s    g }r   )r   T)FNrL   )F)r+   rM   rN   __doc__rR   rS   r   rT   r   r   listrn   rt   r(   Tensorre   rf   r   r   r   __classcell__)r]   s   @r   rX   rX   s   s     )-$ $ 	$
 D#I&$ 
$.< .<Xd3i=P .<\` .<`E*, ,%,, ,\=d =u|| =~# #c #S #U\\ #J#  r   rX   )r=   rD   typingr   r   r   r(   torch.nnr   torch.nn.functional
functionalr   peft.tuners.tuners_utilsr   r   r	   rQ   rX   rV   r   r   <module>r      sG      ' '     LW] W]tlI lr   