
    *`iB                        U d dl Z d dlZd dlZd dlmZ d dlmZ d dlmZm	Z	m
Z
mZmZmZ d dlZd dlmZ  e j        e          Ze j        ed<   g dZe
eee         f         Z	 	 	 dd	ej        j        d
eee                  deee                  dee         dedeeeej        j        f                  fdZ	 	 	 dd	ej        j        d
eee                  deee                  dee         dedeeeej        j        ej        j        f                  fdZdedej        j        d
eee                  de	e         fdZde edz           defdZ!	 	 dd	ej        j        d
eee                  deee                  dedee	e	ej        j                                   f
dZ" e#            dfdedej        j        d
eeee         f         deeee         f         dee         defdZ$	 d d	ej        j        d
eeee         f         dedeej        j                 def
dZ%d dededee         defdZ&dej        j        dedefdZ'dS )!    N)defaultdict)	Generator)IterableListMappingOptionalTupleUnion)InternalModule_LOGGER)match_named_modulesmatch_named_parametersmatch_targetsmatch_modules_setget_lowest_common_ancestor_nameis_matchis_narrow_matchFmodeltargetsignorefusedwarn_on_failreturnc              #   D  K   |pg }|pg }t          |          }|                                 D ]>\  }}|D ]6}t          ||||          r!||hz  }t          ||||          s||fV   n7?|r/|D ].}t                              d| d| j        j                    -dS dS )a  
    Yields names and modules which match `targets` but do not match `ignore`.
    Values are returned in order of `model.named_modules()`

    :param model: model containing submodules to match against
    :param targets: target strings, potentially containing "re:" prefixes
    :param ignore: targets to ignore, potentially containing "re:" prefixes
    :fused: optional mapping from suffixes of fused modules to the suffixes of their
        corresponding shards. See `compressed_tensors.utils.match.is_match`
    :param warn_on_fail: if True, warns if any targets do not match any modules in model
    :return: generator of module names and modules
    )r   Could not match `` in instance of N)setnamed_modulesr   r   warning	__class____name__)	r   r   r   r   r   unmatched_targetsnamemoduletargets	            r/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/compressed_tensors/utils/match.pyr   r   +   s     & mG\rFG++--  f 	 	FffE::: !fX-!ffEBBB ',&&&	  ' 	 	FOOWFWWU_=UWW    	 	    c              #     K   |pg }|pg }t          |          }|                                 D ]}\  }}t          |t                    r|                    d          D ]K\  }}	| d| |D ]<}
t          |
          r)||
hz  }t          fd|D                       s||	fV  =L~|r/|D ].}
t                              d|
 d| j	        j
                    -dS dS )a  
    Yields parameters which match `targets` but do not match `ignore`.
    Values are returned in order of `model.named_modules()`

    :param model: model containing params to match against
    :param targets: target strings, potentially containing "re:" prefixes
    :param ignore: targets to ignore, potentially containing "re:" prefixes
    :fused: optional mapping from suffixes of fused modules to the suffixes of their
        corresponding shards. See `compressed_tensors.utils.match.is_match`
    :param warn_on_fail: if True, warns if any targets do not match any params in model
    :return: generator of fully-qualified param names, parent modules, and params
    F)recurse.c              3   :   K   | ]}t          |          V  d S N_match_name).0ignr   	param_fqns     r&   	<genexpr>z)match_named_parameters.<locals>.<genexpr>s   s/      TTc{9c5AATTTTTTr'   r   r   N)r   r   
isinstancer   named_parametersr.   anyr   r   r    r!   )r   r   r   r   r   r"   module_namer$   
param_nameparamr%   r1   s      `       @r&   r   r   R   sk     & mG\rFG$2244 7 7Vfn-- 	!'!8!8!8!G!G 	7 	7J&5555I! 7 7y&%88 7%&1%TTTTTVTTTTT 7'66667	7  ' 	 	FOOWFWWU_=UWW    	 	r'   r#   r$   c                    |pg }t          |t                    rg S t          |d           }g }|D ]'}t          | |          r|                    |           (|D ]+}t          ||          r||vr|                    |           ,|S )av  
    Returns the targets that match the given name and module.

    :param name: the name of the module
    :param module: the module to match
    :param targets: the target strings, potentially containing "re:" prefixes
    :return: the targets that match the given name and module

    Outputs are ordered by type: exact name match, regex name match, class name match
    c                     d| v | fS )Nre: )xs    r&   <lambda>zmatch_targets.<locals>.<lambda>   s    UaZO r'   )key)r3   r   sortedr.   append_match_class)r#   r$   r   matched_targetsr%   s        r&   r   r   }   s     mG&.)) 	 W";";<<<GO + +tV$$ 	+""6*** + +'' 	+F/,I,I""6***r'   namesc                    d | D             } t          |           dk    rdS dt          |           z   dz   }dt          |           z   dz   }t          j                            ||g          }|d|                    d                   S )a  
    Given a list of names, returns the lowest-scope common name ignoring Nones.

    Implementation is a small alteration of os.path.commonprefix
    https://docs.python.org/3/library/os.path.html#os.path.commonprefix

    ([s1, s2]->prefix->result)
    # case 0: multiple modules: [abc.a., abc.b.] -> .abc. -> abc
    # case 1: single module: [abc.] -> .abc. -> abc
    # case 2: substring modules: [abc., ab.] -> .ab -> ""
    # case 3: parent & child: [ab., ab.a.] -> .ab. -> ab
    c                     g | ]}||S r,   r<   )r/   r#   s     r&   
<listcomp>z3get_lowest_common_ancestor_name.<locals>.<listcomp>   s    888dt'7T'7'7'7r'   r    r*      )lenminmaxospathcommonprefixrfind)rD   s1s2common_prefixs       r&   r   r      s     98e888E
5zzQr 
s5zz	C	B	s5zz	C	BG(("b22M ]0055566r'   Terror_on_module_rematchc              #     K   |pg }|pg }t          t                    d}t          |          }|                                 D ]\  }}t                      }|D ]}	t	          |||	|          rwt          ||g          }
|s;|
|k    r5fd|D             V  t          t                    |}
t          |          }|	                             |           |
}||	hz  }||	hz  }t          |          dk    r|rt          d| d| d          |t          |          k    rdS |sfd|D             V  dS t          dt          |          |z
   d	|           )
aR  
    Yields modules grouped by parent context.

    We group by parent context so that we can return ALL matches of a
    specific target that can be paired with another target. This is most
    relevant in the case of MoE modules with multiple modules for each
    expert i.e. post_attention_layernorm <-> mlp.expert.N.gate_proj,
    mlp.expert.N.up_proj for all N. The parent context will differ from
    one layer to another while being the same for one expert to another.

    Each returned group is a list (of lists) with the same size
    and order as `targets` while all matches for each target and
    the overall order of the groups are ordered in the same way
    as `model.named_modules`


    E.g. the following targets would yield modules belonging to the following layers:
    ```python3
    match_modules_set(model, ["q_proj", "k_proj", "v_proj"]) == (
        [
            [`layers.0.self_attn.q_proj`],
            [`layers.0.self_attn.k_proj`],
            [`layers.0.self_attn.v_proj`],
        ],
        [
            [`layers.1.self_attn.q_proj`],
            [`layers.1.self_attn.k_proj`],
            [`layers.1.self_attn.v_proj`],
        ],
        ...
    )
    ```

    This can be used to match layers to their corresponding downstream counterparts.
    For example, matching layer norms to their subsequent linear layers
    ```python3
    for norm, q, k, v in match_modules_set(model, (norm_tgt, q_tgt, k_tgt, v_tgt)):
        fuse_norm_linears(*norm, [*q, *k, *v])
    ```

    Alternatively for MoE you would get multiple matches
    per target per group, E.g.

    ```python3

    targets = [
        "post_attention_layernorm",
        "up_proj",
        "down_proj"
    ]
    match_modules_set(model, targets) == (
        [
            [layers.0.post_attention_layernorm],
            [
                `layers.0.mlp.experts.0.up_proj`,
                `layers.0.mlp.experts.1.up_proj`,
                ...
            ],
            [
                `layers.0.mlp.experts.0.down_proj`,
                `layers.0.mlp.experts.1.down_proj`,
                ...

            ]
        ], # <- first yield
        [
            [layers.1.post_attention_layernorm],
            [
                `layers.1.mlp.experts.0.up_proj`,
                `layers.1.mlp.experts.1.up_proj`,
                ...
            ],
            [
                `layers.1.mlp.experts.0.down_proj`,
                `layers.1.mlp.experts.1.down_proj`,
                ...
            ]
        ],
        ...
    )
    ```

    :param model: model containing modules to match against
    :param targets: target strings, potentially containing "re:" prefixes
    :param ignore: targets to ignore, potentially containing "re:" prefixes
    :param error_on_module_rematch: if True, errors when a module gets
      matched to multiple targets, if False, no error. (Defaults to True)
    Nc                      g | ]
}|         S r<   r<   r/   r%   matchess     r&   rG   z%match_modules_set.<locals>.<listcomp>@  s    AAAv76?AAAr'   rI   zmodule: z$ was matched with multiple targets: zT which is unexpected disable this check by setting `error_on_module_rematch = False`c                      g | ]
}|         S r<   r<   rW   s     r&   rG   z%match_modules_set.<locals>.<listcomp>W  s    5556wv555r'   z:Found a final incomplete set with matches found for keys: z  but no matches found for keys: )	r   listr   r   r   r   rA   rJ   
ValueError)r   r   r   rT   parent_contextr"   r#   r$   matched_targets_for_cur_moduler%   new_parent_contextrX   s              @r&   r   r      s     | mG\rF, $GNG++--  f),& 	; 	;Ffff55 ;%D>*& &"
 ) 5-?>-Q-QAAAAAAAAAA)$//G)-&(+G%&&v...!3!fX-!.6(:.-..227N2R4 R R1R R R   CLL((  5555W555555
	>w<<++	> 	>*;	> 	>  r'   c                     t          |t                    r|gn|}t          |t                    r|gn|}t          t                     o:t           fd|D                       ot           fd|D                        S )a  
    Returns true if either module name or module parent classes match against target
    and the module is not an internal module. The name and module may refer to a fused
    module defined by vLLM. In these cases, a `fused` mapping must be provided.

    For example, in `vllm/model_executor/models/llama.py`:
    ```python
    packed_modules_mapping = {
        "qkv_proj": ["q_proj", "k_proj", "v_proj"],
        "gate_up_proj": ["gate_proj", "up_proj"]
    }
    ```

    :param name: name of module
    :param module: module to match
    :param target: target which matches name or module, potentially contains regex
    :fused: optional mapping from suffixes of fused modules to the suffixes of their
        corresponding shards
    c              3   Z   K   | ]%}t          |          pt          |          V  &d S r,   r.   rB   )r/   r%   r   r$   r#   s     r&   r2   zis_match.<locals>.<genexpr>  sR       
 
 fe,,LVV0L0L
 
 
 
 
 
r'   c              3   Z   K   | ]%}t          |          pt          |          V  &d S r,   ra   )r/   r0   r   r$   r#   s     r&   r2   zis_match.<locals>.<genexpr>  sO       
 
KNKc5))F\&#-F-F
 
 
 
 
 
r'   )r3   strr   r5   )r#   r$   r   r   r   s   ``  `r&   r   r   a  s    4 &gs33@wiiG#FC00<fXXfF&.111  
 
 
 
 
 
!
 
 
 	
 	
 	
  
 
 
 
 
 
RX
 
 
 
 
 
r'   c                    t          |t                    r|gn|}n|                                                   dd          d         |                               t	          fd|D                       S )a  
    Checks if any of the targets narrowly match the module. A target narrowly matches
    a module if the target matches the module, but does not match the module's parent

    :param model: model containing both module and its parent
    :param targets: target strings, potentially containing "re:" prefixes
    :param name: name of module to match
    :param module: module to match. If none is provided, then get module from model
    :return: True if any of the targets narrow match the module
    Nr*   rI   r   c              3   ^   K   | ]'}t          |          ot          |           V  (d S r,   )r   )r/   r%   r$   r#   parentparent_names     r&   r2   z"is_narrow_match.<locals>.<genexpr>  sW         	vv&&TxVV/T/T+T     r'   )r3   rc   get_submodulersplitr5   )r   r   r#   r$   rf   rg   s     ``@@r&   r   r     s      &gs33@wiiG)VVu/B/B4/H/HF++c1%%a(K  --F            r'   r%   c                 :   |S|D ]P}|                      |          r9|                     |          t          fd||         D                       c S Q                    d          r*t	          j                            d          |           duS | k    S )a  
    Returns true if target string begins with "re:" and regex matches or if target
    string exactly matches name. If the name refers to a fused module defined by vLLM,
    a `fused` mapping must be provided.

    :param name: name of module
    :param target: target name, potentially contains regex
    :fused: optional mapping from suffixes of fused modules to the suffixes of their
        corresponding shards
    Nc              3   >   K   | ]}t          |z             V  d S r,   r-   )r/   shard_suffixname_strippedr%   s     r&   r2   z_match_name.<locals>.<genexpr>  sF        $   <fEE     r'   r;   )endswithremovesuffixr5   
startswithrematchremoveprefix)r#   r%   r   fused_suffixrm   s    `  @r&   r.   r.     s     ! 	 	L}}\**  $ 1 1, ? ?     (-l(;         x++E22D99EE~r'   c                 N    t          fd| j        j        D                       S )a  
    Returns true if any torch parent class names match the target string exactly.
    A special exception is made for vllm's `LinearBase` class which matches `Linear`

    :param module: module to match
    :param target: target which matches name or module
    c              3      K   | ]?}t          |t          j        j                  o|j        k    p|j        d k    odk    V  @dS )
LinearBaseLinearN)
issubclasstorchnnModuler!   )r/   clsr%   s     r&   r2   z_match_class.<locals>.<genexpr>  sp       	 	  sEHO,, & ILL0GVx5G	 	 	 	 	 	r'   )r5   r    __mro__)r$   r%   s    `r&   rB   rB     sE      	 	 	 	 #+	 	 	 	 	 	r'   )NNF)NTr,   )(loggingrM   rq   collectionsr   collections.abcr   typingr   r   r   r   r	   r
   rz   !compressed_tensors.utils.internalr   	getLoggerr!   r   Logger__annotations____all__rc   FusedMapppingr{   r|   boolr   	Parameterr   r   rZ   r   r   tupler   r   r.   rB   r<   r'   r&   <module>r      sI    				 				 # # # # # # % % % % % % B B B B B B B B B B B B B B B B  < < < < < < ,'+H55 5 5 5   Xc]*+ '+%)$ $8?$hsm$$ Xc]#$ M"	$
 $ uS%(/)*+$ $ $ $T '+%)( (8?(hsm$( Xc]#( M"	(
 ( uS%(/58+==>?( ( ( (V#
#x#19(3-1H#	#Y# # # #L74d
+; 7 7 7 7 7: '+$(	a a8?ahsm$a Xc]#a "	a
 tD)*+a a a aP ).%)% %
%HO% 3%&% #x}$%	%
 M"% 
% % % %X )-	 8?3%&  UX_%	
 
   8 c 3 x/F RV    4 # $      r'   