Ë
    g^(h7$  ã            	       óN  — d dl Z d dlmZ d dlmZ d dlmZ d dlmZm	Z	m
Z
mZmZmZmZ d dlmZmZ d dlmZ dd	lmZ dd
lmZmZ ddlmZ ddlmZmZmZ ddlm Z  g d¢Z!dededefd„Z"dededefd„Z#e jH                  jJ                  jL                  jN                  e jH                  jJ                  jL                  jP                  e jH                  jJ                  jR                  jN                  e jH                  jT                  jV                  gZ,dede-fd„Z.	 	 ddede-de-defd„Z/y)é    N)Úconstant_fold)ÚDuplicateDQPass)ÚPortNodeMetaForQDQ)ÚDerivedQuantizationSpecÚFixedQParamsQuantizationSpecÚQuantizationAnnotationÚQuantizationSpecÚQuantizationSpecBaseÚ	QuantizerÚSharedQuantizationSpec)ÚGraphModuleÚNode)ÚPassManageré   )Úprepare)Ú_fold_conv_bn_qatÚ_fuse_conv_bn_qat)Ú reference_representation_rewrite)Ú_disallow_eval_trainÚ_fuse_conv_bn_Ú_get_node_name_to_scope)Ú#_convert_to_reference_decomposed_fx)Úprepare_pt2eÚprepare_qat_pt2eÚconvert_pt2eÚmodelÚ	quantizerÚreturnc                 ól  — t         j                  j                  d«       | j                  }t	        | «      }t        | «       |j                  | «      } |j                  | «       |j                  | «       t        | |d|j                  ¬«      } | j                  j                  |«       t        | «      } | S )a¬  Prepare a model for post training quantization

    Args:
      * `model` (torch.fx.GraphModule): a model captured by `torch.export.export_for_training` API.
      * `quantizer`: A backend specific quantizer that conveys how user want the
        model to be quantized. Tutorial for how to write a quantizer can be found here:
        https://pytorch.org/tutorials/prototype/pt2e_quantizer.html

    Return:
      A GraphModule with observer (based on quantizer annotation), ready for calibration

    Example::

        import torch
        from torch.ao.quantization.quantize_pt2e import prepare_pt2e
        from torch.ao.quantization.quantizer import (
            XNNPACKQuantizer,
            get_symmetric_quantization_config,
        )

        class M(torch.nn.Module):
            def __init__(self) -> None:
                super().__init__()
                self.linear = torch.nn.Linear(5, 10)

           def forward(self, x):
               return self.linear(x)

        # initialize a floating point model
        float_model = M().eval()

        # define calibration function
        def calibrate(model, data_loader):
            model.eval()
            with torch.no_grad():
                for image, target in data_loader:
                    model(image)

        # Step 1. program capture
        # NOTE: this API will be updated to torch.export API in the future, but the captured
        # result shoud mostly stay the same
        m = torch.export.export_for_training(m, *example_inputs).module()
        # we get a model with aten ops

        # Step 2. quantization
        # backend developer will write their own Quantizer and expose methods to allow
        # users to express how they
        # want the model to be quantized
        quantizer = XNNPACKQuantizer().set_global(get_symmetric_quantization_config())
        m = prepare_pt2e(m, quantizer)

        # run calibration
        # calibrate(m, sample_inference_data)
    z+quantization_api.quantize_pt2e.prepare_pt2eF©Úis_qatÚobs_or_fq_callback)ÚtorchÚ_CÚ_log_api_usage_onceÚmetar   r   Útransform_for_annotationÚannotateÚvalidater   Úprepare_obs_or_fq_callbackÚupdater   ©r   r   Úoriginal_graph_metaÚnode_name_to_scopes       úa/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/torch/ao/quantization/quantize_pt2e.pyr   r      s£   € ôt 
‡H�H× Ñ Ð!NÔOØŸ*™*ÐÜ0°Ó7Ðô �5ÔØ×.Ñ.¨uÓ5€EØ×Ñ�uÔØ×Ñ�uÔÜØØØØ$×?Ñ?ô	€Eð 
‡J�J×ÑÐ)Ô*Ü  Ó'€EØ€Ló    c                 ól  — t         j                  j                  d«       | j                  }t	        | «      }|j                  | «      } |j                  | «       |j                  | «       t        | «       t        | |d|j                  ¬«      } | j                  j                  |«       t        | «      } | S )a9  Prepare a model for quantization aware training

    Args:
      * `model` (torch.fx.GraphModule): see :func:`~torch.ao.quantization.quantize_pt2e.prepare_pt2e`
      * `quantizer`: see :func:`~torch.ao.quantization.quantize_pt2e.prepare_pt2e`

    Return:
      A GraphModule with fake quant modules (based on quantizer annotation), ready for
      quantization aware training

    Example::
        import torch
        from torch.ao.quantization.quantize_pt2e import prepare_qat_pt2e
        from torch.ao.quantization.quantizer import (
            XNNPACKQuantizer,
            get_symmetric_quantization_config,
        )

        class M(torch.nn.Module):
            def __init__(self) -> None:
                super().__init__()
                self.linear = torch.nn.Linear(5, 10)

           def forward(self, x):
               return self.linear(x)

        # initialize a floating point model
        float_model = M().eval()

        # define the training loop for quantization aware training
        def train_loop(model, train_data):
            model.train()
            for image, target in data_loader:
                ...

        # Step 1. program capture
        # NOTE: this API will be updated to torch.export API in the future, but the captured
        # result shoud mostly stay the same
        m = torch.export.export_for_training(m, *example_inputs).module()
        # we get a model with aten ops

        # Step 2. quantization
        # backend developer will write their own Quantizer and expose methods to allow
        # users to express how they
        # want the model to be quantized
        quantizer = XNNPACKQuantizer().set_global(get_symmetric_quantization_config())
        m = prepare_qat_pt2e(m, quantizer)

        # run quantization aware training
        train_loop(prepared_model, train_loop)

    z/quantization_api.quantize_pt2e.prepare_qat_pt2eTr    )r#   r$   r%   r&   r   r'   r(   r)   r   r   r*   r+   r   r,   s       r/   r   r   n   s£   € ôp 
‡H�H× Ñ Ð!RÔSØŸ*™*ÐÜ0°Ó7ÐØ×.Ñ.¨uÓ5€EØ×Ñ�uÔØ×Ñ�uÔô �eÔÜØØØØ$×?Ñ?ô	€Eð 
‡J�J×ÑÐ)Ô*Ü  Ó'€EØ€Lr0   Únc                 óH   — | j                   dk(  xr | j                  t        v S )aT  If there is any pure ops between get_attr and quantize op they will be const propagated
    e.g. get_attr(weight) -> transpose -> quantize -> dequantize*
    (Note: dequantize op is not going to be constant propagated)

    This filter is added because we don't want to constant fold the things that are not
    related to quantization
    Úcall_function)ÚopÚtargetÚ
_QUANT_OPS)r2   s    r/   Ú_quant_node_constraintr8   Ã   s!   € ð �4‰4�?Ñ"Ò= q§x¡x´:Ð'=Ð=r0   Úuse_reference_representationÚfold_quantizec                 óè  — t         j                  j                  d«       t        |t        «      st        d|› d�«      ‚| j                  }t        | «      } t        | «      } t        t        «       g«      } || «      j                  } t        t        «       g«      } || «      j                  } |rt        | t        «       |rt        | «      } | j                  j!                  |«       t#        | «      } | S )aÛ  Convert a calibrated/trained model to a quantized model

    Args:
      * `model` (torch.fx.GraphModule): calibrated/trained model
      * `use_reference_representation` (bool): boolean flag to indicate whether to produce referece representation or not
      * `fold_quantize` (bool): boolean flag for whether fold the quantize op or not

    Returns:
        quantized model, either in q/dq representation or reference representation

    Example::

        # prepared_model: the model produced by `prepare_pt2e`/`prepare_qat_pt2e` and calibration/training
        # `convert_pt2e` produces a quantized model that represents quantized computation with
        # quantize dequantize ops and fp32 ops by default.
        # Please refer to
        # https://pytorch.org/tutorials/prototype/pt2e_quant_ptq_static.html#convert-the-calibrated-model-to-a-quantized-model
        # for detailed explanation of output quantized model
        quantized_model = convert_pt2e(prepared_model)

    z+quantization_api.quantize_pt2e.convert_pt2ezjUnexpected argument type for `use_reference_representation`, please make sure you intend to pass argument z to convert_pt2e)r#   r$   r%   Ú
isinstanceÚboolÚ
ValueErrorr&   r   r   r   r   Úgraph_moduler   r   r8   r   r+   r   )r   r9   r:   r-   Úpms        r/   r   r   Î   sß   € ô4 
‡H�H× Ñ Ð!NÔOÜÐ2´DÔ9Üð<Ø<XÐ;YÐYiðkó
ð 	
ð  Ÿ*™*ÐÜ/°Ó6€EÜ˜eÓ$€Eä	”oÓ'Ð(Ó	)€BÙˆu‹I×"Ñ"€Eä	Ô(Ó*Ð+Ó	,€BÙˆu‹I×"Ñ"€EáÜ�eÔ3Ô4á#Ü0°Ó7ˆà	‡J�J×ÑÐ)Ô*Ü  Ó'€EØ€Lr0   )FT)0r#   Ú%torch._export.passes.constant_foldingr   Ú,torch.ao.quantization.pt2e.duplicate_dq_passr   Ú-torch.ao.quantization.pt2e.port_metadata_passr   Útorch.ao.quantization.quantizerr   r   r   r	   r
   r   r   Útorch.fxr   r   Ú"torch.fx.passes.infra.pass_managerr   Úpt2e.preparer   Úpt2e.qat_utilsr   r   Úpt2e.representationr   Ú
pt2e.utilsr   r   r   Úquantize_fxr   Ú__all__r   r   ÚopsÚquantized_decomposedÚquantize_per_tensorÚdefaultÚtensorÚquantize_per_channelÚ
pt2e_quantÚquantize_affiner7   r=   r8   r   © r0   r/   ú<module>rV      s4  ðÛ Ý ?Ý HÝ L÷÷ ñ ÷ 'Ý :å !ß @Ý Aß UÑ UÝ <ò€ðLØðLàðLð óLð^JØðJàðJð óJð\ 
‡I�I×"Ñ"×6Ñ6×>Ñ>Ø	‡I�I×"Ñ"×6Ñ6×=Ñ=Ø	‡I�I×"Ñ"×7Ñ7×?Ñ?Ø	‡I�I×Ñ×(Ñ(ð	€
ð>˜dð > tó >ð */Øñ2Øð2à"&ð2ð ð2ð ô	2r0   