
    ёiJ                       % S SK Jr  S SKrS SKJr  S SKrS SKJr  SSKJr  \(       a  S SK	J
r
  SSKJr  \R                  R                  \R                  R                  R                   \R"                  \R                  R$                  R&                  \R(                  \R                  R$                  R*                  0rS	\S
'   \R0                  \R2                  /r " S S5      r " S S5      rg)    )annotationsN)TYPE_CHECKING)nn   )ObserveWrapper)Layer)QuanterFactorydict[Layer, Layer]DEFAULT_QAT_LAYER_MAPPINGSc                  \    \ rS rSrSr      S	S jr\S
S j5       r\S
S j5       rS r	Sr
g)SingleLayerConfig(   a  
Configure how to quantize the activations and weights of a single layer.

Args:
    activation(QuanterFactory): The factory to create instance of quanter used to quantize activations.
    weight(QuanterFactory): The factory to create instance of quanter used to quantize weights.
c                    Xl         X l        g N_activation_weightself
activationweights      Z/var/www/html/banglarbhumi/venv/lib/python3.13/site-packages/paddle/quantization/config.py__init__SingleLayerConfig.__init__1   s     &    c                    U R                   $ r   )r   r   s    r   r   SingleLayerConfig.activation7   s    r   c                    U R                   $ r   )r   r   s    r   r   SingleLayerConfig.weight;   s    ||r   c                :    SU R                    SU R                   3$ )Nzactivation: z	
weight: r   r   s    r   __str__SingleLayerConfig.__str__?   s     d../z$,,HHr   r   N)r   r	   r   r	   returnNone)r$   r	   )__name__
__module____qualname____firstlineno____doc__r   propertyr   r   r"   __static_attributes__ r   r   r   r   (   sR    (2@	      Ir   r   c                     \ rS rSrSr      S S jr  S!       S"S jjr  S!       S#S jjr  S!       S$S jjr      S%S jr	S&S	 jr
\S'S
 j5       rS(S jrS(S jrS(S jrS(S jrS(S jrS(S jrS(S jrS(S jrS(S jr\S)S j5       r\S)S j5       r\S*S j5       rS*S jrS(S jrS+S jrS+S jrS,S jrS(S jrS rS r Sr!g)-QuantConfigC   a  
Configure how to quantize a model or a part of the model. It will map each layer to
an instance of SingleLayerConfig by the settings. It provides diverse methods to set
the strategies of quantization.

Args:
    activation(QuanterFactory | None): The global quantizer used to quantize the activations.
    weight(QuanterFactory | None): The global quantizer used to quantize the weights.

Examples:
    .. code-block:: python

        >>> from paddle.quantization import QuantConfig
        >>> from paddle.quantization.quanters import FakeQuanterWithAbsMaxObserver

        >>> quanter = FakeQuanterWithAbsMaxObserver(moving_rate=0.9)
        >>> q_config = QuantConfig(activation=quanter, weight=quanter)
        >>> print(q_config)
        Global config:
        activation: FakeQuanterWithAbsMaxObserver(name=None,moving_rate=0.9,bit_length=8,dtype=float32)
        weight: FakeQuanterWithAbsMaxObserver(name=None,moving_rate=0.9,bit_length=8,dtype=float32)

c                    Uc  Uc  S U l         O[        X5      U l         0 U l        0 U l        0 U l        S U l        [        R                  " [        5      U l	        0 U l
        / U l        g r   )_global_configr   _layer2config_prefix2config_type2config_modelcopydeepcopyr   _qat_layer_mapping_customized_qat_layer_mapping_customized_leavesr   s      r   r   QuantConfig.__init__\   sd     &."&D"3J"GD "&--0J"K-/*"$r   Nc                    [        U[        5      (       a  U H  nU R                  XBUS9  M     gU R                  UR	                  5       X#S9  g)a  
Set the quantization config by layer. It has the highest priority among
all the setting methods.

Args:
    layer(Layer|list[Layer]]): One or a list of layers.
    activation(QuanterFactory | None): Quanter used for activations. Default is None.
    weight(QuanterFactory | None): Quanter used for weights. Default is None.

Examples:
    .. code-block:: python

        >>> import paddle
        >>> from paddle.nn import Linear
        >>> from paddle.quantization import QuantConfig
        >>> from paddle.quantization.quanters import FakeQuanterWithAbsMaxObserver

        >>> class Model(paddle.nn.Layer):
        ...    def __init__(self):
        ...        super().__init__()
        ...        self.fc = Linear(576, 120)
        >>> model = Model()
        >>> quanter = FakeQuanterWithAbsMaxObserver(moving_rate=0.9)
        >>> q_config = QuantConfig(activation=None, weight=None)
        >>> q_config.add_layer_config([model.fc], activation=quanter, weight=quanter)
        >>> # doctest: +SKIP('random memory address')
        >>> print(q_config)
        Global config:
        None
        Layer prefix config:
        {'linear_0': <paddle.quantization.config.SingleLayerConfig object at 0x7fe41a680ee0>}

r   r   N)
isinstancelistadd_layer_configadd_name_config	full_name)r   layerr   r   _elements        r   rA   QuantConfig.add_layer_configl   sU    N eT""!%%F &  "
   !j ! r   c                    [        U[        5      (       a  [        X#5      nX@R                  U'   [        U[        5      (       a  U H  nU R                  XRUS9  M     gg)a  
Set the quantization config by full name of layer. Its priority is
lower than `add_layer_config`.

Args:
    layer_name(str|list[str]): One or a list of layers' full name.
    activation(QuanterFactory | None): Quanter used for activations. Default is None.
    weight(QuanterFactory | None): Quanter used for weights. Default is None.

Examples:
    .. code-block:: python

        >>> import paddle
        >>> from paddle.nn import Linear
        >>> from paddle.quantization import QuantConfig
        >>> from paddle.quantization.quanters import FakeQuanterWithAbsMaxObserver

        >>> class Model(paddle.nn.Layer):
        ...     def __init__(self):
        ...         super().__init__()
        ...         self.fc = Linear(576, 120)
        >>> model = Model()
        >>> quanter = FakeQuanterWithAbsMaxObserver(moving_rate=0.9)
        >>> q_config = QuantConfig(activation=None, weight=None)
        >>> q_config.add_name_config([model.fc.full_name()], activation=quanter, weight=quanter)
        >>> # doctest: +SKIP('random memory address')
        >>> print(q_config)
        Global config:
        None
        Layer prefix config:
        {'linear_0': <paddle.quantization.config.SingleLayerConfig object at 0x7fe41a680fd0>}

r>   N)r?   strr   r4   r@   rB   )r   
layer_namer   r   configrE   s         r   rB   QuantConfig.add_name_config   s^    N j#&&&z:F.4
+j$''&$$F %  ' (r   c                   [        U[        5      (       aB  [        U[        R                  R
                  5      (       a  [        X#5      nX@R                  U'   [        U[        5      (       a  U H  nU R                  XRUS9  M     gg)a  
Set the quantization config by the type of layer. The `layer_type` should be
subclass of `paddle.nn.Layer`. Its priority is lower than `add_layer_config`
and `add_name_config`.

Args:
    layer_type(type[Layer] | list[type[Layer]]): One or a list of layers' type. It should be subclass of
    `paddle.nn.Layer`. Python built-in function `type()` can be used to get the type of a layer.
    activation(QuanterFactory | None): Quanter used for activations. Default is None.
    weight(QuanterFactory | None): Quanter used for weights. Default is None.

Examples:
    .. code-block:: pycon

        >>> import paddle
        >>> from paddle.nn import Linear
        >>> from paddle.quantization import QuantConfig
        >>> from paddle.quantization.quanters import (
        ...     FakeQuanterWithAbsMaxObserver,
        ... )

        >>> class Model(paddle.nn.Layer):
        ...     def __init__(self):
        ...         super().__init__()
        ...         self.fc = Linear(576, 120)
        >>> model = Model()
        >>> quanter = FakeQuanterWithAbsMaxObserver(moving_rate=0.9)
        >>> q_config = QuantConfig(activation=None, weight=None)
        >>> q_config.add_type_config([Linear], activation=quanter, weight=quanter)
        >>> # doctest: +SKIP('random memory address')
        >>> print(q_config)
        Global config:
        None
        Layer type config:
        {<class 'paddle.nn.layer.common.Linear'>: <paddle.quantization.config.SingleLayerConfig object at 0x7fe41a680a60>}

r>   N)
r?   type
issubclasspaddler   r   r   r5   r@   add_type_config)r   
layer_typer   r   rJ   rE   s         r   rP   QuantConfig.add_type_config   sy    V j$''J		-
 -
 'z:F,2j)j$''&$$F %  ' (r   c                P   [        U[        5      (       a)  [        U[        R                  R
                  5      (       d   S5       e[        U[        5      (       a)  [        U[        R                  R
                  5      (       d   S5       eX R                  U'   X R                  U'   g)ah  
Add rules converting layers to simulated quantization layers
before quantization-aware training. It will convert layers
with type `source` to layers with type `target`. `source` and
`target` should be subclass of `paddle.nn.Layer`. And a default
mapping is provided by property `default_qat_layer_mapping`.

Args:
    source(type[Layer]): The type of layers that will be converted.
    target(type[Layer]): The type of layers that will be converted to.

Examples:
    .. code-block:: pycon

        >>> import paddle
        >>> from paddle.nn import Conv2D
        >>> from paddle.quantization import QuantConfig
        >>> from paddle.quantization.quanters import (
        ...     FakeQuanterWithAbsMaxObserver,
        ... )
        >>> quanter = FakeQuanterWithAbsMaxObserver(moving_rate=0.9)
        >>> q_config = QuantConfig(activation=None, weight=None)
        >>> class CustomizedQuantedConv2D(paddle.nn.Layer):
        ...     def forward(self, x):
        ...         pass
        ...         # add some code for quantization simulation
        >>> q_config.add_qat_layer_mapping(Conv2D, CustomizedQuantedConv2D)
zEThe source layer to be placed should be a subclass of paddle.nn.Layerz<The target layer should be a subclass of paddle.nn.qat.LayerN)r?   rM   rN   rO   r   r   r9   r:   )r   sourcetargets      r   add_qat_layer_mapping!QuantConfig.add_qat_layer_mapping  s    > &$''JFIIOO-
 -
 	
 T	
 

 &$''JFIIOO-
 -
 	JI	J 
 +1'5;**62r   c                :    U R                   R                  U5        g)aB  
Declare the customized layer as leaf of model for quantization.
The leaf layer is quantized as one layer. The sublayers of
leaf layer will not be quantized.

Args:
    layer_type(type[Layer]): The type of layer to be declared as leaf.

Examples:
    .. code-block:: python

        >>> from paddle.nn import Sequential
        >>> from paddle.quantization import QuantConfig
        >>> from paddle.quantization.quanters import FakeQuanterWithAbsMaxObserver
        >>> q_config = QuantConfig(activation=None, weight=None)
        >>> q_config.add_customized_leaf(Sequential)

N)r;   append)r   rQ   s     r   add_customized_leafQuantConfig.add_customized_leaf-  s    & 	&&z2r   c                    U R                   $ )z 
Get all the customized leaves.
)r;   r   s    r   customized_leavesQuantConfig.customized_leavesB  s    
 &&&r   c                T    U R                  U5      =(       a    U R                  U5      $ )z3
Whether the layer should be observed by observer.
)_is_leaf_has_observer_configr   rD   s     r   _need_observeQuantConfig._need_observeI  s#     }}U#H(A(A%(HHr   c                    U R                  U5      nU R                  R                  [        U5      U R                  R                  [        U5      5      5      nU" X5      $ r   )_get_config_by_layerr:   getrM   qat_layer_mappings)r   rD   q_configtarget_types       r   _get_qat_layerQuantConfig._get_qat_layerO  sS    ,,U388<<K0044T%[A
 5++r   c                V    U R                  U5      nUSL=(       a    UR                  SL$ )zD
Whether the layer has been configured for activation quantization.
N)rf   r   )r   rD   _configs      r   ra    QuantConfig._has_observer_configW  s/     ++E2d"Ew'9'9'EEr   c                    U R                  U5      =(       d)    U R                  U5      =(       d    U R                  U5      $ r   )_is_default_leaf_is_real_leaf_is_customized_leafrb   s     r   r`   QuantConfig._is_leaf^  s;    !!%( /!!%(/''.	
r   c                &    [        U5      [        ;   $ r   )rM   DEFAULT_LEAVESrb   s     r   rq   QuantConfig._is_default_leafe  s    E{n,,r   c                \    UR                   SL =(       d    [        UR                   5      S:H  $ )z1
The leaf is real leaf when it has no sublayers.
Nr   )_sub_layerslenrb   s     r   rr   QuantConfig._is_real_leafh  s*       D(GC0A0A,Ba,GGr   c                2    [        U5      U R                  ;   $ r   )rM   r]   rb   s     r   rs   QuantConfig._is_customized_leafn  s    E{d4444r   c                r    U R                  U5      nUc  SOUR                  nUc  S$ UR                  U5      $ )z_
Create an instance of observer or quanter according to the
given layer's quantization config.
N)rf   r   	_instance)r   rD   rn   	_observers       r   _get_observerQuantConfig._get_observerq  s@    
 ++E2#OD1C1C	 (tHi.A.A%.HHr   c                :    U R                  U5      n[        X!5      $ r   )r   r   )r   rD   r   s      r   _get_observe_wrapper QuantConfig._get_observe_wrapperz  s    &&u-	i//r   c                    U R                   $ r   )r9   r   s    r   rh   QuantConfig.qat_layer_mappings~  s    &&&r   c                    [         $ r   )r   r   s    r   default_qat_layer_mapping%QuantConfig.default_qat_layer_mapping  s    ))r   c                    U R                   $ r   )r2   r   s    r   global_configQuantConfig.global_config  s    """r   c                :    U R                   R                  US 5      $ r   )r3   rg   rb   s     r   rf    QuantConfig._get_config_by_layer  s    !!%%eT22r   c                    XR                   ;   $ )zi
The layer is quantifiable when it configured by activation quanter/observer
or weight quanter/observer.
)r3   rb   s     r   _is_quantifiableQuantConfig._is_quantifiable  s    
 ****r   c                F    Xl         U R                  U R                   5        g)ay  
Specify the quantization config of each sublayer in model.
For each layer in sublayers of mode,
1. Set the config by global config
2. Overwrite the config with parents' config
3. Overwrite the config with config set by layer's type
4. Overwrite the config with config set by layer's full name
5. Overwrite the config with config set by layer

Args:
    model(Layer): The model to be specified by the config.

Examples:
    .. code-block:: python

        >>> import paddle
        >>> from paddle.nn import Linear, Sequential
        >>> from paddle.quantization import QuantConfig
        >>> from paddle.quantization.quanters import FakeQuanterWithAbsMaxObserver

        >>> class Model(paddle.nn.Layer):
        ...     def __init__(self):
        ...         super().__init__()
        ...         self.fc = Sequential(Linear(576, 120),Linear(576, 120))
        >>> model = Model()
        >>> quanter = FakeQuanterWithAbsMaxObserver(moving_rate=0.9)
        >>> q_config = QuantConfig(activation=None, weight=None)
        >>> q_config.add_layer_config([model.fc], activation=quanter, weight=quanter)
        >>> q_config._specify(model)
N)r6   _specify_helper)r   models     r   _specifyQuantConfig._specify  s    > T[[)r   c                b   UR                  5        H  nUR                  5       nU R                  R                  XR                  5      nU R
                  R                  [        U5      U5      nU R                  R                  X45      nUb  X@R                  U'   U R                  U5        M     U $ r   )	childrenrC   r3   rg   r   r5   rM   r4   r   )r   r   childlayer_prefixrJ   s        r   r   QuantConfig._specify_helper  s    ^^%E ??,L''++E3E3EFF&&**4;?F((,,\BF!,2""5)  ' & r   c                r    U R                   c  U R                  5       $ U R                  U R                   5      $ )z.
Get the formatted details of current config.
)r6   r"   _details_helperr   s    r   detailsQuantConfig.details  s/     ;;<<>!##DKK00r   c                   / nUR                  5        Ho  u  p4U R                  U5      nU R                  US5      nX@R                  ;   d  M9  UR	                  SU-   S-   U-   S-   [        U R                  U   5      -   5        Mq     UR                  R                  S-   nU(       a  USSR                  U5      -   S-   -  nUS-  nU$ )N   (z): z, z
  
))	named_childrenr   
_addindentr3   rY   rH   	__class__r&   join)r   rD   sublayer_linesnamesublayersublayer_str	final_strs          r   r   QuantConfig._details_helper  s    #224ND//9L??<;L---%% ## 	
 $,,X678	 5 OO,,s2	&++n"==DDIS	r   c                    UR                  S5      n[        U5      S:X  a  U$ / n[        U5       H-  u  pVUS:  d  M  UR                  [	        US-  U-   5      5        M/     US   S-   SR                  U5      -   $ )Nr   r   r    )splitrz   	enumeraterY   rH   r   )r   stringindents1s2idxlines          r   r   QuantConfig._addindent  ss    \\$r7a<M"2ICQw		#v|t345 ' !ut|diim++r   c                    SnUSU R                    S3-  n[        U R                  5      S:  a  USU R                   S3-  n[        U R                  5      S:  a  USU R                   S3-  nU$ )N zGlobal config:
r   r   zLayer type config:
zLayer prefix config: 
)r2   rz   r5   r4   )r   results     r   r"   QuantConfig.__str__  s    $T%8%8$9<<t  !A%,T->->,?rBBFt""#a'/0C0C/DBGGFr   )r;   r:   r2   r3   r6   r4   r9   r5   )r   QuanterFactory | Noner   r   r$   r%   )NN)rD   zLayer | list[Layer]r   r   r   r   r$   r%   )rI   zstr | list[str]r   r   r   r   r$   r%   )rQ   ztype[Layer] | list[type[Layer]]r   r   r   r   r$   r%   )rT   type[Layer]rU   r   r$   r%   )rQ   r   r$   r%   )r$   zlist[type[Layer]])rD   r   )r$   r
   )r$   r   )r   r   )r$   rH   )"r&   r'   r(   r)   r*   r   rA   rB   rP   rV   rZ   r+   r]   rc   rk   ra   r`   rq   rr   rs   r   r   rh   r   r   rf   r   r   r   r   r   r   r"   r,   r-   r   r   r/   r/   C   s   0%/%9N%	%& -1(,	/"/ */ &	/
 
/h -1(,	.#. *. &	.
 
.f -1(,	434 *4 &	4
 
4l(<!(<+6(<	(<T3* ' 'I,F
-H5I0 ' ' * * # #3+ *D
1,,r   r/   )
__future__r   r7   typingr   rO   r   wrapperr   	paddle.nnr   factoryr	   quantStubstubQuanterStubLinearqatQuantedLinearConv2DQuantedConv2Dr   __annotations__ReLU	AvgPool2Drv   r   r/   r-   r   r   <module>r      s    #      #'
 HHMM288==,,IIrxx||))IIrxx||))2 .  ''2<<(I I6n nr   