o
    8wÖiy¥  ã                   @  sü   d dl mZ d dlZd dlZd dlZd dlm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 daedd„ ƒZd	d
„ ZG dd„ deƒZG dd„ dejƒZG dd„ deƒZG dd„ dejeƒZG dd„ dejeƒZdS )é    )ÚannotationsN)Úcontextmanager)ÚAnyÚOptionalÚUnion)ÚFunction)ÚBaseTunerLayerÚcheck_adapters_to_mergec                  k  sˆ    i }|   ¡ D ]\}}| ¡ }|tjv rtj| ||< t|ƒtj|< qdV  | D ]}| ¡ }||v r:|| tj|< q(tj |d¡ q(dS )aÈ  
    A context manager that will add each keyword argument passed to `os.environ` and remove them when exiting.

    Will convert the values in `kwargs` to strings and upper-case all the keys.

    Example:

    ```python
    >>> import os
    >>> from accelerate.utils import patch_environment

    >>> with patch_environment(FOO="bar"):
    ...     print(os.environ["FOO"])  # prints "bar"
    >>> print(os.environ["FOO"])  # raises KeyError
    ```
    N)ÚitemsÚupperÚosÚenvironÚstrÚpop)ÚkwargsÚexisting_varsÚkeyÚvalue© r   úS/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/peft/tuners/boft/layer.pyÚpatch_environment&   s   €
úr   c               
   C  sÎ   t d urt S ddlm}  tj t¡}z/tddd | d|› d|› dgdd	}W d   ƒ n1 s3w   Y  W |a t S W |a t S  tyf } zt	 
d
|› d¡ t	 
d¡ d }W Y d }~|a t S d }~ww )Nr   )ÚloadÚgcc)ÚCCÚCXXÚfbd_cudaz/fbd/fbd_cuda.cppz/fbd/fbd_cuda_kernel.cuT)ÚnameÚsourcesÚverbosez#Failed to load the CUDA extension: z, check if ninja is available.zHSetting boft_n_butterfly_factor to 1 to speed up the finetuning process.)Ú	_FBD_CUDAÚtorch.utils.cpp_extensionr   r   ÚpathÚdirnameÚ__file__r   Ú	ExceptionÚwarningsÚwarn)r   Úcurr_dirr   Úer   r   r   Úget_fbd_cudaJ   s2   ýÿòú
€úr)   c                   @  s(   e Zd ZdZedd„ ƒZedd„ ƒZdS )ÚFastBlockDiaga  
    Implements a custom autograd Function for a fast block diagonal operation using CUDA.

    This function is optimized for 4D tensors where the last two dimensions are equal, representing block diagonal
    matrices for efficient computation on CUDA devices.
    c                 C  s   t ƒ  |¡d }|  |¡ |S )a|  
        The forward method for FastBlockDiag.

        Computes the block diagonal operation on the input tensor using a CUDA-optimized function. This method assumes
        that the input is a 4D tensor where the last two dimensions are equal, which represent the blocks to be
        diagonalized.

        Parameters:
        ctx: A context object that can be used to stash information for backward computation.
        input (Tensor): The input tensor of shape (N, D, H, H), where `N` is the batch size,
                        `D` represents one additional dimension (In BOFT, the number of BOFT blocks), and `H` is the
                        size of the square blocks along the last two dimensions (In BOFT, the block size).

        Returns:
        Tensor: The resulting tensor after applying the block diagonal operation,
                will have the shape (N, DxH, DxH).
        r   )r)   ÚforwardÚsave_for_backward)ÚctxÚinputÚoutputr   r   r   r+   o   s   
zFastBlockDiag.forwardc                 C  s   | j \}tƒ  ||¡d }|S )Nr   )Úsaved_tensorsr)   Úbackward)r-   Úgrad_outputr.   Ú
grad_inputr   r   r   r1   †   s   zFastBlockDiag.backwardN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Ústaticmethodr+   r1   r   r   r   r   r*   g   s    
r*   c                      s*   e Zd ZdZd‡ fdd„	Zdd„ Z‡  ZS )ÚMultiplicativeDropoutLayerz?
    Implements the multiplicative dropout layer for BOFT.
    ç        c                   s   t ƒ  ¡  || _dS )z¡
        Initializes the multiplicative dropout layer.

        Parameters:
        p (float): The probability of dropping out a block. Defaults to 0.0.
        N)ÚsuperÚ__init__Úp)Úselfr=   ©Ú	__class__r   r   r<   ’   s   

z#MultiplicativeDropoutLayer.__init__c                 C  sê   | j rs|jd |jd krtdƒ‚|j\}}}}t d|d¡ ¡ }t| j| ƒ}|| }t tj	||j
dtj||j
dg¡}	|	t |¡  d|dd¡}	tj||dd|j
d}
|	|
|< tj||j
d ||dd¡}d|
 | |
|  }|S )a‹  
        Applies multiplicative dropout to the input tensor.

        Parameters:
        x (Tensor): The input tensor of shape (N, D, H, H), where `N` is the batch size, `D` represents
                    one additional dimension (In BOFT, the number of BOFT blocks), and `H` is the size of the square
                    blocks along the last two dimensions (In BOFT, the block size).
        éÿÿÿÿéþÿÿÿz4The last two dimensions of input should be the same!r   )é   ©ÚdevicerC   )ÚtrainingÚshapeÚ
ValueErrorÚtorchÚrandintÚitemÚintr=   ÚcatÚonesrE   ÚzerosÚrandpermÚviewÚeyeÚrepeat)r>   ÚxÚNÚDÚHÚ_Ún_randomÚnum_to_replaceÚ	num_zerosÚmaskÚ	full_maskÚ
eye_matrixr   r   r   r+   œ   s   	&z"MultiplicativeDropoutLayer.forward)r:   )r4   r5   r6   r7   r<   r+   Ú__classcell__r   r   r?   r   r9      s    
r9   c                   @  sj   e Zd ZdZdZdZddd	„Zd
d„ Zd dd„Zd!d"dd„Z	dd„ Z
dd„ Zdd„ Zd#dd„Zdd„ ZdS )$Ú	BOFTLayerz$
    Implements the BOFT layer.
    )Úboft_RÚboft_s)Úboft_block_sizeÚboft_block_numÚboft_dropoutÚ
base_layerú	nn.ModuleÚreturnÚNonec                 K  s°   || _ i | _i | _t i ¡| _t i ¡| _t i ¡| _d| _	g | _
d| _|| _|  ¡ }t|tjƒr9|j|j}}nt|tjƒrG|j|j}}n	tdt|ƒ› ƒ‚|| _|| _dS )zý
        Initializes the BOFT layer.

        Note, currently only support linear layer and convolutional layer, with further support for other layers to be
        added soon.

        Parameters:
        base_layer: the pretrained model layer
        FTzUnsupported layer type N)rf   rc   rd   ÚnnÚ
ModuleDictre   ÚParameterDictra   rb   Ú_disable_adaptersÚmerged_adaptersÚcast_input_dtype_enabledr   Úget_base_layerÚ
isinstanceÚLinearÚin_featuresÚout_featuresÚConv2dÚin_channelsÚout_channelsrH   Útype)r>   rf   r   rs   rt   r   r   r   r<   Ì   s$   

zBOFTLayer.__init__c                 C  s   || j vrd S t d¡ d S )NúGScaling operation for BOFT not supported! Automatically set scale to 1.)Úscalingr%   r&   )r>   ÚadapterÚscaler   r   r   Ú	set_scaleï   s   
zBOFTLayer.set_scaler|   Úfloatc                 C  s6   |dkrd S | j D ]}|| j ¡ vrq	t d¡ q	d S )NrC   ry   ©Úactive_adaptersra   Úkeysr%   r&   ©r>   r|   Úactive_adapterr   r   r   Úscale_layerö   s   
üzBOFTLayer.scale_layerNc                 C  s*   | j D ]}|| j ¡ vrqt d¡ qd S )Nz?Unscaling operation for BOFT not supported! Keeping scale to 1.r   r‚   r   r   r   Úunscale_layer   s
   
üzBOFTLayer.unscale_layerc                 C  s  t ƒ s	d| _d}nd| _|d }|dk rtd|d › dƒ‚|dkr(t|d}nt ¡ }| j t ||i¡¡ |dkr‰|dkr‰| j	| dkrRtd	| j	› d
|› dƒ‚|dkr|t
t |¡ƒkrltd|d › d|› dƒ‚|d|  dkrtd|› d|d › dƒ‚t
| j	| ƒ}na|dkræ|dkræ| j	| dkr¤td	| j	› d|› dƒ‚|dkrÞ| j	|d|  k rÂtd| j	› d|d › d|› dƒ‚| j	|d|   dkrÞtd| j	› d|d › d|› dƒ‚t
| j	| ƒ}ntdƒ‚|dkr|d dkrýtd|› dƒ‚|d dkrtd|› dƒ‚t |d | j	| j	f¡}t|d ƒD ]}	|  | j	t
|d|	  ƒt
|d ƒ|¡}
|  |
¡}|||	< q| jd|dd t t |d |||¡¡| j|< t t t
| jƒd¡¡| j|< |  ||¡ || j|< || j|< |  |¡ |  | j¡ dS )zf
        Update the linear layer with trainable BOFT weights. Override for other layer types.
        FrC   Tr   ú-You can only specify boft_n_butterfly_factor ú! to be a positive integer number.r:   ©r=   zin_features (ú') must be divisible by boft_block_num (ú)!ú0Invalid combination of boft_n_butterfly_factor (ú) and boft_block_num (é   úboft_block_num (úJ) must be a multiple of 2 raised to the power of boft_n_butterfly_factor (ú() must be divisible by boft_block_size (z$Invalid combination of in_features (ú), boft_n_butterfly_factor (ú) and boft_block_size (úZSomething went wrong, please report this error: https://github.com/huggingface/peft/issuesú) must be an even number!úboft_block_size (Úboft_P©Ú
persistentN)r)   Úfbd_cuda_availablerH   r9   rj   ÚIdentityre   Úupdaterk   rs   rL   ÚmathÚlog2rI   ÚemptyÚrangeÚblock_butterfly_permÚperm2matÚregister_bufferÚ	ParameterrO   ra   rN   rt   rb   Úreset_boft_parametersrc   rd   Ú%_move_adapter_to_device_of_base_layerÚset_adapterr€   )r>   Úadapter_namerc   rd   Úboft_n_butterfly_factorre   Úinit_weightsÚboft_dropout_layerÚPÚiÚpermÚperm_matr   r   r   Úupdate_layer  sˆ   ÿÿÿÿÿÿÿÿ
ÿ

ÿ


zBOFTLayer.update_layerc                 C  sŒ   |du rt jj| j| ddd t jj| j| ddd dS || j ¡ v rD|du r=t j | j| ¡ t j | j| ¡ dS td|›ƒ‚dS )	z,
        Reset the BOFT parameters.
        Fr:   çš™™™™™¹?)ÚmeanÚstdg      ð?NTz$Unknown initialization init_weights=)	rj   ÚinitÚnormal_ra   rb   r   Úzeros_Úones_rH   )r>   r§   r©   r   r   r   r¤   m  s   úzBOFTLayer.reset_boft_parametersc                 C  s8   t |ƒ}t ||f¡}t|ƒD ]
\}}d|||f< q|S )z”
        Convert permutation indices to permutation matrix.

        Args:
        indices: A list of indices representing the permutation.
        rC   )ÚlenrI   rO   Ú	enumerate)r>   ÚindicesÚnr®   r¬   Úidxr   r   r   r¡   ~  s
   zBOFTLayer.perm2maté   rC   c                 C  sŒ   |dkr	t  |¡S || d |krtdƒ‚t|| ƒ}t  |¡}dd„ }|||ƒ}td||ƒD ]}	|	| }
||	|
… }|| ||	|
…< q/|S )a0  
        Define the permutation matrix for the block butterfly permutation.

        Args:
        n: size of the permutation matrix
        b: desired number of blocks after multiplying with the permutation matrix
        r: base block size of the block diagonal matrix, e.g. 2x2, 3x3, 5x5 etc.
        r   r   zInvalid number of blocks!c           
      S  s¢   | | }t  | ¡}t j| t jd}t  d|d¡}t  d|d¡}t j||fdd}t|ƒD ]"\}}	|t|	| ƒt|	| | ƒ… |t|| ƒt|| | ƒ…< q,|S )N)Údtyper   r   rC   )Údim)rI   Úarangerž   ÚlongrM   r¸   rL   )
ÚbÚrÚstepÚinitial_orderÚsorted_orderÚevensÚoddsÚ
sorted_seqr¬   Úposr   r   r   Ú
sort_block¤  s   
>z2BOFTLayer.block_butterfly_perm.<locals>.sort_block)rI   r¿   rH   rL   rŸ   )r>   rº   rÁ   rÂ   Ún_butterfly_factorÚ
block_sizer¹   rÊ   rÅ   r¬   Ú	block_endÚtmp_indicesr   r   r   r    ‘  s   



zBOFTLayer.block_butterfly_permc                 C  s^   |j \}}}d|| dd¡  }tj||jd d¡ |||¡}tjj|| || dd}|S )z³
        Perform the Cayley parametrization on a batch of skew-symmetric matrices.

        Args:
            data: A batch of skew-symmetric matrices of shape (b, r, c).
        g      à?rC   r   rD   r   F)Úleft)	rG   Ú	transposerI   rR   rE   Ú	unsqueezeÚexpandÚlinalgÚsolve)r>   ÚdatarÁ   rÂ   ÚcÚskew_matÚid_matÚQr   r   r   Úcayley_batch¸  s
    zBOFTLayer.cayley_batch)rf   rg   rh   ri   )r|   r~   rh   ri   ©N©rh   ri   )r¼   rC   )r4   r5   r6   r7   Úadapter_layer_namesÚother_param_namesr<   r}   r„   r…   r¯   r¤   r¡   r    rÚ   r   r   r   r   r`   Â   s    
#

f
'r`   c                      sj   e Zd ZdZ							d,d-‡ fdd„Zd.d/dd„Zd0dd„Zd1d!d"„Zd2d(d)„Zd3‡ fd*d+„Z	‡  Z
S )4rr   z,
    BOFT implemented in a dense layer.
    é   r   r°   FTr§   r   rc   rL   rd   r¨   re   r~   Úfan_in_fan_outÚboolr©   úUnion[bool, str]Úis_target_conv_1d_layerrh   ri   c
                   sH   t ƒ  ¡  tj| |fi |
¤Ž || _|| _|  ||||||¡ |	| _d S rÛ   )r;   r<   r`   rà   Ú_active_adapterr¯   rã   )r>   rf   r§   rc   rd   r¨   re   rà   r©   rã   r   r?   r   r   r<   Ï  s   
ÿ
zLinear.__init__NÚ
safe_mergeÚadapter_namesúOptional[list[str]]c           	      C  s:  t | |ƒ}|s	dS |D ]}|| j ¡ v rš|  ¡ }|jj}|ra|jj ¡ }|  |¡\}}t	 
|dd¡}t	 || |j¡¡}t	 
|dd¡}|| }t	 |¡ ¡ sVtd|› dƒ‚| ¡  |¡| jj_n3|  |¡\}}|jj ¡ }t	 
|dd¡}t	 || |j¡¡}t	 
|dd¡}|| }| ¡  |¡| jj_| j |¡ qdS )á^  
        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   rC   z1NaNs detected in the merged weights. The adapter z seems to be broken)r	   ra   r   rp   Úweightr½   rÕ   ÚcloneÚget_delta_weightrI   rÐ   ÚmmÚtoÚisfiniteÚallrH   Ú
contiguousrf   rn   Úappend©	r>   rå   ræ   rƒ   rf   Ú
orig_dtypeÚorig_weightÚbutterfly_oft_matrb   r   r   r   Úmergeç  s:   

ÿ€âzLinear.mergec                 C  sÄ   | j s
t d¡ dS t| jƒdkr`| j ¡ }|  ¡ }|jj}|| j	 
¡ v rW|  |¡\}}|jj ¡ }t |dd¡}t | ¡ | |j¡¡}t |d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   rC   )Úmergedr%   r&   r·   rn   r   rp   ré   r½   ra   r   rë   rÕ   rê   rI   rÐ   rì   Útrí   ©r>   rƒ   rf   ró   rõ   rb   rô   r   r   r   Úunmerge  s   

ôzLinear.unmergeú!tuple[torch.Tensor, torch.Tensor]c                 C  sæ   | j | }| j| }|j\}}}}| || ||¡}|  |¡}| ||||¡}| jr0t |¡}	n| d¡}t	j
t	 |¡Ž }	|	 d¡}	| j |	j¡}
t	 |	|
 ddd¡¡}t	 |
|¡}|d }td|jd ƒD ]}|| | }qf||f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.
        r   r   rC   )ra   rb   rG   rQ   rÚ   r™   r*   ÚapplyÚsqueezerI   Ú
block_diagÚunbindrÑ   r–   rí   rE   ÚbmmÚpermuterŸ   ©r>   r{   ra   rb   rU   rV   rW   rX   Úorth_rotate_butterflyÚblock_diagonal_butterflyr–   Úbutterfly_oft_mat_batchrõ   r¬   r   r   r   rë   /  s$   




zLinear.get_delta_weightrT   útorch.TensorÚargsr   r   c              	   O  sZ  |j }| jr| jr|  ¡  | j|g|¢R i |¤Ž}n| jr+| j|g|¢R i |¤Ž}nûtj| j|j|d}tj	t
| jƒdf|j|d}| jD ]Ž}|| j ¡ vrPqF| j| }	| j| }
| j| }|	j\}}}}|	 || ||¡}	|  |	¡}| ||||¡}||ƒ}| jr‰t |¡}n| d¡}tjt |¡Ž }| d¡}| j |¡}| |¡}t || ddd¡¡}t ||¡}|d }td|jd ƒD ]}|| | }qÃ|| }|
| }qF| |   ¡ j!j"j ¡}|   ¡ j!j"}t #|dd¡}| |¡}| |¡}t $||¡}t #|dd¡}|| }| |¡}| jj%d ur| jj% |¡| j_%t&j'||| jj%d}| |¡}|S )N©rE   r½   rC   r   r   )r.   ré   Úbias)(r½   Údisable_adaptersrø   rû   rf   rI   rR   rs   rE   rN   rL   rt   r€   ra   r   rb   re   rG   rQ   rÚ   r™   r*   rþ   rÿ   r   r  rÑ   r–   rí   r  r  rŸ   rp   ré   rÕ   rÐ   rì   r  ÚFÚlinear)r>   rT   r	  r   Úprevious_dtypeÚresultÚboft_rotationÚ
boft_scalerƒ   ra   rb   ÚdropoutrU   rV   rW   rX   r  r  r–   r  rõ   r¬   rô   Úrotated_weightÚscaled_rotated_weightr   r   r   r+   O  s`   












zLinear.forwardc                   ó   t ƒ  ¡ }d| S ©Nzboft.©r;   Ú__repr__©r>   Úrepr?   r   r   r    ó   
zLinear.__repr__)rß   r   r   r°   FTF)r§   r   rc   rL   rd   rL   r¨   rL   re   r~   rà   rá   r©   râ   rã   rá   rh   ri   ©FN©rå   rá   ræ   rç   rh   ri   rÜ   ©rh   rü   ©rT   r  r	  r   r   r   rh   r  ©rh   r   )r4   r5   r6   r7   r<   rö   rû   rë   r+   r  r_   r   r   r?   r   rr   Ê  s    ö
2

 @rr   c                      sn   e Zd ZdZ					d.d/‡ fdd„Zdd„ Zd0d1dd„Zd2d d!„Zd3d#d$„Zd4d*d+„Z	d5‡ fd,d-„Z
‡  ZS )6ru   z-
    BOFT implemented in a Conv2d layer.
    rß   r   r°   Trf   rg   r§   r   rc   rL   rd   r¨   re   r~   r©   râ   rh   ri   c           	        s4   t ƒ  ¡  t | |¡ || _|  ||||||¡ d S rÛ   )r;   r<   r`   rä   r¯   )	r>   rf   r§   rc   rd   r¨   re   r©   r   r?   r   r   r<   ™  s   
ÿzConv2d.__init__c                 C  s  t ƒ s	d| _d}nd| _|d }|dk rtd|d › dƒ‚|dkr(t|d}nt ¡ }| j t ||i¡¡ |  	¡ }| j
|jd  |jd  }	|dkr—|dkr—|	| dkratd	|	› d
|› dƒ‚|dkr|tt |¡ƒkr{td|d › d|› dƒ‚|d|  dkrtd|› d|d › dƒ‚t|	| ƒ}nZ|dkrí|dkrí|	| dkr°td	|	› d|› dƒ‚|dkræ|	|d|  k rÌtd|	› d|d › d|› dƒ‚|	|d|   dkrætd|	› d|d › d|› dƒ‚t|	| ƒ}ntdƒ‚|dkr|d dkrtd|› dƒ‚|d dkrtd|› dƒ‚t |d |	|	f¡}
t|d ƒD ]}|  |	t|d|  ƒt|d ƒ|¡}|  |¡}||
|< q$| jd|
dd t t |d |||¡¡| j|< t t dt| jƒ¡¡| j|< |  ||¡ || j|< || j|< |  |¡ |  | j ¡ dS )zF
        Update the conv2d layer with trainable BOFT weights.
        FrC   Tr   r†   r‡   r:   rˆ   z Convolutional kernel dimension (r‰   rŠ   r‹   rŒ   r   rŽ   r   r   z7Invalid combination of convolutional kernel dimension (r‘   r’   r“   r”   r•   r–   r—   N)!r)   r™   rH   r9   rj   rš   re   r›   rk   rp   rs   Úkernel_sizerL   rœ   r   rI   rž   rŸ   r    r¡   r¢   r£   rO   ra   rN   rt   rb   r¤   rc   rd   r¥   r¦   r€   )r>   r§   rc   rd   r¨   re   r©   rª   rf   Úconv_filter_dimr«   r¬   r­   r®   r   r   r   r¯   ¬  sŒ   ÿÿÿÿÿÿÿÿ
ÿ

ÿ


zConv2d.update_layerFNrå   rá   ræ   rç   c           	      C  s¤  t | |ƒ}|s	dS |D ]Ä}|| j ¡ v rÏ|  ¡ }|jj}|rt|jj ¡ }|  |¡\}}| 	| j
| j|jd  |jd  ¡}t |dd¡}t || |j¡¡}t |dd¡}|| }| 	| j
| j|jd |jd ¡}| ¡  |¡| jj_nU|  |¡\}}|jj ¡ }| 	| j
| j|jd  |jd  ¡}t |dd¡}t || |j¡¡}t |dd¡}|| }| 	| j
| j|jd |jd ¡}| ¡  |¡| jj_| j |¡ qdS )rè   Nr   rC   )r	   ra   r   rp   ré   r½   rÕ   rê   rë   rQ   rt   rs   r"  rI   rÐ   rì   rí   rð   rf   rn   rñ   rò   r   r   r   rö     sJ   
ÿÿÿÿ€ÙzConv2d.mergec                 C  s  | j s
t d¡ dS t| jƒdkr„| j ¡ }|  ¡ }|jj}|| j	 
¡ v r{|  |¡\}}|jj ¡ }| | j| j|jd  |jd  ¡}t |dd¡}t | ¡ | |j¡¡}t |dd¡}|d|  }| | j| j|jd |jd ¡}| |¡|j_t| jƒdksdS dS r÷   )rø   r%   r&   r·   rn   r   rp   ré   r½   ra   r   rë   rÕ   rê   rQ   rt   rs   r"  rI   rÐ   rì   rù   rí   rú   r   r   r   rû   S  s4   

þüézConv2d.unmergerü   c                 C  sî   | j | }| j|  dd¡}|j\}}}}| || ||¡}|  |¡}| ||||¡}| jr4t |¡}	n| 	d¡}t
jt
 |¡Ž }	|	 d¡}	| j |	j¡}
t
 |	|
 ddd¡¡}t
 |
|¡}|d }td|jd ƒD ]}|| | }qj||fS )rý   r   rC   r   )ra   rb   rÐ   rG   rQ   rÚ   r™   r*   rþ   rÿ   rI   r   r  rÑ   r–   rí   rE   r  r  rŸ   r  r   r   r   rë   s  s$   
	


zConv2d.get_delta_weightrT   r  r	  r   r   c              	   O  sº  |j }| jr| jr|  ¡  | j|g|¢R i |¤Ž}n;| jr,| j|g|¢R i |¤Ž}n*tj| j| jjd  | jjd  |j	|j d}tj
t| jƒdf|j	|j d}| jD ]’}|| j ¡ vr_qU| j| }	| j|  dd¡}
| j| }|	j\}}}}|	 || ||¡}	|  |	¡}| ||||¡}||ƒ}| jrœt |¡}n| d¡}tjt |¡Ž }| d¡}| j |¡}| |¡}t ||  ddd¡¡}t ||¡}|d }t!d|jd ƒD ]}|| | }qÖ|| }|
| }qU| | jj"j#j ¡}| jj"j#}| | j| j| jjd  | jjd  ¡}t |dd¡}t $||¡}t |dd¡}|| }| | j| j| jjd | jjd ¡}|  %||j ¡}|  %| jj&|j ¡}t'j(|||| jj)d | jj*d d}| |¡}|S )Nr   r
  rC   r   )r.   ré   r  ÚpaddingÚstride)+r½   r  rø   rû   rf   rI   rR   rs   r"  rE   rN   rL   rt   r€   ra   r   rb   rÐ   re   rG   rQ   rÚ   r™   r*   rþ   rÿ   r   r  rÑ   r–   rí   r  r  rŸ   ré   rÕ   rì   Ú_cast_input_dtyper  r  Úconv2dr$  r%  )r>   rT   r	  r   r  r  r  r  rƒ   ra   rb   r  rU   rV   rW   rX   r  r  r–   r  rõ   r¬   rô   r  r  r  r   r   r   r+   ”  s|   ý








þÿ

û
zConv2d.forwardc                   r  r  r  r  r?   r   r   r  á  r  zConv2d.__repr__)rß   r   r   r°   T)rf   rg   r§   r   rc   rL   rd   rL   r¨   rL   re   r~   r©   râ   rh   ri   r  r  rÜ   r  r   r!  )r4   r5   r6   r7   r<   r¯   rö   rû   rë   r+   r  r_   r   r   r?   r   ru   ”  s    øl
;
 
!Mru   )Ú
__future__r   rœ   r   r%   Ú
contextlibr   Útypingr   r   r   rI   Útorch.nnrj   Útorch.nn.functionalÚ
functionalr  Útorch.autogradr   Úpeft.tuners.tuners_utilsr   r	   r   r   r)   r*   ÚModuler9   r`   rr   ru   r   r   r   r   Ú<module>   s.   
#&5  
 K