
    bi&                     `   d dl Z d dlmZ d dlZd Zdej
                  dedej
                  fdZdej
                  dededej
                  fd	Z		 ddej
                  ded
ed   dedej
                  f
dZ
	 ddej
                  d
ed   dej
                  fdZdej
                  dej
                  dej
                  fdZdeej
                     dej
                  dej
                  fdZdeej
                     dej
                  dedej
                  fdZ	 ddeej
                     dej
                  deded   dej
                  f
dZdeej
                     dej
                  dedej
                  fdZ	 ddeej
                     dej
                  deded   dej
                  f
dZy)    N)Literalc                     |j                   d| j                         |j                         z
  z  z   }|j                  |      }|S )aI  
    Reshapes `weights` to match the shape of `task_tensors` by unsqeezing in the remaining dimenions.

    Args:
        task_tensors (`torch.Tensor`): The tensors that will be used to reshape `weights`.
        weights (`torch.Tensor`): The tensor to be reshaped.

    Returns:
        `torch.Tensor`: The reshaped tensor.
    )   )shapedimview)task_tensorsweights	new_shapes      Q/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/peft/utils/merge_utils.pyreshape_weight_task_tensorsr      s>     (8(8(:W[[](J KKIll9%GN    tensordensityreturnc                 8   t        j                  |       j                  d      }t        || j	                         z        }t        j
                  | j                         j                  d      |d      }d||d   <   | |j                  | j                        z  S )a^  
    Prune the smallest values of the task tensors and retain the top-k values based on the specified fraction
    `density`.

    Args:
        tensor (`torch.Tensor`):The tensor to prune.
        density (`float`):The fraction of values to preserve. Should be in [0,1].

    Returns:
        `torch.Tensor`: The tensor with the pruned weights.
    T)klargestr   )torch
zeros_likereshapeintnumeltopkabsr   )r   r   maskr   top_ks        r   magnitude_based_pruningr   %   s|     F#++B/DGflln$%AJJvzz|++B/1dCEDqNDLL...r   rescalec                     t        j                  t        j                  | |            }| |z  }|rt        j                  ||       |S )a  
    Prune random values based on the specified fraction `density`.

    Args:
        tensor (`torch.Tensor`):The tensor to prune.
        density (`float`):The fraction of values to preserve. Should be in [0,1].
        rescale (`bool`):Whether to rescale the result to preserve the expected value of the original tensor.

    Returns:
        `torch.Tensor`: The pruned tensor.
    )input
fill_value)r"   other)r   	bernoulli	full_likediv)r   r   r    r   pruned_tensors        r   random_pruningr)   8   s=     ??5??GLMDTMM		W5r   method)	magnituderandomc                     |dk\  rt        j                  d| d       | S |dk  rt        d|       |dk(  rt        | |      S |dk(  rt	        | ||      S t        d	|       )
a  
    Prune the values of task tensors based on the `method`.

    Args:
        tensor (`torch.Tensor`):The tensor to prune.
        density (`float`):The fraction of values to preserve. Should be in [0,1].
        method (`str`):The method to use to prune. Should be one of ["magnitude", "random"].
        rescale (`bool`):Whether to rescale the result to preserve the expected value of the original tensor.

    Returns:
        `torch.Tensor`: The pruned tensor.
    r   zThe density z= is greater than or equal to 1, no pruning will be performed.r   zDensity should be >= 0, got r+   r,   )r    zUnknown method )warningswarn
ValueErrorr   r)   )r   r   r*   r    s       r   pruner1   K   s~     !|WI-jkl	17yABB&vw77	8	fgw???6(344r   )total	frequencyc                     | j                         }|dk(  r| j                  d      }n'|dk(  r|j                  d      }nt        d| d      t        j                  |dk\  dd      }||k(  S )	aZ  
    Get the mask of the majority sign across the task tensors. Task tensors are stacked on dimension 0.

    Args:
        tensor (`torch.Tensor`):The tensor to get the mask from.
        method (`str`):The method to use to get the mask. Should be one of ["total", "frequency"].

    Returns:
        `torch.Tensor`: The majority sign mask.
    r2   r   r   r3   zUnimplemented mask method ""r   r   )signsumRuntimeErrorr   where)r   r*   r7   sign_magnitudemajority_signs        r   calculate_majority_sign_maskr=   g   su     ;;=D*	;	a8BCCKK! 3Q;M=  r   r	   majority_sign_maskc                     | |z  j                  d      }|j                  d      }|t        j                  |d      z  S )a  
    Merge the task tensors using disjoint merge.

    Args:
        task_tensors (`torch.Tensor`):The task tensors to merge.
        majority_sign_mask (`torch.Tensor`):The mask of the majority sign across the task tensors.

    Returns:
        `torch.Tensor`: The merged tensor.
    r   r5   g      ?)min)r8   r   clamp)r	   r>   mixed_task_tensorsnum_params_preserveds       r   disjoint_mergerD      sI     ');;@@Q@G-11a18,@c JJJr   r
   c                 z    t        j                  | d      } t        | |      }| |z  }|j                  d      }|S )a  
    Merge the task tensors using `task arithmetic`.

    Args:
        task_tensors(`List[torch.Tensor]`):The task tensors to merge.
        weights (`torch.Tensor`):The weights of the task tensors.

    Returns:
        `torch.Tensor`: The merged tensor.
    r   r5   )r   stackr   r8   )r	   r
   weighted_task_tensorsrB   s       r   task_arithmeticrH      sE     ;;|3L),@G(72.22q29r   c                     | D cg c]  }t        ||d       } }t        j                  | d      } t        | |      }| |z  }|j	                  d      }|S c c}w )aX  
    Merge the task tensors using `task arithmetic`.

    Args:
        task_tensors(`List[torch.Tensor]`):The task tensors to merge.
        weights (`torch.Tensor`):The weights of the task tensors.
        density (`float`): The fraction of values to preserve. Should be in [0,1].

    Returns:
        `torch.Tensor`: The merged tensor.
    r+   r*   r   r5   r1   r   rF   r   r8   r	   r
   r   r   rG   rB   s         r   magnitude_prunerM      si     NZZ6E&'+>ZLZ;;|3L),@G(72.22q29 [s   Amajority_sign_methodc                     | D cg c]  }t        ||d       } }t        j                  | d      } t        | |      }t	        | |      }| |z  }t        ||      }|S c c}w )a  
    Merge the task tensors using `ties`.

    Args:
        task_tensors(`List[torch.Tensor]`):The task tensors to merge.
        weights (`torch.Tensor`):The weights of the task tensors.
        density (`float`):The fraction of values to preserve. Should be in [0,1].
        majority_sign_method (`str`):
            The method to use to get the majority sign mask. Should be one of ["total", "frequency"].

    Returns:
        `torch.Tensor`: The merged tensor.
    r+   rJ   r   r5   r1   r   rF   r=   r   rD   r	   r
   r   rN   r   r>   rG   rB   s           r   tiesrR      sr    ( NZZ6E&'+>ZLZ;;|3L5lK_`),@G(72'(=?QR [s   Ac           	          | D cg c]  }t        ||dd       } }t        j                  | d      } t        | |      }| |z  }|j	                  d      }|S c c}w )aS  
    Merge the task tensors using `dare linear`.

    Args:
        task_tensors(`List[torch.Tensor]`):The task tensors to merge.
        weights (`torch.Tensor`):The weights of the task tensors.
        density (`float`):The fraction of values to preserve. Should be in [0,1].

    Returns:
        `torch.Tensor`: The merged tensor.
    r,   Tr*   r    r   r5   rK   rL   s         r   dare_linearrU      sk     YeefE&'(DIeLe;;|3L),@G(72.22q29 fs   Ac           	          | D cg c]  }t        ||dd       } }t        j                  | d      } t        | |      }t	        | |      }| |z  }t        ||      }|S c c}w )a  
    Merge the task tensors using `dare ties`.

    Args:
        task_tensors(`List[torch.Tensor]`):The task tensors to merge.
        weights (`torch.Tensor`):The weights of the task tensors.
        density (`float`):The fraction of values to preserve. Should be in [0,1].
        majority_sign_method (`str`):
            The method to use to get the majority sign mask. Should be one of ["total", "frequency"].

    Returns:
        `torch.Tensor`: The merged tensor.
    r,   TrT   r   r5   rJ   rP   rQ   s           r   	dare_tiesrW      st    ( YeefE&'(DIeLe;;|3L5lK_`),@G(72'(=?QR fs   A )F)r2   )r.   typingr   r   r   Tensorfloatr   boolr)   r1   r=   rD   listrH   rM   rR   rU   rW    r   r   <module>r^      s<      /ELL /5 /U\\ /&5<< % $ 5<< ( ch5LL5#(529:O2P5[_5
\\5: CJ!LL!")*>"?!
\\!2K K5<< KTYT`T` K $u||"4 u|| PUP\P\ &$u||"4 u|| V[ `e`l`l 4 ;B	u||$\\  ""67	
 \\@d5<<0 5<< RW \a\h\h 4 ;B	u||$\\  ""67	
 \\r   