Ë
    g^(h©w  ã                   óö  — d dl Z d dlZd dlZd dlZd dlZd dlmc mc m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 d dlmZ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%m&Z& g d
¢Z'eZ(ejR                  ejT                  jR                  ejV                  ejT                  jV                  iejT                  jR                  ej                  jR                  ejT                  jV                  ej                  jV                  idœZ,d„ Z-	 	 	 d!d„Z.d"d„Z/d„ Z0d„ Z1d#d„Z2	 	 	 	 d$d„Z3d„ Z4d„ Z5	 	 	 	 d%d„Z6d„ Z7d„ Z8d&d„Z9dejt                  ddfd„Z;d&d„Z<d#d„Z=	 	 	 	 	 	 d'd„Z>	 	 	 	 	 d(d„Z?	 d#d„Z@d)d „ZAy)*é    N)Ú_FusedModule)Ú_is_activation_post_process)Ú_activation_is_memorylessÚ_add_module_to_qconfig_obs_ctrÚdefault_dynamic_qconfigÚfloat16_dynamic_qconfigÚ!float_qparams_weight_only_qconfigÚ&float_qparams_weight_only_qconfig_4bit)Ú_get_special_act_post_processÚ_has_special_act_post_processÚ)get_default_dynamic_quant_module_mappingsÚget_default_qat_module_mappingsÚ$get_default_qconfig_propagation_listÚ(get_default_static_quant_module_mappingsÚ2get_default_static_quant_reference_module_mappingsÚno_observer_set)ÚDeQuantStubÚQuantWrapper)Útype_before_parametrizationsé   )Úget_qparam_dictÚ)has_no_children_ignoring_parametrizations)
Úget_default_custom_config_dictÚpropagate_qconfig_Úadd_quant_dequantÚprepareÚquantizeÚquantize_dynamicÚprepare_qatÚquantize_qatÚconvertÚswap_module)Ú%float_to_observed_custom_module_classÚ)observed_to_quantized_custom_module_classc                  ó   — t         S )z'Defines the default custom config dict.)Ú_DEFAULT_CUSTOM_CONFIG_DICT© ó    ú\/var/www/skyplay_api_hub/venv/lib/python3.12/site-packages/torch/ao/quantization/quantize.pyr   r   B   s   € ä&Ð&r(   c                 óÔ  — |j                  t        | «      |«      }|j                  ||«      }t        | d|«      }t        j                  j
                  j                  j                  || «       t        || «      }|| _        | j                  «       D ]T  \  }}|r|dz   |z   n|}	|�3||j                  dg «      v rŒ)t        |«      |j                  dg «      v rŒGt        ||||	«       ŒV y)aò  This is a helper function for `propagate_qconfig_`

    Args:
        module: input module
        qconfig_dict: dictionary that maps from name of submodule to quantization
                     configuration
        qconfig_parent: quantization config of parent module, we will fallback to
                       this config when there is no specified config for current
                       module
        prefix: corresponding prefix of the current module, used as key in
                qconfig_dict
        prepare_custom_config_dict: dictionary for custom handling of modules
                                    see docs for :func:`~torch.ao.quantization.prepare_fx`

    Return:
        None, module is modified inplace with qconfig attached
    Úqconfigú.NÚnon_traceable_module_nameÚnon_traceable_module_class)Úgetr   ÚgetattrÚtorchÚaoÚquantizationr+   Ú_assert_valid_qconfigr   Únamed_childrenÚtypeÚ_propagate_qconfig_helper)
ÚmoduleÚqconfig_dictÚqconfig_parentÚprefixÚprepare_custom_config_dictÚmodule_qconfigÚqconfig_with_device_checkÚnameÚchildÚmodule_prefixs
             r)   r7   r7   G   sò   € ð2 "×%Ñ%Ü$ VÓ,¨nó€Nð "×%Ñ% f¨nÓ=€NÜ˜V Y°Ó?€Nä	‡H�H×Ñ×!Ñ!×7Ñ7¸ÈÔOä >¸~ÈvÓ VÐØ.€F„Nà×,Ñ,Ó.ò 
‰ˆˆeÙ/5˜ ™ tÒ+¸4ˆà%Ð-ØÐ.×2Ñ2Ð3NÐPRÓSÒSÜ�E‹{Ø)×-Ñ-Ð.JÈBÓOòPô &Ø�|Ð%>Àõñ
r(   c                 ó0   — |€i }|€i }t        | ||¬«       y)a“  Propagate qconfig through the module hierarchy and assign `qconfig`
    attribute on each leaf module

    Args:
        module: input module
        qconfig_dict: dictionary that maps from name or type of submodule to
            quantization configuration, qconfig applies to all submodules of a
            given module unless qconfig for the submodules are specified (when
            the submodule already has qconfig attribute)
        prepare_custom_config_dict: dictionary for custom handling of modules
            see docs for :func:`~torch.ao.quantization.prepare_fx`

    Return:
        None, module is modified inplace with qconfig attached
    N)r<   )r7   )r8   r9   r<   s      r)   r   r   x   s+   € ð  ÐØˆØ!Ð)Ø%'Ð"ÜØ�Ð9Sör(   c                 ó$   — | j                  |«      S )z.Forward hook that calls observer on the output©Úactivation_post_process)ÚselfÚinputÚoutputs      r)   Ú_observer_forward_hookrI   ‘   s   € à×'Ñ'¨Ó/Ð/r(   c                 ó*   — | j                  |d   «      S )z2Forward pre hook that calls observer on the outputr   rD   )rF   rG   s     r)   Ú_observer_forward_pre_hookrK   –   s   € à×'Ñ'¨¨a©Ó1Ð1r(   Fc                 óŒ   — t        | d«      sJ d«       ‚|r| j                  t        d¬«       y | j                  t        d¬«       y )NrE   zGExpect activation_post_process attribute already attached to the moduleT)Úprepend)ÚhasattrÚregister_forward_pre_hookrK   Úregister_forward_hookrI   )r8   Úpre_hooks     r)   Ú&_register_activation_post_process_hookrR   ›   sQ   € ÜØÐ)ôð QàPóQð ñ Ø×(Ñ(Ô)CÈTÐ(ÕRà×$Ñ$Ô%;ÀTÐ$ÕJr(   c                 ó  ‡‡‡— |€
t        «       }|€i }‰€Gt        | «      }t        |«      dk  s
J d|› �«       ‚t        |«      dkD  rt        t	        |«      «      ndŠdd„Šd„ Šdˆˆˆfd„	}| j                  «       D �]t  \  }}t        |«      t        j                  fv rŒ$t        t        |«      t        j                  t        j                  f«      rB ‰|«      sŒ`t        |d«      sJ d	t        |«      › d
�«       ‚ ‰|j                  ‰«      |_        Œ™t!        |t"        «      r ‰|«      sŒ² ||«       Œ»|�t        |«      |v r ‰|«      sŒÓ ||«       ŒÜt%        |«      rt'        |«      }	 |||	«       Œü ‰|«      rbt        |«      |v rU|t        |«         }
|
j)                  |«      }t+        | ||«       t        |
t-        t/        «       «      «      r�Œ\ ||«       �Œft1        |||‰|«       �Œw t3        | «      r9t!        | t4        j                  j6                  «      st        | «      |v r || «       t        | d«      r<t!        | t4        j                  j6                  «      st        | «      |v r	 || «       yyyy)as  Add observer for the leaf child of the module.

    This function insert observer module to all leaf child module that
    has a valid qconfig attribute.

    Args:
        module: input module with qconfig attributes for all the leaf modules that we want to quantize
        qconfig_propagation_list: a list of quantizable modules that will have observers added to them
            if they are leaf nodes
        device: parent device, if any
        non_leaf_module_list: list of non-leaf modules we want to add observer

    Return:
        None, module is modified inplace with added observer modules and forward_hooks
    Nr   zR_add_observer_ only works with cpu or single-device CUDA modules, but got devices r   c                 ó^   — |€| j                  «       n |«       }|�|j                  |«       |S ©N)Ú
activationÚto)r+   ÚdeviceÚspecial_act_post_processrV   s       r)   Úget_activation_post_processz3_add_observer_.<locals>.get_activation_post_processÉ   s=   € ð (Ð/ð ×ÑÔ á)Ó+ð 	ð
 ÐØ�M‰M˜&Ô!ØÐr(   c                 ó:   — t        | d«      xr | j                  d uS )Nr+   ©rN   r+   )Úms    r)   Úneeds_observationz)_add_observer_.<locals>.needs_observationÓ   s   € Ü�q˜)Ó$Ò>¨¯©¸$Ð)>Ð>r(   c                 óÂ   •—  ‰| «      rVt        | t        «      sE| j                  d ‰| j                  ‰|«      «       t	        | t        | j                  «      ¬«       yyy)zmAdds an activation post process module and register
        a pre or post hook that calls the module
        rE   ©rQ   N)Ú
isinstancer   Ú
add_moduler+   rR   r   )r]   rY   rX   rZ   r^   s     €€€r)   Úinsert_activation_post_processz6_add_observer_.<locals>.insert_activation_post_processÖ   s[   ø€ ñ
 ˜QÔ¬
°1´kÔ(Bà�L‰LØ)Ù+Ø—I‘I˜vÐ'?óôô 3ØÔ5°a·i±iÓ@öð )CÐr(   rE   zfunctional class z- has no pre-defined `activation_post_process`Úweight_fake_quantrU   )r   Ú_get_unique_devices_ÚlenÚnextÚiterr5   r   ÚnnÚDropoutÚ
issubclassÚnnqÚFloatFunctionalÚQFunctionalrN   r+   rE   ra   r   r   r   Ú
from_floatÚsetattrÚtupler   Ú_add_observer_r   r1   Ú
Sequential)r8   Úqconfig_propagation_listÚnon_leaf_module_listrX   Úcustom_module_class_mappingÚdevicesrc   r?   r@   rY   Úobserved_classÚobserved_childrZ   r^   s      `        @@r)   rr   rr   ¥   s�  ú€ ð,  Ð'Ü#GÓ#IÐ à"Ð*Ø&(Ð#ð €~Ü& vÓ.ˆä�‹L˜AÒð	jà_Ð`gÐ_hÐió	jØä(+¨G«°qÒ(8””d˜7“mÔ$¸dˆóò?÷ð& ×,Ñ,Ó.ó /‰ˆˆeä'¨Ó.´2·:±:°,Ñ>ØÜÜ(¨Ó/´#×2EÑ2EÄsÇÁÐ1Wô
ñ ! Õ'ÜØÐ4ôð zà&Ô'CÀEÓ'JÐ&KÐKxÐyózð ñ 1LØ—M‘M 6ó1�Õ-ô ˜œ|Ô,á  Õ'Ù.¨uÕ5à Ð,Ü,¨UÓ3Ð7KÑKá  Õ'Ù.¨uÕ5Ü*¨5Ô1Ü'DÀUÓ'KÐ$Ù*¨5Ð2JÕKá˜eÔ$Ü,¨UÓ3Ð7RÑRà8Ü,¨UÓ3ñˆNð ,×6Ñ6°uÓ=ˆNÜ�F˜D .Ô1ô ˜n¬e´OÓ4EÓ.FÖGÙ.¨~Ö>äØØ(Ø$ØØ+öðS/ôh 	2°&Ô9Ü˜6¤5§8¡8×#6Ñ#6Ô7Ü(¨Ó0Ð4LÑLá& vÔ.ô 	�Ð+Ô,Ü˜6¤5§8¡8×#6Ñ#6Ô7Ü(¨Ó0Ð4LÑLá& vÕ.ð Mð 8ð 	-r(   c                 ó   — | j                  «       D �ch c](  }|j                  j                  dk7  sŒ|j                  ’Œ* c}| j                  «       D �ch c](  }|j                  j                  dk7  sŒ|j                  ’Œ* c}z  S c c}w c c}w )NÚmeta)Ú
parametersrX   r6   Úbuffers)r8   Úps     r)   re   re   .  sn   € Ø$×/Ñ/Ó1ÖM˜°Q·X±X·]±]ÀfÓ5LˆA�H‹HÒMØ Ÿ.™.Ó*öQØ¨a¯h©h¯m©m¸vÓ.Eˆ�‹òQñ ð ùÒMùò Qs   “B²BÁBÁ3Bc                 óÂ   — t        | «      r#t        | d«      r| j                  rt        | «      S | j	                  «       D ]  \  }}t        |«      | j                  |<   Œ | S )a{  Wrap the leaf child module in QuantWrapper if it has a valid qconfig
    Note that this function will modify the children of module inplace and it
    can return a new module which wraps the input module as well.

    Args:
        module: input module with qconfig attributes for all the leaf modules
        that we want to quantize

    Return:
        Either the inplace modified module with submodules wrapped in
        `QuantWrapper` based on qconfig or a new `QuantWrapper` module which
        wraps the input module, the latter case only happens when the input
        module is a leaf module and we want to quantize it.
    r+   )r   rN   r+   r   r5   r   Ú_modules)r8   r?   r@   s      r)   r   r   4  s\   € ô  	2°&Ô9Ü�F˜IÔ&Ø�NŠNä˜FÓ#Ð#à×,Ñ,Ó.ò 9‰ˆˆeÜ 1°%Ó 8ˆ�‰˜Òð9à€Mr(   c                 ól  — t         j                  j                  d«       |€
t        «       }|j	                  di «      }|st        j                  | «      } |}|€
t        «       }t        | d¬«       t        d„ | j                  «       D «       «      st        j                  d«       t        | |||¬«       | S )aƒ  Prepares a copy of the model for quantization calibration or quantization-aware training.

    Quantization configuration should be assigned preemptively
    to individual submodules in `.qconfig` attribute.

    The model will be attached with observer or fake quant modules, and qconfig
    will be propagated.

    Args:
        `model`: input model to be modified in-place
        `inplace`: carry out model transformations in-place, the original module is mutated
        `allow_list`: list of quantizable modules
        `observer_non_leaf_module_list`: list of non-leaf modules we want to add observer
        `prepare_custom_config_dict`: customization configuration dictionary for prepare function

    .. code-block:: python

       # Example of prepare_custom_config_dict:
       prepare_custom_config_dict = {
           # user will manually define the corresponding observed
           # module class which has a from_float class method that converts
           # float custom module to observed custom module
           "float_to_observed_custom_module_class": {
               CustomModule: ObservedCustomModule
           }
        }

    z!quantization_api.quantize.prepareNr#   ©r9   c              3   óP   K  — | ]  }t        |d «      xr |j                  –— Œ  y­w)r+   Nr\   )Ú.0r]   s     r)   ú	<genexpr>zprepare.<locals>.<genexpr>ƒ  s#   è ø€ ÒL°qŒw�q˜)Ó$Ò2¨¯©Ó2ÑLùs   ‚$&z¬None of the submodule got qconfig applied. Make sure you passed correct configuration through `qconfig_dict` or by assigning the `.qconfig` attribute directly on submodules)rv   )r1   Ú_CÚ_log_api_usage_oncer   r/   ÚcopyÚdeepcopyr   r   ÚanyÚmodulesÚwarningsÚwarnrr   )ÚmodelÚinplaceÚ
allow_listÚobserver_non_leaf_module_listr<   rv   rt   s          r)   r   r   O  s¶   € ôF 
‡H�H× Ñ Ð!DÔEØ!Ð)Ü%CÓ%EÐ"Ø"<×"@Ñ"@Ø/°ó#Ðñ Ü—‘˜eÓ$ˆð  *ÐØÐÜ#GÓ#IÐ Ü�u¨4Õ0ô ÑL¸E¿M¹M»OÔLÔLÜ�‰ðKô	
ô ØØ Ø%Ø$?õ	ð €Lr(   c                 ó�   ‡ — t        ‰ d«      r!t        ‰ j                  «      rt        ‰ d«       dˆ fd„	} |d¬«        |d¬«       y )NrE   Fc                 óö   •— | r‰j                   n‰j                  }| rt        nt        }t	        «       }|j                  «       D ]  \  }}||u sŒ|j                  |«       Œ |D ]  }|j                  |«       Œ y rU   )Ú_forward_pre_hooksÚ_forward_hooksrK   rI   ÚsetÚitemsÚaddÚpop)rQ   Úhook_mapÚobserver_hookÚhandle_ids_to_removeÚ	handle_idÚhook_fnr8   s         €r)   Úremove_hooksz5_remove_activation_post_process.<locals>.remove_hooksœ  s~   ø€ Ù08�6×,Ò,¸f×>SÑ>Sˆá*2Õ&Ô8Nð 	ô  #›uÐØ"*§.¡.Ó"2ò 	4ÑˆI�wØ˜-Ò'Ø$×(Ñ(¨Õ3ð	4ð .ò 	$ˆIØ�L‰L˜Õ#ñ	$r(   Tr`   ©F)rN   r   rE   Údelattr)r8   rŸ   s   ` r)   Ú_remove_activation_post_processr¢   “  sE   ø€ ô ˆvÐ0Ô1Ô6QØ×&Ñ&ô7ô 	�Ð1Ô2õ
$ñ ˜$ÕÙ˜%Ö r(   c                 óv   — | j                  «       D ]  }t        |«       Œ t        | d«      r| `t	        | «       y)zŠClean up the qconfig left in the module so that new qconfig can be
    propagated.

    Args:
        module: module to be cleaned up
    r+   N)ÚchildrenÚ_remove_qconfigrN   r+   r¢   )r8   r@   s     r)   r¥   r¥   ­  s;   € ð —‘Ó"ò ˆÜ˜Õðô ˆv�yÔ!ØˆNä# FÕ+r(   c                 óò   — t         j                  j                  d«       |€
t        «       }|st	        j
                  | «      } | j                  «        t        | d¬«        || g|¢­Ž  t        | |d¬«       | S )aƒ  Quantize the input float model with post training static quantization.

    First it will prepare the model for calibration, then it calls
    `run_fn` which will run the calibration step, after that we will
    convert the model to a quantized model.

    Args:
        model: input float model
        run_fn: a calibration function for calibrating the prepared model
        run_args: positional arguments for `run_fn`
        inplace: carry out model transformations in-place, the original module is mutated
        mapping: correspondence between original module types and quantized counterparts

    Return:
        Quantized model.
    z"quantization_api.quantize.quantizeT©r�   )	r1   r†   r‡   r   rˆ   r‰   Úevalr   r!   )rŽ   Úrun_fnÚrun_argsÚmappingr�   s        r)   r   r   ½  sf   € ô" 
‡H�H× Ñ Ð!EÔFØ€Ü:Ó<ˆÙÜ—‘˜eÓ$ˆØ	‡J�J„LÜˆE˜4Õ Ù
ˆ5Ð�8ÓÜˆE�7 DÕ)Ø€Lr(   c                 óp  — t         j                  j                  d«       |�€•|t         j                  k(  r|t        j
                  t        t        j                  t        t        j                  t        t        j                  t        t        j                  t        t        j                  t        i}�n·|t         j                  k(  r|t        j
                  t        t        j                  t        t        j                  t        t        j                  t        t        j                  t        t        j                  t        i}�n(|t         j                  k(  r+t        j                  t         t        j"                  t         i}nê|t         j$                  k(  rt        j                  t&        i}nÀt)        d|› d�«      ‚t+        |t,        «      r¡|t         j                  u rt        }n`|t         j                  u rt        }nG|t         j                  u rt         }n.|t         j$                  u rt&        }nt/        dt1        |«      «      ‚t3        t5        |t7        j8                  |«      «      «      }|€
t;        «       }|st=        j>                  | «      } | jA                  «        tC        | |«       tE        | |d¬«       | S )av  Converts a float model to dynamic (i.e. weights-only) quantized model.

    Replaces specified modules with dynamic weight-only quantized versions and output the quantized model.

    For simplest usage provide `dtype` argument that can be float16 or qint8. Weight-only quantization
    by default is performed for layers with large weights size - i.e. Linear and RNN variants.

    Fine grained control is possible with `qconfig` and `mapping` that act similarly to `quantize()`.
    If `qconfig` is provided, the `dtype` argument is ignored.

    Args:
        model: input model
        qconfig_spec: Either:

            - A dictionary that maps from name or type of submodule to quantization
              configuration, qconfig applies to all submodules of a given
              module unless qconfig for the submodules are specified (when the
              submodule already has qconfig attribute). Entries in the dictionary
              need to be QConfig instances.

            - A set of types and/or submodule names to apply dynamic quantization to,
              in which case the `dtype` argument is used to specify the bit-width

        inplace: carry out model transformations in-place, the original module is mutated
        mapping: maps type of a submodule to a type of corresponding dynamically quantized version
            with which the submodule needs to be replaced

    z*quantization_api.quantize.quantize_dynamicz5Don't know how to quantize with default settings for z. Provide full qconfig pleasez.Unknown dtype specified for quantize_dynamic: Tr§   )#r1   r†   r‡   Úqint8ri   ÚLinearr   ÚLSTMÚGRUÚLSTMCellÚRNNCellÚGRUCellÚfloat16r   Úquint8ÚEmbeddingBagr	   Ú	EmbeddingÚquint4x2r
   Ú
ValueErrorra   r–   ÚRuntimeErrorÚstrÚdictÚzipÚ	itertoolsÚrepeatr   rˆ   r‰   r¨   r   r!   )rŽ   Úqconfig_specÚdtyper«   r�   Údefault_qconfigs         r)   r   r   Ú  sç  € ô> 
‡H�H× Ñ Ð!MÔNØÑØ”E—K‘KÒä—	‘	Ô2Ü—‘Ô0Ü—‘Ô/Ü—‘Ô4Ü—
‘
Ô3Ü—
‘
Ô3ðŠLð ”e—m‘mÒ#ä—	‘	Ô2Ü—‘Ô0Ü—‘Ô/Ü—‘Ô4Ü—
‘
Ô3Ü—
‘
Ô3ðŠLð ”e—l‘lÒ"ä—‘Ô!BÜ—‘Ô?ð‰Lð ”e—n‘nÒ$ä—‘Ô!Gð‰Lô ØGÈÀwÐNkÐlóð ô 
�L¤#Ô	&Ø”E—K‘KÑÜ5‰OØ”e—m‘mÑ#Ü5‰OØ”e—l‘lÑ"Ü?‰OØ”e—n‘nÑ$ÜD‰OäØ@Ä#ÀeÃ*óð ô œC ¬i×.>Ñ.>¸Ó.OÓPÓQˆà€Ü;Ó=ˆáÜ—‘˜eÓ$ˆØ	‡J�J„LÜ�u˜lÔ+ÜˆE�7 DÕ)Ø€Lr(   c                 ó2  — t         j                  j                  d«       | j                  sJ d«       ‚|€
t	        «       }|st        j                  | «      } t        | d¬«       t        | |dd¬«       t        | t        |j                  «       «      d¬«       | S )	a  
    Prepares a copy of the model for quantization calibration or
    quantization-aware training and converts it to quantized version.

    Quantization configuration should be assigned preemptively
    to individual submodules in `.qconfig` attribute.

    Args:
        model: input model to be modified in-place
        mapping: dictionary that maps float modules to quantized modules to be
                 replaced.
        inplace: carry out model transformations in-place, the original module
                 is mutated
    z%quantization_api.quantize.prepare_qatz1prepare_qat only works on models in training modeNr‚   TF)r«   r�   Úremove_qconfig)r‘   r�   )r1   r†   r‡   Útrainingr   rˆ   r‰   r   r!   r   r–   Úvalues)rŽ   r«   r�   s      r)   r   r   4  s}   € ô 
‡H�H× Ñ Ð!HÔIØ�>Š>ÐNÐNÓNˆ>Ø€Ü1Ó3ˆáÜ—‘˜eÓ$ˆä�u¨4Õ0ÜˆE˜7¨DÀÕGÜˆE´°W·^±^Ó5EÓ1FÐPTÕUØ€Lr(   c                 óØ   — t         j                  j                  d«       |st        j                  | «      } | j                  «        t        | d¬«        || g|¢­Ž  t        | d¬«       | S )ag  Do quantization aware training and output a quantized model

    Args:
        model: input model
        run_fn: a function for evaluating the prepared model, can be a
                function that simply runs the prepared model or a training
                loop
        run_args: positional arguments for `run_fn`

    Return:
        Quantized model.
    z&quantization_api.quantize.quantize_qatTr§   )r1   r†   r‡   rˆ   r‰   Útrainr   r!   )rŽ   r©   rª   r�   s       r)   r    r    Q  sW   € ô 
‡H�H× Ñ Ð!IÔJÙÜ—‘˜eÓ$ˆØ	‡K�K„MÜ�˜tÕ$Ù
ˆ5Ð�8ÓÜˆE˜4Õ Ø€Lr(   c                 ó®   — t         j                  j                  d«       |st        j                  | «      } t        | |d|||¬«       |rt        | «       | S )a¼  Converts submodules in input module to a different module according to `mapping`
    by calling `from_float` method on the target module class. And remove qconfig at the
    end if remove_qconfig is set to True.

    Args:
        `module`: prepared and calibrated module
        `mapping`: a dictionary that maps from source module type to target
                   module type, can be overwritten to allow swapping user defined
                   Modules
        `inplace`: carry out model transformations in-place, the original module
                   is mutated
        `convert_custom_config_dict`: custom configuration dictionary for convert function
        `use_precomputed_fake_quant`: a flag to enable use of precomputed fake quant

    .. code-block:: python

       # Example of convert_custom_config_dict:
       convert_custom_config_dict = {
           # user will manually define the corresponding quantized
           # module class which has a from_observed class method that converts
           # observed custom module to quantized custom module
           "observed_to_quantized_custom_module_class": {
               ObservedCustomModule: QuantizedCustomModule
           }
       }

    z!quantization_api.quantize.convertT)r�   Úis_referenceÚconvert_custom_config_dictÚuse_precomputed_fake_quant)r1   r†   r‡   rˆ   r‰   Ú_convertr¥   )r8   r«   r�   rÄ   rÊ   rË   rÌ   s          r)   r!   r!   h  sU   € ôH 
‡H�H× Ñ Ð!DÔEÙÜ—‘˜vÓ&ˆÜØØØØ!Ø#=Ø#=õñ Ü˜ÔØ€Mr(   c           	      ó   — |€|r
t        «       n	t        «       }|€
t        «       }|j                  di «      }|st	        j
                  | «      } i }| j                  «       D ]D  \  }}	t        |	t        «      st        |	«      |vrt        |	|d|||¬«       t        |	|||«      ||<   ŒF |j                  «       D ]  \  }
}|| j                  |
<   Œ | S )ao  Converts submodules in input module to a different module according to `mapping`
    by calling `from_float` method on the target module class

    Args:
        module: input module
        mapping: a dictionary that maps from source module type to target
                 module type, can be overwritten to allow swapping user defined
                 Modules
        inplace: carry out model transformations in-place, the original module
                 is mutated
        is_reference: a flag to enable quantized reference module
        use_precomputed_fake_quant: a flag to enable use of precomputed fake quant

    r$   T©rÌ   )r   r   r   r/   rˆ   r‰   r5   ra   r   r   rÍ   r"   r—   r€   )r8   r«   r�   rÊ   rË   rÌ   rv   Úreassignr?   ÚmodÚkeyÚvalues               r)   rÍ   rÍ   œ  sü   € ð, €ñ ô ?Ô@ä9Ó;ð 	ð
 "Ð)Ü%CÓ%EÐ"Ø"<×"@Ñ"@Ø3°Ró#Ðñ Ü—‘˜vÓ&ˆØ€HØ×*Ñ*Ó,ò 
‰	ˆˆcô ˜3¤Ô-Ü,¨SÓ1Ð9TÑTäØØØØØ*Ø+Eõô %Ø�Ð5Ð7Qó
ˆ�Šð
ð& —n‘nÓ&ò %‰
ˆˆUØ$ˆ�‰˜Òð%ð €Mr(   c                 ó.  — | }t        | d«      �r| j                  ��ød}t        | «      |v r |t        | «         j                  | «      }d}nßt        | «      |v rÒ|t        | «         }t        |d«      rd|j                  rX| j                  €J ‚| j                  j                  «       } || j
                  «       t        |«      }|j                  | |«      }nRt        j                  |j                  «      }	d|	j                  v r|j                  | |¬«      }n|j                  | «      }d}|rè| j                  j                  «       D ]  }
|j                  |
«       Œ | j                  j                  «       D ]  }|t        usŒ|j!                  |«       Œ t#        | «      }t%        |«      dk  s/t%        |«      d	k(  rt'        j(                  d
«      |v s
J d|› �«       ‚t%        |«      dkD  rt+        t-        |«      «      nd}|r|j/                  |«       |S )a	  Swaps the module if it has a quantized counterpart and it has an
    `observer` attached.

    Args:
        mod: input module
        mapping: a dictionary that maps from nn module to nnq module

    Return:
        The corresponding quantized module of `mod`
    r+   NFTÚ_IS_REFERENCErÌ   rÏ   r   é   r{   zOswap_module only works with cpu or single-device CUDA modules, but got devices r   )rN   r+   r   Úfrom_observedrÕ   Úweightr   ro   ÚinspectÚ	signaturer|   r”   rÆ   rO   r•   rI   rP   re   rf   r1   rX   rg   rh   rW   )rÑ   r«   rv   rÌ   Únew_modÚswappedÚqmodÚweight_post_processÚweight_qparamsÚsigÚpre_hook_fnrž   rw   rX   s                 r)   r"   r"   Ú  s  € ð €GÜˆs�IÕ 3§;¡;Ñ#:ØˆÜ'¨Ó,Ð0KÑKØ1Ü,¨SÓ1ñç‰m˜CÓ ð ð ‰GÜ)¨#Ó.°'Ñ9ØÔ7¸Ó<Ñ=ˆDÜ�t˜_Ô-°$×2DÒ2DØ—{‘{Ð.Ð.Ð.Ø&)§k¡k×&8Ñ&8Ó&:Ð#Ù# C§J¡JÔ/Ü!0Ð1DÓ!E�ØŸ/™/¨#¨~Ó>‘ä×'Ñ'¨¯©Ó8�Ø/°3·>±>ÑAØ"Ÿo™oØÐ8Rð .ó ‘Gð #Ÿo™o¨cÓ2�GØˆGáà"×5Ñ5×<Ñ<Ó>ò ?�Ø×1Ñ1°+Õ>ð?ð ×-Ñ-×4Ñ4Ó6ò ;�ØÔ"8Ò8Ø×1Ñ1°'Õ:ð;ô
 +¨3Ó/ˆGÜ�w“< 1Ò$Ü�G“ Ò!¤e§l¡l°6Ó&:¸gÑ&Eðkà`ÐahÐ`iÐjókð ô -0°«L¸1Ò,<”Tœ$˜w›-Ô(À$ˆFÙØ—
‘
˜6Ô"Ø€Nr(   c                 óº   — d„ }t        | d«      r| j                  | ||«      dz   <   | j                  «       D ]!  \  }}|r ||«      |z   n|}t        |||«       Œ# y)a,  Traverse the modules and save all observers into dict.
    This is mainly used for quantization accuracy debug
    Args:
        mod: the top module we want to save all observers
        prefix: the prefix for the current module
        target_dict: the dictionary used to save all the observers
    c                 ó   — | dk(  r| S | dz   S )NÚ r,   r'   )r;   s    r)   Ú
get_prefixz&_get_observer_dict.<locals>.get_prefix  s   € Ø 2šˆvÐ7¨6°C©<Ð7r(   rE   N)rN   rE   r5   Ú_get_observer_dict)rÑ   Útarget_dictr;   rå   r?   r@   rA   s          r)   ræ   ræ     st   € ò8ô ˆsÐ-Ô.ð ×'Ñ'ð 	Ù�vÓÐ!:Ñ:ñ	
ð ×)Ñ)Ó+ò >‰ˆˆeÙ5;™
 6Ó*¨TÒ1ÀˆÜ˜5 +¨}Õ=ñ>r(   )Nrä   N)NNr    )NNNN)FNNN)NF)NFTFNF)NFFNF)rä   )Brˆ   rÙ   r¾   rŒ   r1   Útorch.ao.nn.quantizedr2   ri   Ú	quantizedrl   Útorch.nnÚtorch.ao.nn.intrinsicr   Útorch.ao.quantization.observerr   Útorch.ao.quantization.qconfigr   r   r   r   r	   r
   Ú+torch.ao.quantization.quantization_mappingsr   r   r   r   r   r   r   r   Útorch.ao.quantization.stubsr   r   Útorch.nn.utils.parametrizer   Úutilsr   r   Ú__all__Úis_activation_post_processr¯   ÚquantizableÚMultiheadAttentionr&   r   r7   r   rI   rK   rR   rr   re   r   r   r¢   r¥   r   r­   r   r   r    r!   rÍ   r"   ræ   r'   r(   r)   ú<module>rö      s˜  ðã Û Û Û ã ß #Ó #Ý Ý .Ý F÷÷ ÷	÷ 	ó 	÷ BÝ Cç Mò€ð 9Ð ð
 	�‰�—‘×$Ñ$Ø
×Ñ˜rŸ~™~×@Ñ@ð.ð
 	�‰×Ñ˜RŸ\™\×.Ñ.Ø
�‰×)Ñ)¨2¯<©<×+JÑ+Jð2ñ	Ð ò'ð ØØ#ó.óbò20ò
2ó
Kð "ØØØ $óF/òRòð: ØØ"&Ø#óAòH!ò4,ó ð<  E§K¡K¸ÀuóWótó:ð2 ØØØØ#Ø$ó1ðl ØØØ#Ø$ó;ð~ KPó9ôx>r(   