o
    h%                     @   s  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  deeef dedede j!j"dee#e j!j"f deee f de$defddZ%dedede j!j"dee#e j!j"f deee f de$ddfddZ&dede j'jdeee f de$fddZ(dedee#ee#e)f f de$def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r#g }|D ]}t| ||||||}	||	 qt||S t |ts*|S t |ts1J |}
| jdt	 }t
|| |||}t|\}}t||||}t|\}}|s`|tjdfvr||kr||krt||soJ |dusuJ |jd }t |tsJ dt| ||v sJ d| |j}t|||}t |tr|j}t||| |||< n|| }|}
|||| f< |
S d}|j D ]}|jdkr||j }t|t|kr|j|kr|}|} nq|dusJ |||| f< |du rt|||||j}|}
|
S |}
|
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: call_module)
isinstancelisttuple-_maybe_insert_input_observer_for_arg_or_kwargappendtyper   metagetr   r   r   r   torchfloatr	   argsinput_qspec_mapr
   r   targetsetattruserskeysopdtyper   graph)r   r   r   r   r   r   r   new_arg_to_return	inner_argnew_inner_argnew_argr!   arg_as_input_act_obs_or_fqarg_as_input_target_dtypearg_as_input_target_is_dynamicarg_as_output_act_obs_or_fqarg_as_output_target_dtypearg_as_output_target_is_dynamicobserved_argr.   input_arg_qspecobs_or_fq_nameexisting_obs_nodemaybe_obs_nodemaybe_obs_modnew_obs_node rG   X/var/www/html/ai/venv/lib/python3.10/site-packages/torch/ao/quantization/pt2e/prepare.pyr&      sr   




#



r&   c           	   	   C   sd   g }| j D ]}t| ||||||}|| q| jtjjjjks+t	| j
dks+J 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+   opsatenclonedefaultlenkwargsr%   )	r   r   r   r   r   r   new_argsr   r9   rG   rG   rH   &_maybe_insert_input_observers_for_node~   s   
"rP   c                 C   s   d| j v r
| j d nd }d| j v r|d uot| j d t}n|d u}|d u }|r*d S t|jdd}t| d |||| | }|rBd S t| |||j||}	|	d u rRd S t| j	
 }
|
D ]}||	u rbq[|| |	 q[d S )Nr!   valF)remove_duplicate)r)   r#   r   dictr   rP   r   r5   r$   r1   r2   replace_input_with)r   r   r   r   !this_node_quantization_annotationoutput_is_a_tensor)skip_inserting_input_and_output_observersr   skip_inserting_output_observersmaybe_output_obs_node
orig_users	user_noderG   rG   rH   1_maybe_insert_input_and_output_observers_for_node   s@   

r\   node_name_to_scopec              	   C   sT   t | jj}i }|D ]	}t|| || q
t| | j} t| i |t i t |t  | S )N)	r$   r5   nodesr\   r   r   r   r   set)r   r]   r   nodes_before_observationr   r   rG   rG   rH   prepare   s    
ra   )+r+   torch._subclassesr    torch.ao.quantization.fx.preparer   r   r   r   r   r   r	   r
   torch.fxr   r   torch.fx.noder   torch.ao.quantizationr   torch.ao.quantization.qconfigr   &torch.ao.quantization.fx.custom_configr   typingr   r   r   r   torch.ao.quantization.quantizerr   r   r   r   nnModulestrboolr&   rP   fxr\   r(   ra   rG   rG   rG   rH   <module>   sz    (



`

'

B