U
    9%e%                  	   @   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rt||st|dk	st|jd }t |tstdt| ||ks.td| |j}t|||}t |trh|j}t||| |||< n|| }|}
|||| f< nd}|j D ]H}|jdkr||j }t|t|kr|j|kr|}|} qڐq|dk	st|||| 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/Darija-Ai-API/env/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 |||| | }|rd S t| |||j||}	|	d krd S t| j	
 }
|
D ]}||	krq|| |	 qd 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