U
    ©Ê¹jÞ%  ã                	   @   sj  d dl Z d dl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 d dlmZ d dlmZ d d	lmZmZmZmZ d d
lmZmZmZ d dlm Z  eeef eee j!j"ee#e j!j"f eee f e$edœdd„Z%eee j!j"ee#e j!j"f eee f e$ddœdd„Z&ee j'jeee f e$dœdd„Z(eee#ee#e)f f e$edœdd„Z*dS )é    N)Ú
FakeTensor)Ú_get_arg_as_input_act_obs_or_fqÚ_get_output_act_obs_or_fqÚ_get_dtype_and_is_dynamicÚ_insert_obs_or_fqÚ&_maybe_insert_output_observer_for_nodeÚ_save_stateÚ _is_activation_post_process_nodeÚ_get_qspec_for_arg)ÚGraphModuleÚNode)ÚArgument)ÚQConfigMapping)Ú
QConfigAny)ÚPrepareCustomConfig)ÚDictÚTupleÚUnionÚAny)ÚQuantizationAnnotationÚ
EdgeOrNodeÚSharedQuantizationSpec)ÚObserverOrFakeQuantize)ÚnodeÚargÚqconfigÚmodelÚnamed_modulesÚobs_or_fq_mapÚis_qatÚreturnc              	   C   s  t |ttfƒrFg }|D ]"}t| ||||||ƒ}	| |	¡ qt|ƒ|ƒS t |tƒsT|S t |tƒsbt‚|}
| j 	dt
ƒ ¡}t|| |||ƒ}t|ƒ\}}t||||ƒ}t|ƒ\}}|sÀ|tjdfk�r||k�r‚||k�r‚t||ƒsât‚|dk	sît‚|jd }t |tƒ�stdt|ƒ› �ƒ‚||k�s.td|› �ƒ‚|j}t|||ƒ}t |tƒ�rh|j}t|||ƒ |||< n|| }|}
|||| f< n˜d}|j ¡ D ]H}|jdk�r�||j }t|ƒt|ƒk�r�|j|k�r�|}|} �qÚ�q�|dk	�sèt‚|||| f< |dk�rt|||||jƒ}|}
n|}
|
S )zk
    Given a `node` and an `arg`, inserts an input observer between
    `node` and `arg` if necessary.
    Úquantization_annotationNr   z0expect observed argument to be a Node, but got: zKcan't refer to a node that does not have observer/fake_quant inserted yet: Zcall_module)Ú
isinstanceÚlistÚtupleÚ-_maybe_insert_input_observer_for_arg_or_kwargÚappendÚtyper   ÚAssertionErrorÚmetaÚgetr   r   r   r   ÚtorchÚfloatr	   ÚargsÚinput_qspec_mapr
   r   ÚtargetÚsetattrÚusersÚkeysÚopZdtyper   Úgraph)r   r   r   r   r   r   r   Znew_arg_to_returnZ	inner_argZnew_inner_argÚnew_argr!   Zarg_as_input_act_obs_or_fqZarg_as_input_target_dtypeZarg_as_input_target_is_dynamicZarg_as_output_act_obs_or_fqZarg_as_output_target_dtypeZarg_as_output_target_is_dynamicZobserved_argr.   Zinput_arg_qspecZobs_or_fq_nameZexisting_obs_nodeZmaybe_obs_nodeZmaybe_obs_modZnew_obs_node© r6   úa/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/ao/quantization/pt2e/prepare.pyr%      s†          ÿ

ÿ
ÿ

ÿþ

    ÿr%   )r   r   r   r   r   r   r    c           	   	   C   sd   g }| j D ]"}t| ||||||ƒ}| |¡ q
| jtjjjjksVt	| j
ƒdksVtdƒ‚t|ƒ| _ dS )a  
    If needed, inserts observers to the input args and kwargs of `node`.
    Note: modifies `node` inplace.

    For example, if cur_node needs an observer after prev_node, we change from

      prev_node -> cur_node

    To

      prev_node -> obs -> cur_node

    r   z, expecting kwargs for aten op IR to be emptyN)r-   r%   r&   r/   r+   ZopsZatenÚcloneÚdefaultÚlenÚkwargsr(   r$   )	r   r   r   r   r   r   Únew_argsr   r5   r6   r6   r7   Ú&_maybe_insert_input_observers_for_node~   s&    
      ÿÿÿþr=   )r   r   r   r   c                 C   sÖ   d| j kr| j d nd }d| j kr<|d k	o8t| j d tƒ}n|d k	}|d k}|rTd S t|jdd�ƒ}t| d ||||ƒ | }|r„d S t| |||j||ƒ}	|	d kr¤d S t| j	 
¡ ƒ}
|
D ]}||	krÄq¶| | |	¡ q¶d S )Nr!   ÚvalF)Zremove_duplicate)r)   r"   r   Údictr   r=   r   r4   r#   r1   r2   Zreplace_input_with)r   r   r   r   Z!this_node_quantization_annotationZoutput_is_a_tensorZ)skip_inserting_input_and_output_observersr   Zskip_inserting_output_observersZmaybe_output_obs_nodeZ
orig_usersZ	user_noder6   r6   r7   Ú1_maybe_insert_input_and_output_observers_for_node¥   s>    
þÿú
ÿr@   )r   Únode_name_to_scoper   r    c              	   C   sT   t | jjƒ}i }|D ]}t|| ||ƒ qt| | jƒ} t| i |tƒ i tƒ |tƒ ƒ | S )N)	r#   r4   Znodesr@   r   r   r   r   Úset)r   rA   r   Znodes_before_observationr   r   r6   r6   r7   Úprepareç   s     ø
rC   )+r+   Ztorch._subclassesr   Z torch.ao.quantization.fx.preparer   r   r   r   r   r   r	   r
   Ztorch.fxr   r   Ztorch.fx.noder   Ztorch.ao.quantizationr   Ztorch.ao.quantization.qconfigr   Z&torch.ao.quantization.fx.custom_configr   Útypingr   r   r   r   Ztorch.ao.quantization.quantizerr   r   r   r   ÚnnÚModuleÚstrÚboolr%   r=   Zfxr@   r'   rC   r6   r6   r6   r7   Ú<module>   sJ   (


øa
ù(
üCü