ó
    pˆjâ   ã                   óœ   • 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        €Ú`/var/www/html/pdf-tiff/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/X•S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/XµS9U l        SU R                  l
        g )Nz.scalezquant_dequant.scalegü©ñÒMbP?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                  " X„5        U(       a  [        R                  " X•5        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_forwardÚ2FakeQuanterWithAbsMaxObserverLayer.dynamic_forward   s.  € àØ×ÑØØ×ÑØØ—‘Ôð
ˆô #Ø—‘Ø—J‘J<Ð5Ð6Ø—+‘+Ø—+‘+Øñ
ˆ	ð  $Ÿ}Ÿ}—’°$ˆØ#Ÿ}Ÿ}—’°$ˆô ×BÒBØØK‰KØØØ×ÑØ×ÑØ—‘ÔØó	
ñ	
ØØØØô 	×Ò˜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_forwardÚ1FakeQuanterWithAbsMaxObserverLayer.static_forward¹   s  € Ü Ø7˜Y˜KÐ)Gô	
ð  ×,Ñ,Ø×*Ñ*ØŸ=™=Ô(ñ
ˆð
 w¨D¯K©K¨=Ñ9ˆØ—L‘L×0Ñ0Ø—J‘J<Ð5Ð6Ø—+‘+Ü—‘×%Ñ%×2Ñ2ØØð 1ð 
ˆ	ð %˜+°D·K±K°=Ñ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ØØK‰KØØØ×ÑØ×ÑØ—‘ÔØó	
ñ	
ØØØØð ˆ	Ü×Ò˜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)Néÿÿÿÿr"   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2 Nô B2ôJm¨õ mr   