
    *`i              
           d dl mZ d dlZd dlmZ ddgZ	 ddej        j        dedee         d	efd
Z	dej
        dej
        dedeej        j                 d	ej
        f
dZdej
        dej
        d	ej
        fdZdS )    )OptionalN)TransformLocationget_transform_sizeapply_transform_weightmodulelocationhead_dimreturnc           	         d}t          | t          j        j                  r*|t          j        t          j        fv r| j        }ns| j        }nkt          | t          j        j	                  r*|t          j        t          j        fv r| j
        }n*| j        }n"| t          dt          |            d          |4|0||z  dk    r't          | d| dt          |            d|           |}|S )a  
    Determine the size of a transform matrix given its location on the module

    :param module: module that matrix will be applied to
    :param location: location on module
    :param head_dim: size of head when transform is applied to mha
    :return: size of matrix
    NzTransforms on z# are not supported without head_dimr   z must divide z for z at )
isinstancetorchnnLinearr   INPUTWEIGHT_INPUTin_featuresout_features	Embeddingnum_embeddingsembedding_dimNotImplementedErrortype
ValueError)r   r   r	   sizes       }/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/compressed_tensors/transform/utils/matrix.pyr   r      s    D&%(/** 
)/1B1OPPP%DD&DD	FEH.	/	/ 
)/1B1OPPP(DD'DD		!NT&\\NNN
 
 	
 x1 4 4QQ$QQT&\\QQxQQ   K    transform_weightvaluemodule_typec                 6   | j         d         | j         d         k    sJ t          |                                          rt          ||           S |t          j        j        k    rK|t          j        k    rt          || j                  S |t          j	        k    rt          | j        |          S nU|t          j        j
        k    r@|t          j        k    rt          | |          S |t          j	        k    rt          ||           S t          d| d| d          )a;  
    Using the transform location, apply the transform_weight to the
    given value wrt linear weights. For more info on input and output transforms,
    see `TransformLocation`

    The following explains how weights should be applied to values according to location

    let  x          be input activation
         W          be weight,
         yh, xh, Wh be transformed output, input, weight

    note that
         y  = (x W.T)        // torch.nn.Linear

    Choose values for yh, xh, and Wh which incorporate matrix transforms

    let  V, Vi      be transform matrices on input side
         U, Ui      be transform matrices on output side

    pick xh = (x V)
         Wh = (U.T W Vi.T)
         yh = (y U)

    The following shows that `yh = (xh) (Wh).T` for the chosen values of yh, xh, and Wh

    (xh) (Wh).T = (x V) (U.T W Vi.T).T
                = (x V) (Vi W.T U)        // transpose matrix product identity
                = (x W.T) U
                = y U
                = yh

    :param transform_weight: transform weight to apply
    :param value: value to apply transform_weight to
    :param location: determines how weight should be applied
    :param model_type: result of type(module), passed in to determine application of
        weight transform
    :return: value after transform_weight has been applied
    r      zApplying transforms to  z is not supported)shaper   	is_online_multihead_matmulr   r   r   r   TWEIGHT_OUTPUTr   r   )r   r   r   r   s       r   r   r   A   s(   Z !!$(8(>q(AAAAA"",,.. : (8999eho%%(555$U,<,>???*888$%5%7??? 9
 
*	*	*(555$%5u===*888$U,<===
K+KKKKK  r   ABc                    | j         d         |j         d         k    rN|j         d         }| j         d         |z  }|                     d||f          } | |z                      dd          S | j         d         |j         d         k     rN| j         d         }|j         d         |z  }|                    d||f          }| |z                      dd          S | |z  S )a  
    Performs A @ B for last two dims of two matrices A and B that possibly
    have different shapes, as is the case in multi-headed dimension. If
    shapes are different, this is equivalent to converting the last two dims
    of the smaller matrix into a block-diagonal matrix with the same shape as
    the last two dims of the larger matrix.

    E.g. if A is half the size of B, this function will perform
    [[A  ]  @ B
     [  A]]

    If B is a third of the size of A, this function will perform
    A @ [[B    ]
         [  B  ]
         [    B]]

    This function will error out if the shapes are not evenly divisble

    :param A: left-hand tensor
    :param B: right-hand tensor
    :return: result
    )r#   	unflattenflatten)r(   r)   r	   	num_headss       r   r%   r%      s    . 	wr{QWR[  72;GBK8+	KKY122Ar2&&&	
qwr{	"	"72;GBK8+	KKY122Ar2&&&1ur   )N)typingr   r   compressed_tensors.transformr   __all__r   Moduleintr   Tensorr   r   r%    r   r   <module>r8      s           : : : : : :  !9
: #& &HO&& sm& 		& & & &RElE<E  E eho&	E
 \E E E EP" "%, "5< " " " " " "r   