
    ёi                          S SK r S SK Jr  S SKJr  S SKJr  S SKJrJr  S SK	J
r
  S SKJr  SS	KJr  SS
KJr   " S S\5      r " S S\5      rg)    N)_C_ops)check_variable_and_dtype)_create_tensor)	ParamAttrcore)Constant)unique_name   )BaseQuanter)QuanterFactoryc                   >   ^  \ rS rSrSr    SU 4S jjrS rSrU =r$ )FakeQuanterWithAbsMaxObserver   a  
Compute quantization parameters and simulate quantization.

It collects maximum absolute values of target tensor with moving average.
The average value will be used as quantization scale to quantize and
dequantize the tensor.

And it is symmetric uniform quantization which means the zero point is always 0.

The computational formula of moving average is described as below:

.. math::
        state = rate * state + 1
        accum = rate * accum + max(abs(x))
        scale = accum / state

Where:

- :math:`x` is the input tensor.
- :math:`state` and :math:`accum` are zero-initialized accumulators.
- :math:`rate` is moving average rate.
- :math:`scale` is quantization scale

And the computational formula of simulate quantization is:

.. math::
        range = 2^{bit\_length - 1} - 1
        out = round(x / scale * range) * scale / range

Where:

- :math:`{bit\_length}` is the length of bits.
- :math:`x` is the input tensor and :math:`out` is the output of simulate quantization.

Args:
    moving_rate(float, optional): The rate of moving average.
    bit_length(int, optional): Number of bits to represent an quantized integer in binary.
    dtype(str, optional): The data type of input tensor.
    name (str, optional): This parameter is used by developers to print debugging information. \
        For details, please refer to :ref:`api_guide_Name`. Default is None.

Examples:
    .. code-block:: python

        >>> from paddle.quantization import QuantConfig
        >>> from paddle.quantization.quanters import FakeQuanterWithAbsMaxObserver
        >>> quanter = FakeQuanterWithAbsMaxObserver(moving_rate=0.99)
        >>> q_config = QuantConfig(activation=quanter, weight=quanter)
c                 &   > [         TU ]  UUUUS9  g )N)namemoving_rate
bit_lengthdtype)super__init__)selfr   r   r   r   	__class__s        d/var/www/html/banglarbhumi/venv/lib/python3.13/site-packages/paddle/quantization/quanters/abs_max.pyr   &FakeQuanterWithAbsMaxObserver.__init__N   s#     	#!	 	 	
    c                     [         $ N)"FakeQuanterWithAbsMaxObserverLayerr   s    r   
_get_class(FakeQuanterWithAbsMaxObserver._get_class\   s    11r    )?   float32N)	__name__
__module____qualname____firstlineno____doc__r   r    __static_attributes____classcell__r   s   @r   r   r      s&    0h 
2 2r   r   c                   d   ^  \ rS rSr    SU 4S jjrS rS rS rS rS r	S r
S	 rS
 rSrU =r$ )r   `   c                 h  > [         TU ]  5         X0l        X@l        U(       a  U S3OSn[	        [
        R                  " U5      [        S5      SS9nU R                  S/XuS9U l	        SU R                  l
        U(       a  U S	3OS
n[	        [
        R                  " U5      [        S5      SS9n	U R                  S/XS9U l        SU R                  l
        U(       a  U S3OSn
[	        [
        R                  " U
5      [        S5      SS9nU R                  S/XS9U l        SU R                  l
        g )Nz.scalezquant_dequant.scalegMbP?F)r   initializer	trainable   )shapeattrr   Tz.statezquant_dequant.statez.accumzquant_dequant.accum)r   r   _moving_rate_bit_lengthr   r	   generater   create_parameter_scalestop_gradient_state_accum)r   layerr   r   r   r   scale_prefix
scale_attrstate_prefix
state_attraccum_prefix
accum_attrr   s               r   r   +FakeQuanterWithAbsMaxObserverLayer.__init__a   s<    	'%*.$v4I%%l3 


 ++#J , 
 %)!*.$v4I%%l3 


 ++#J , 
 %)!*.$v4I%%l3 


 ++#J , 
 %)!r   c           
         SU R                   SU R                  SU R                  (       + 4n[        UR                  UR
                   S3UR                  UR                  SS9nU R                  (       a  U R                  OS nU R                  (       a  U R                  OS n[        R                  " UU R                  UUU R                   U R                  U R                  (       + S5      u  nnnn	[        R                  " Xc5        UR                  5       (       a   [        R                  " XpR                  5        U(       a  [        R                  " X5        U(       a  [        R                  " X5        U$ )Nr   r   is_test.quantized.dequantizedF)typer   r4   r   persistabler3   )r6   r7   trainingr   rI   r   r4   r   r<   r=   r   /fake_quantize_dequantize_moving_average_abs_maxr:   assign_out__is_initialized)
r   inputattrs	quant_outstateaccumout1out2out3out4s
             r   dynamic_forward2FakeQuanterWithAbsMaxObserverLayer.dynamic_forward   s.   
 #JJ<56++++
	  $}}$#}}$ BBKK	
	
 	4+!!t[[1t+t+r   c                 @   [        USS/S5        U R                  U R                  U R                  (       + S.nU/U R                  /S.nU R
                  R                  UR                   S3UR                  [        R                  R                  R                  SSS9nU/U R                  /S	.nU R                  (       a@  U R                  /US
'   U R                  /US'   U R                  /US'   U R                  /US'   U R
                  R                  SUUUS9  U$ )NrO   r%   FakeQuantMovingAverageAbsMax)r   r   rG   )XInScalerH   F)r   r   rI   rJ   r;   )OutOutScaleInStateInAccumOutStateOutAccumrL   )rI   inputsoutputsrP   )r   r6   r7   rK   r:   _helpercreate_variabler   r   r   VarDescVarTypeDENSE_TENSORr<   r=   	append_op)r   rO   rP   rd   rQ   re   s         r   static_forward1FakeQuanterWithAbsMaxObserverLayer.static_forward   s    7YK)G	
  ,,**==(

 wDKK=9LL00JJ<56++%%22 1 
	 %+DKK=A==!%F9!%F9#';;-GJ#';;-GJB	 	 	
 r   c           
          U R                   (       a  U R                  OS nU R                   (       a  U R                  OS n[        R                  " UU R
                  UUU R                  U R                  U R                   (       + S5      u  nnnnUn[        R                  " XPR
                  5        U R                   (       a  [        R                  " Xb5        U R                   (       a  [        R                  " Xs5        U$ )Nr3   )	rK   r<   r=   r   rL   r:   r6   r7   rM   )	r   rO   rR   rS   rT   rU   rV   rW   rQ   s	            r   pir_forward.FakeQuanterWithAbsMaxObserverLayer.pir_forward   s    #}}$#}}$ BBKK	
	
 	4-==t+==t+r   c                     [         R                  " 5       (       a  U R                  U5      $ [         R                  R                  R                  5       (       a  U R                  U5      $ U R                  U5      $ r   )paddlein_dynamic_moderX   base	frameworkin_pir_modero   rl   )r   rO   s     r   forward*FakeQuanterWithAbsMaxObserverLayer.forward   s]    !!##''..[[""..00##E**&&u--r   c                     U R                   $ r   )r7   r   s    r   r   -FakeQuanterWithAbsMaxObserverLayer.bit_length  s    r   c                     g)Nr"   r   s    r   
quant_axis-FakeQuanterWithAbsMaxObserverLayer.quant_axis  s    r   c                     U R                   $ r   )r:   r   s    r   scales)FakeQuanterWithAbsMaxObserverLayer.scales	  s    {{r   c                     g r   r"   r   s    r   zero_points.FakeQuanterWithAbsMaxObserverLayer.zero_points  s    r   )r=   r7   r6   r:   r<   )Nr#   r$   r%   )r&   r'   r(   r)   r   rX   rl   ro   rw   r   r}   r   r   r+   r,   r-   s   @r   r   r   `   sG     *)X*X D@.  r   r   )rr   r   paddle.base.data_feederr   paddle.base.frameworkr   paddle.frameworkr   r   paddle.nn.initializerr   paddle.utilsr	   base_quanterr   factoryr   r   r   r"   r   r   <module>r      s?      < 0 , * $ & $B2N B2Jm mr   