
    *`iy                        d dl Z d dlmZ d dlmZ d dlZd dlmZ  ee          j	        dz  Z
g dZej         ej        d          fded	ej        d
ej        dej        fdZej         ej        d          dfded	ej        d
ej        deej                 dej        f
dZdedefdZ ej        d          e
fded	ej        d
ej        dedeej                 f
dZdej        dej        fdZdS )    N)Path)Optional)	safe_openzhadamards.safetensors)random_hadamard_matrixdeterministic_hadamard_matrixis_pow2cpusizedtypedevicereturnc                 v   | dk    rt          d          t          t          j        |                     }| d|z  k    rt          d          t	          j        dgg||          }t          |          D ]A}t	          j        t	          j        ||f          t	          j        || f          f          }B|S )a  
    Construct an n-by-n Hadamard matrix, using Sylvester's construction.
    `n` must be a power of 2.

    Adapated from https://github.com/scipy/scipy/blob/v1.15.2/scipy/linalg/_special_matrices.py  # noqa: E501

    :param size: order of the matrix, must be a power of 2
    :param dtype: data type of matrix
    :param device: device to construct matrix on
    :return: hadamard matrix of size `size`
    r   z4Cannot construct deterministic hadamard of size <= 0   z6Cannot construct deterministic hadamard of size != 2^n   r   r   )	
ValueErrorintmathlog2torchtensorrangevstackhstack)r
   r   r   r   H_s         /home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/compressed_tensors/transform/utils/hadamard.pyr   r   !   s      qyyOPPPtyDq$wQRRRqcU%777A 4[[ H HL%,1v..a!W0E0EFGGH    genc                     t          j        dd| f||          }|                    |          }|dz  dz
  }t          j        |          }t	          |          S )a  
    Produces a randomly generated Hadamard matrix. Differs from
    `deterministic_hadamard_matrix` in that this function supports non powers of 2
    and randomization using a seeded generator

    Adapated from https://github.com/facebookresearch/SpinQuant/blob/main/utils/hadamard_utils.py  # noqa: E501
    Known matrices were retrieved from N. J. A. Sloane's Library of Hadamard Matrices http://www.neilsloane.com/hadamard/  # noqa: E501

    :param size: The dimension of the hamadard matrix
    :param dtype: data type of matrix
    :param device: device to construct matrix on
    :param gen: Optional generator random values
    :return: randomly generated hadamard matrix
    r   r   )lowhighr
   	generatorr   r   r   )r   randinttodiag_matmul_hadU)r
   r   r   r   Qs        r   r   r   A   sY    ( 	!!4'SNNNA	FA	A	A
1A??r   nc                 &    | dk    o| | dz
  z  dk    S )zt
    Check if a number is a power of 2

    :param n: number to check
    :return: True iff `n` is a power of 2
    r   r    )r*   s    r   r   r   \   s      q5'a1q5kQ&'r   	file_pathc                    |j         dk    rt          j        d          n|}t          |dt	          |                    5 }t          d |                                D             d          }|D ]b}| |z  dk    rWt          | |z            rE|                    t	          |                    	                    ||	          c cd
d
d
           S c	 d
d
d
           n# 1 swxY w Y   d
S )a{  
    Fetch a known hadamard matrix from the given file path. The returned matrix will
    be of of size `k` such that `n / k` is a power of two. Return None if no such
    matrix exists.

    Note: This function reopens the safetensors file every time it is called.
    This is technically inefficient, but a very small runtime cost and simpler
    than forcing callers to manage the file open context

    :param n: size of known hadamard matrix
    :param dtype: data type to move fetched hadamard to
    :param device: device to move fetched hadamard to
    :return: a known hadamard matrix of size `n` if one exists, else None
    metar	   pt)	frameworkr   c              3   4   K   | ]}t          |          V  d S )N)r   ).0keys     r   	<genexpr>z*_fetch_hadamard_divisor.<locals>.<genexpr>|   s(      ;;3s88;;;;;;r   T)reverser   r   N)
typer   r   r   strsortedkeysr   
get_tensorr&   )r*   r   r   r-   open_devicefiledivisorsdivisors           r   _fetch_hadamard_divisorr@   f   si   ( *0)>)>%,u%%%FK	9S5E5E	F	F	F T$;;tyy{{;;;TJJJ 	T 	TG7{aGAL$9$9s7||4477eF7SSSS	T T T T T T T T	TT T T T T T T T T T T T T T T 4s   BC!C!!C%(C%Xc                    |                      d          }| j        }| j        }t          |||          }|t	          d|           |                     d          }|                                                     d|d          }|                                }|j        d         |k    r|                    |j        d         |j        d         dz  d|j        d                   }|                    |j                  }|d d d d dd d f         |d d d d dd d f         z   |d d d d dd d f<   |d d d d dd d f         |d d d d dd d f         z
  |d d d d dd d f<   |                    |j        d         |j        d         d          }||}}|j        d         |k    |j        d         |k    sJ ~|                    d||                              |          |z  }|                    | j                  S )Nr   r$   z0Cannot construct random hadamard matrix of size r   r   )	r
   r   r   r@   r   cloneviewshaper&   )rA   r
   r   r   hadKKinputoutputs           r   r(   r(      s!   66!99DGEXF #4v>>>D|RDRRSSS		!A GGIINN2tQ''E[[]]F
+a.1



5;q>5;q>Q+>5;q>RRU[))"111aaaAAA:.qqq!!!Qz1BBqqq!!!Qz"111aaaAAA:.qqq!!!Qz1BBqqq!!!QzU[^U[^R@@!5 +a.1

 ;q>Q IIaA!!%((50E ::agr   )r   pathlibr   typingr   r   safetensorsr   __file__parent	REPO_PATH__all__bfloat16r   r   r   Tensorr   	Generatorr   boolr   r8   r@   r(   r,   r   r   <module>rV      s                 ! ! ! ! ! ! DNN!$;;	 Q
P
P '5<.. 
; L \	   D '5<..%)	 
; L 
%/	"	
 \   6(s (t ( ( ( ( (5<..	 
; L 	
 el   <EL U\      r   