
    h              	           S SK r S SKJr  / SQrS rS r " S S\5      r  SS\ R                  S	\S
\S\ R                  4S jjr	g)    N)UniformQuantizationObserverBase)create_block_sparse_tensorcreate_semi_structured_tensorPerChannelNormObservermask_creatorc                 <   US::  a  US:  d   S5       e[         R                  " [         R                  " X-  X-  4SU-
  US95      n[         R                  " XRSS9n[         R                  " XRSS9nUR	                  U5      R                  5       R                  5       $ )N      ?g        z*sparsity should be a value between 0 and 1   )dtyper   dim)torch	bernoullifullrepeat_interleaveto
contiguouscuda)MN	blocksizesparsityr   As         P/home/james-whalen/.local/lib/python3.13/site-packages/torchao/sparsity/utils.pyr   r      s    s?x3 4. 	

ANAN3Q\O	A 	!4A!4A44;!!#((**    c                    [         R                  " SSX-  S-  45      R                  5       n[         R                  R                  R                  USS9R                  X5      R                  5       R                  [         R                  5      nU[         R                  " X5      R                  5       U-  -   nUR                  U5      $ )z
This function returns a 1:2 sparse matrix of size (r, c).
Note that this means this matrix will also be 2:4 and 4:8 sparse as well.
r      )num_classes)r   randintr   nn
functionalone_hotreshaper   r   int32rand)rcr   choice_indicesmasksparse_weights         r   r   r      s     ]]1a!%1*7<<>N##N#B			EKK	 	 EJJq,113d:;ME""r   c                   <   ^  \ rS rSrSrSU 4S jjrS rS rSrU =r	$ )r   3   zX
A custom observer that computes the L2 norm of each channel and stores it in a buffer.
c                   > [         TU ]  " S[        R                  [        R                  SS S [        R
                  " [        R                  5      R                  S.UD6  SU l        U R                  S[        R                  " / 5      5        g )NF)r   qschemereduce_range	quant_min	quant_maxepsr	   norm )super__init__r   quint8per_channel_affinefinfofloat32r2   averaging_constantregister_buffertensor)selfkwargs	__class__s     r   r6   PerChannelNormObserver.__init__8   sq     	
,,,,EMM*..	
 	
 #&VU\\"%56r   c                 F   UR                  5       S:X  a  U$ UR                  5       n[        UR                  5       5       Vs/ s H  o3PM     nnUS   US   sUS'   US'   UR	                  U5      n[
        R                  " USS9n[
        R                  R                  USS9S-  nU R                  R                  5       S:X  aB  U R                  R                  UR                  5        U R                  R                  U5        U$ U =R                  U-  sl	        U$ s  snf )Nr   r
   )	start_dimr   r   )numeldetachranger   permuter   flattenlinalgvector_normr3   resize_shapecopy_)r>   x_origxinew_axis_listyr3   s          r   forwardPerChannelNormObserver.forwardI   s    <<>QMMMO %*!%%'N3NqN3.;B.?qAQ+a-+IIm$MM!q)||''q'1Q699??!IIdjj)IIOOD!  III 4s   Dc                     [        S5      e)Nz>PerChannelNormObserver is designed to store activations only. )NotImplementedError)r>   s    r   calculate_qparams(PerChannelNormObserver.calculate_qparams_   s    !L
 	
r   )r;   )returnN)
__name__
__module____qualname____firstlineno____doc__r6   rT   rX   __static_attributes____classcell__)r@   s   @r   r   r   3   s    7",
 
r   r   r=   r   r   rZ   c                    SnU R                  5       U-  S:w  a  [        SU R                   SU S35      eU R                  5       U-  nU R                  5       R	                  5       R                  XB5      n[        R                  " USS9SS2S[        X!-
  5      24   n[        R                  " UR                  UR                  S9nUR                  SUSS	9R                  U R                  5      nU$ )
a  
Class for creating N:M sparsity masks.
Masks will be created using the N:M ratio, where for every block of
M weights, N will be pruned based on ranked weight value. Each mask
will correspond to the given tensor.
:param tensor: The input tensor to create a mask for
:param N: The number of weights in a group to keep
:param M: The size of a weight group
:return: A mask tensor with the same shape as the input tensor
Nr   zTensor of size z can't be evenly divided into z groupsr
   r   )device)r   indexvalue)rE   
ValueErrorrM   rF   absr#   r   argsortintonesrc   scatter_)r=   r   r   r)   
num_groupstensor_temprd   w_bs           r   r   r   e   s     D||~Qfll^+I!GT
 	
 1$J --/%%'//
>KMM+1-a3qu:o>E
**[&&{/A/A
BC<<AU!<4<<V\\JDKr   )r      )
r   torch.ao.quantization.observerr   __all__r   r   r   Tensorri   r   r4   r   r   <module>rs      se     J	+#,/
< /
h LL
  \\	r   