
    Vh                         U d dl Z d dlmZ g Zee   ed<    G d de j                  j                  j                        Z
y)    N)	Parameter__all__c                   6    e Zd ZdZ	 	 	 	 	 	 d fd	Zej                  j                  d        Zej                  j                  d        Z	ej                  j                  d        Z
ej                  j                  dd       Zej                  j                  dd       Zej                  j                  dd       Zej                  j                  dd	       Zej                  j                  d
        Zej                  j                  d        Zd Z xZS )_LearnableFakeQuantizea  Generalized extension of the FakeQuantize module in fake_quantize.py.

    This is an extension of the FakeQuantize module in fake_quantize.py, which
    supports more generalized lower-bit quantization and supports learning of the scale
    and zero point parameters through backpropagation.

    In addition to the attributes in the original FakeQuantize module, the _LearnableFakeQuantize
    module also includes the following attributes to support quantization parameter learning.

    * :attr:`channel_len` defines the length of the channel when initializing scale and zero point
      for the per channel case.

    * :attr:`use_grad_scaling` defines the flag for whether the gradients for scale and zero point are
      normalized by the constant, which is proportional to the square root of the number of
      elements in the tensor. The related literature justifying the use of this particular constant
      can be found here: https://openreview.net/pdf?id=rkgO66VKDS.

    * :attr:`fake_quant_enabled` defines the flag for enabling fake quantization on the output.

    * :attr:`static_enabled` defines the flag for using observer's static estimation for
      scale and zero point.

    * :attr:`learning_enabled` defines the flag for enabling backpropagation for scale and zero point.
    c                 b   t         
|           ||k  sJ d       || _        || _        ||d<   ||d<   || _        |dk(  rIt        t        j                  |g            | _        t        t        j                  |g            | _	        njt        |t              r|dkD  sJ d       t        t        j                  |g|z              | _        t        t        j                  |g|z              | _	         |di || _        t        j                  | j                  j                        j                  |k  sJ d       |t        j                  | j                  j                        j                   k  sJ d       | j                  j                  | _        | j                  j"                  | _        t%        | j                  d	      r| j                  j&                  nd| _        | j)                  d
t        j                  dgt        j*                               | j)                  dt        j                  dgt        j*                               | j)                  dt        j                  dgt        j*                               t        j                  ||z
  dz         j-                         }	t        t        j.                  |	      j1                               | _        | j)                  dt        j                  t        j4                  t        j6                        j8                  g             y )Nz/quant_min must be strictly less than quant_max.	quant_min	quant_maxr   z(Channel size must be a positive integer.zquant_min out of boundzquant_max out of boundch_axisfake_quant_enabled   )dtypestatic_enabledlearning_enabledeps )super__init__r   r	   use_grad_scalingr   torchtensorscale
zero_point
isinstanceintactivation_post_processiinfor   minmaxqschemehasattrr   register_bufferuint8doublelog2itembitwidthfinfofloat32r   )selfobserverr   r	   r   r   channel_lenr   observer_kwargsbitrange	__class__s             ^/home/dcms/DCMS/lib/python3.12/site-packages/torch/ao/quantization/_learnable_fake_quantize.pyr   z_LearnableFakeQuantize.__init__$   s    	9$W&WW$""'0$'0$ 0""5<<#89DJ'j\(BCDO ;,q:9:@"5<<+0E#FGDJ'j\K5O(PQDO'/'B/'B$KK44::;??9L	$#	$L T%A%A%G%GHLLL	$#	$L1177
33;; t33Y? ((00 	
 	15<<5;;3WX-u||QCu{{/ST/qc1UV<<	I 5 9:AACEJJx05578UELL%++emm2L2P2P1Q$RS    c                 j    | j                  d      j                  d      j                  d       | S )zEnable parameter learning over static observer estimates.

        Enables learning of quantization parameters and
        disables static observer estimates. Forward path returns fake quantized X.
        TenabledFtoggle_qparam_learningtoggle_fake_quanttoggle_observer_updater*   s    r0   enable_param_learningz,_LearnableFakeQuantize.enable_param_learningW   s<     	##D#1CC 	D 	

 
 
 
/r1   c                 h    | j                  d      j                  d      j                  d       y)zEnable static estimates of quantization parameters.

        Enables static observer estimates and disables learning of
        quantization parameters. Forward path returns fake quantized X.
        Fr3   TNr5   r9   s    r0   enable_static_estimatez-_LearnableFakeQuantize.enable_static_estimatec   s7     	##E#2DD 	E 	

 
 
 
.r1   c                 h    | j                  d      j                  d      j                  d       y)zEnable accumulation of data without updating quantization parameters.

        Enables static observer accumulating data from input but doesn't
        update the quantization parameters. Forward path returns the original X.
        Fr3   TNr5   r9   s    r0   enable_static_observationz0_LearnableFakeQuantize.enable_static_observationn   s7     	##E#2DD 	E 	

 
 
 
.r1   c                 6    t        |      | j                  d<   | S Nr   )r   r   r*   r4   s     r0   r8   z-_LearnableFakeQuantize.toggle_observer_updatey   s    !$WAr1   c                 &    | j                  |       y )N)r8   rA   s     r0   enable_observerz&_LearnableFakeQuantize.enable_observer~   s    ##G,r1   c                 z    t        |      | j                  d<   || j                  _        || j                  _        | S r@   )r   r   r   requires_gradr   rA   s     r0   r6   z-_LearnableFakeQuantize.toggle_qparam_learning   s3    #&w<a #*

 (/%r1   c                 6    t        |      | j                  d<   | S r@   )r   r   rA   s     r0   r7   z(_LearnableFakeQuantize.toggle_fake_quant   s    %(\"r1   c                     t        d| j                  j                                 t        d| j                  j                                 y )Nz_LearnableFakeQuantize Scale: z#_LearnableFakeQuantize Zero Point: )printr   detachr   r9   s    r0   observe_quant_paramsz+_LearnableFakeQuantize.observe_quant_params   s>    .tzz/@/@/B.CDE3DOO4J4J4L3MNOr1   c                 n   | j                   j                  j                  | j                  j	                                | j                   j                         }| j                  j                         j                         j                  | j                  | j                        j                         }||fS )Nr   )r   dataclamp_r   r&   rI   r   roundclampr   r	   long)r*   r   r   s      r0   calculate_qparamsz(_LearnableFakeQuantize.calculate_qparams   s{    

488==?3

!!#OO""$UWU4>>4>>2TV	 	 j  r1   c           	         | j                   d   dk(  r| j                  |j                                | j                  j                         \  }}|j	                  | j
                  j                        }|j	                  | j                  j                        }| j
                  j                  j                  |       | j                  j                  j                  |       n>| j
                  j                  j                  | j                  j                                | j                  d   dk(  r?| j                  t        j                   t        j"                  fv r$| j                  j                  j%                          | j&                  r$d|j)                         | j*                  z  dz  z  }nd}| j                  t        j                   t        j,                  fv rOt        j.                  || j
                  | j                  | j0                  | j2                  | j*                  |      }|S t        j4                  || j
                  | j                  | j2                  | j*                  |      }|S )Nr   r   rL         ?g      ?)r   r   rI   rR   tor   devicer   rM   copy_rN   r   r&   r   r    r   per_channel_symmetricper_tensor_symmetriczero_r   numelr	   per_channel_affine+_fake_quantize_learnable_per_channel_affiner   r   *_fake_quantize_learnable_per_tensor_affine)r*   X_scale_zero_pointgrad_factors        r0   forwardz_LearnableFakeQuantize.forward   s   q!Q&((4"&">">"P"P"RFKYYtzz001F%..)?)?@KJJOO!!&)OO  &&{3JJOO""txx}}"7""1%*||++**   $$**,$$!QWWY%?C$GG!|| ; ;U=U=UVVEEJJOOLLNNNN&  DDJJOONNNN r1   )r      rT   g        r
   F)T)__name__
__module____qualname____doc__r   r   jitexportr:   r<   r>   r8   rC   r6   r7   rJ   rR   rc   __classcell__)r/   s   @r0   r   r   
   s8   8 1Tf YY	 	 YY/ / YY/ / YY  YY- - YY  YY  YYP P YY	! 	!*r1   r   )r   torch.nn.parameterr   r   liststr__annotations__aoquantizationFakeQuantizeBaser   r   r1   r0   <module>rs      s;     ( c UXX22CC r1   