
    Pi.                     h   d dl Z d dlZd dlZd dlmZmZmZmZ d dlZd dl	m
Z
mZ d dlmZmZmZmZ d dlmZ d dlmZmZ d dlmZmZ d dlmZmZ d d	lmZ d d
lmZm Z m!Z!m"Z"m#Z# d dl$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l0m1Z1 d dl2m3Z3m4Z4m5Z5m6Z6m7Z7 d dl8m9Z9 d dl:m;Z;m<Z<m=Z= d dl>m?Z? d dl@mAZAmBZB d dlCmDZD d dlEmFZF d dlGmHZH d dlImJZJ d dlKmLZL g dZMejN        ejO        ejP        ejQ        ejR        ejS        ejT        ejU        ejV        ejW        g
ZXejY        ejZ        j[        j\        j]        ej^        ejZ        j[        j_        j]        iZ`dee9eja        jb        f         decedef         ddfdZedeja        jb        ddfdZf	 dFdejg        j9        d e=d!ecedeja        jb        f         d"ecedehedeif         f         d#ecede*f         d$eejj                 ddfd%Zk	 dFdejg        j9        d e=d!ecedeja        jb        f         d"ecedehedeif         f         d#ecede*f         d$eejj                 ddfd&Zld e=d'e<ddfd(Zmd)eja        jb        denfd*Zod e;d#ecede*f         denfd+Zpd,e9d-e
ddfd.Zqd/ed e=d'e<ddfd0Zrd1e=d"ecedehedeif         f         d#ecede*f         dehededf         fd2Zsd e=d'e<ddfd3Ztd e=d!ecedeja        jb        f         deeja        jb                 fd4Zud e=d!ecedeja        jb        f         dejg        j9        d5end-ee
         ddfd6Zv	 	 	 dGd e=d!ecedeja        jb        f         d8ewed         d#ecede*f         d-e
d9end5end$eejj                 ddfd:Zx	 	 	 	 	 	 	 	 dHde9d5end<eeecedef         df         d=end>end?ee-ecedef         df         d-ee
ecedef         df         d9end@ende9fdAZy	 	 	 	 	 	 	 dIdBe9d5end<eeecedef         df         d=endCend?ee-ecedef         df         d-ee
ecedef         df         d9end@ende9fdDZz	 	 	 dJdBe9d<eeecedef         df         d?ee-ecedef         df         d-ee
ecedef         df         de9f
dEZ{dS )K    N)AnyCallableOptionalUnion)BackendConfigget_native_backend_config)get_fused_module_classesget_pattern_to_dtype_configsget_qat_module_classes-get_root_module_to_quantized_reference_module)quantized_decomposed_lib)convert_eq_obsupdate_obs_for_equalization)ConvertCustomConfigPrepareCustomConfig)_is_observed_module_is_observed_standalone_module)lower_to_fbgemm))_compare_prepare_convert_qconfig_mappings_generate_node_name_to_qconfig&_is_qconfig_supported_by_dtype_configs_update_qconfig_for_fusion_update_qconfig_for_qat)_get_modulecollect_producer_nodes graph_module_from_producer_nodesnode_arg_is_weight)
QConfigAnyqconfig_equals)QConfigMapping)_remove_qconfig)DeQuantStub)_parent_nameget_qparam_dictis_per_channelto_underlying_dtypeweight_is_quantized)GraphModule)ArgumentGraphNode)_USER_PRESERVED_ATTRIBUTES_KEY)
NodeSourceNodeSourceAction)type_before_parametrizations)FROM_NODE_KEY)_is_activation_post_process)create_getattr_from_value)_assert_and_get_unique_device)convertconvert_standalone_moduleconvert_weighted_modulemodelpreserved_attrsreturnc                     t          j         |          | j        t          <   | j        t                                                   D ]\  }}t	          | ||           dS )zXStore preserved attributes to the model.meta so that it can be preserved during deepcopyN)copymetar,   itemssetattr)r7   r8   	attr_nameattrs       u/home/jaya/work/projects/VOICE-AGENT/VIET/agent-env/lib/python3.11/site-packages/torchao/quantization/pt2e/convert.pyattach_preserved_attrs_to_modelrB   g   sc    
 26?1K1KEJ-. !:&DEKKMM ( (	4y$''''( (    c                     t          | t                    s2t          dt          t	          |                     z   dz   dz             d S )Nz,input model must be a GraphModule, Got type:z Please make zsure to follow the tutorials.)
isinstancer(   
ValueErrorstrtype)r7   s    rA   _check_is_graph_modulerI   s   s_    e[)) 
$u++  .	.
 
 	

 
rC   nodemodulesnode_name_to_scopenode_name_to_qconfigmodel_devicec           	         | j         }|J t          |j        t                    sJ t	          ||          \  }}||j                 }	t          |	d          r|	                    | |           dS t          fdt          |j	                  t          |j
                                                  z   D                       }
|
st          |	          sd|                    |          5  |                    |j	        d                    |                    |           ddd           n# 1 swxY w Y   dS |	j        }d}t          |	d          r|	j        }d }d }|t$          v r}|szd	}d}|	                                \  }}t)          |	j                  rqt-          |	j                  }t0          j        j        j        j        }t0          j        j        j        j        }|	j        }|	j        }tA          |          }||||||d
}nyt0          j        j        j!        j        }t0          j        j        j"        j        }tG          |          }t-          |          }|	j        }|	j        }tA          |          }|||||d}|                    |          5  |j	        d         }|g}|$                                D ]i\  }}|dv rKt          |tF          t,          f          s/tK          | |||z   |z   ||          }|&                    |           T|&                    |           j|'                    ||tQ          |          i           } |||           |g|dd         z   }|)                    |tQ          |           |||                    } |                    |             || |           |                    |           ddd           dS # 1 swxY w Y   dS |rd	}t0          j        j        j!        j*        }tA          |          }|t0          j+        t0          j,        fv s
J d            |	j        }|	j        }t[          |	dt0          j.                  }!t[          |	dt1          j/        t0          j0                  j1                  }"|||"|d}td          |!         }#|                    |          5  |j	        d         }|j	        d         g}$|$                                D ]\  }}%|$&                    |%           |'                    d	|#tQ          |$          i           }&|'                    d	tf          j4        |&dfi           }'|'                    d	tf          j4        |&dfi           }(|d         }|d         }|d         }|'|(|||d}ddd           n# 1 swxY w Y   |                    |          5  |j	        d         }|g}|$                                D ]6\  }}|dv r|}|&                    |           !|&                    |           7|'                    ||tQ          |          i           } |||           |g|dd         z   }t0          j        j        j"        j*        }|)                    |tQ          |           |||                    } |                    |             || |           |                    |           ddd           dS # 1 swxY w Y   dS |t0          j5        k    rt0          j        j        j6        j7        })|                    |          5  |j	        d         }|'                    d	|)|t0          j5        fi           }*|'                    d	|)|*t0          j#        fi           }+|                    |+           |                    |           ddd           dS # 1 swxY w Y   dS dS )au  Replace activation_post_process module call node with quantize and
    dequantize node working with decomposed Tensor

    Before:
    ... -> observer_0(x) -> ...
    After:
    ... -> torch.ops.quantized_decomposed.quantize_per_tensor(x, ...) ->
    torch.ops.quantized_decomposed.dequantize_per_tensor() -> ...

    or quantize_per_channel and dequantize_per_channel
    Nr4   c              3   8   K   | ]}t          |          V  d S N_has_none_qconfig.0nrM   s     rA   	<genexpr>zM_replace_observer_with_quantize_dequantize_node_decomposed.<locals>.<genexpr>   B         	!122     rC   r   F
is_dynamicc                 h    i }d|j         v r&|j         d         j        }|t          j        k    rd|i}|S )Nval	out_dtype)r<   dtypetorchfloat32)dequantize_op
input_nodedequantize_op_kwargsdq_out_dtypes       rA   add_dequantize_op_kwargsz\_replace_observer_with_quantize_dequantize_node_decomposed.<locals>.add_dequantize_op_kwargs   sB    !JO##%?517Lu},,(3\'B$##rC   c                 Z    t          |dt          j        g          g| j        t          <   d S )N.replace_observer_with_quantize_dequantize_node)r-   r.   CREATEr<   r0   )qdq_nodeoriginal_nodes     rA   !add_quantize_dequantize_node_infoze_replace_observer_with_quantize_dequantize_node_decomposed.<locals>.add_quantize_dequantize_node_info   s4     @!() (
m$$$rC   call_function)_scale__zero_point__axis__quant_min__quant_max__dtype_)rl   rm   ro   rp   rq   rl   rm      zVonly uint8 and int8 are supported in reference flow for dynamic quantization right nowqschemeeps)ro   rp   _eps_rq   ro   rp   rq   )8graphrE   targetrG   _get_module_path_and_prefixhasattrr4   alllistargsuserskeys_is_conversion_supportedinserting_beforereplace_all_uses_with
erase_noder]   rY   SUPPORTED_QDTYPEScalculate_qparamsr%   rt   intch_axisr^   opsquantized_decomposedquantize_per_channeldefaultdequantize_per_channel	quant_min	quant_maxr&   quantize_per_tensordequantize_per_tensorfloatr=   r2   appendcreate_nodetuplerk   tensoruint8int8getattrper_tensor_affinefinfor_   ru   _QSCHEME_TO_CHOOSE_QPARAMS_OPoperatorgetitemfloat16convert_element_typeno_fuse),r7   rJ   rK   rL   rM   rN   rw   module_pathprefixactivation_post_processskip_replacementr]   rY   rd   rj   	node_typequantize_opscale
zero_pointr   r`   r   r   dtype_qparamsra   quantize_op_inputskeyvalue_or_nodeqparam_nodequantized_node	dq_inputsdequantized_nodert   ru   choose_qparams_opchoose_qparams_op_inputsvaluechoose_qparams_node
scale_nodezero_point_nodedtype_convert_opconvert_fp16_nodeconvert_fp32_nodes,       `                                       rA   :_replace_observer_with_quantize_dequantize_node_decomposedr   ~   s,
   & KEdk3'''''5 "6 K &dk2&	22 ''t444     di4
(9(9#:#::      78OPP  ##D)) 	# 	#&&ty|444T"""	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	 $)EJ&55 8,7
$ $ $
 
 
 !!!:! $	*.3EEGGz19:: 	19::G)8MUK	.EM  09I/9I(//F  *!((! GG  )8LTK!I:PXM%LLEZJ/9I/9I(//F  *((! G ##D)) -	# -	#1J",&-mmoo = ="] 555"=5#,?? 6 #<#f,s2%$# #K '--k:::: '--m<<<<"..;.@(A(A2 N .-ndCCC ((+=abb+AAI$22i  ((
CC    &&'7888--.>EEET"""[-	# -	# -	# -	# -	# -	# -	# -	# -	# -	# -	# -	# -	# -	# -	# -	# -	# -	#\ 
 o# $	i4HO
 %U++%+uz2222- 322 ,5	+5	19e>UVV-uek%-6P6P6TUU
 %$	
 
 :'B##D)) 	 	1J(,	!~$%mmoo 7 7
U )//6666"'"3"3!2E:R4S4SUW# # **!14G3KR J $//!14G3KR O  .I.II&E% /((  G)	 	 	 	 	 	 	 	 	 	 	 	 	 	 	: ##D)) &	# &	#1J",&-mmoo = ="] 555 #0K&--k:::: '--m<<<<"..;.@(A(A2 N .-ndCCC ((+=abb+AAI "I:PWM$22i  ((
CC    &&'7888--.>EEET"""M&	# &	# &	# &	# &	# &	# &	# &	# &	# &	# &	# &	# &	# &	# &	# &	# &	# &	#N 
%-		 99NV##D)) 		# 		#1J % 1 1!1J3NPR! ! !& 1 1!14Eu{3SUW! ! &&'8999T"""		# 		# 		# 		# 		# 		# 		# 		# 		# 		# 		# 		# 		# 		# 		# 		# 		# 		# 
 	s^   ,6D..D25D2D2OO"O?CV##V'*V'D[**[.1[.7B ___c           	      	   |J t          |j        t                    sJ | j        }t	          ||          \  }}||j                 }	t          fdt          |j                  t          |j        	                                          z   D                       }
|
st          |	          sd|                    |          5  |                    |j        d                    |                    |           ddd           n# 1 swxY w Y   dS |	j        }d}t          |	d          r|	j        }|t"          j        t"          j        t"          j        t"          j        t"          j        fv r|sd}d}|	                                \  }}t1          |	j                  r(t5          |	j                  }||||d}t"          j        }n0t;          |          }t5          |          }|||d}t"          j        }|                    |          5  |j        d         }|g}|                                D ]M\  }}|d	v r/tA          | |||z   |z   ||          }|!                    |           8|!                    |           N|"                    ||tG          |          i           }|$                    d
|f          }|                    |           |                    |           ddd           dS # 1 swxY w Y   dS |rd}t"          j%        }t"          j&        j'        j(        dv }||d}|                    |          5  |j        d         }|g}|                                D ]\  }}|!                    |           |"                    ||tG          |          i           }|$                    d
|f          }|                    |           |                    |           ddd           dS # 1 swxY w Y   dS |t"          j)        k    rd}d}d|i}|                    |          5  |j        d         }|g}|                                D ]\  }}|!                    |           |"                    ||tG          |          i           }|$                    d
|f          }|                    |           |                    |           ddd           dS # 1 swxY w Y   dS dS )zReplace activation_post_process module call node with quantize and
    dequantize node

    Before:
    ... -> observer_0(x) -> ...
    After:
    ... -> torch.quantize_per_tensor(x, ...) -> x.dequantize() -> ...
    Nc              3   8   K   | ]}t          |          V  d S rQ   rR   rT   s     rA   rW   zB_replace_observer_with_quantize_dequantize_node.<locals>.<genexpr>  rX   rC   r   FrY   rk   )rl   rm   rn   rq   )rl   rm   rq   rr   
dequantize)r}   )fbgemmx86)rq   _reduce_range_call_methodtorq   )*rE   rx   rG   rw   ry   r{   r|   r}   r~   r   r   r   r   r   r]   rz   rY   r^   quint8qint8qint32float8_e5m2float8_e4m3fnr   r%   rt   r   r   r   r   r   r=   r2   r   r   r   r   quantize_per_tensor_dynamicbackends	quantizedenginer   )r7   rJ   rK   rL   rM   rN   rw   r   r   r   r   r]   rY   r   r   r   r   r   r   ra   r   r   r   r   r   r   reduce_ranger   s       `                       rA   /_replace_observer_with_quantize_dequantize_noder     s     dk3'''''KE5 "6 K &dk2     di4
(9(9#:#::      78OPP  ##D)) 	# 	#&&ty|444T"""	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	 $)EJ&55 8,7
    $	*.3EEGGz19:: 	419::G  *! 	 G  4KK%LLEZJ"'PUVVG3K ##D)) 	# 	#1J",&-mmoo = ="] 555 #<#f,s2%$# #K '--k:::: '--m<<<<"..;.@(A(A2 N  %00^DU0VV&&'7888T"""5	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#6 
 '# $	7 ~/6:KK#|DD##D)) 	# 	#1J",%mmoo 1 1
U"))%0000"..;.@(A(A2 N  %00^DU0VV&&'7888T"""	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 
%-		!	e$##D)) 	# 	#1J",%mmoo 1 1
U #))%0000"..;.@(A(A2 N  %00^DU0VV&&'7888T"""	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	# 	#	 
 	sK   6DD
D
CK55K9<K9B'O99O= O=3B'S''S+.S+rw   c                     | j         d         }t          |t                    sJ d|             |                     |           |                    |            t          ||           d S )Nr   z@Expecting the for call custom module node to be a Node, but got )r}   rE   r+   r   r   _insert_dequantize_node)rJ   rw   call_custom_module_nodes      rA   6_replace_observer_or_dequant_stub_with_dequantize_noder   .  s     #il-t44  dKbdd 4 	6777	T3U;;;;;rC   r   c                 ~    | j         }d}t          | d          r| j        }|t          v r| p|p|t          j        k    S )NFrY   )r]   rz   rY   r   r^   r   )r   r]   rY   s      rA   r   r   :  sX    #)EJ&55 8,7
 
#	#	8Z 	"	"EM!rC   c                 \    t          | t                    o| j        |v o|| j                 du S )z\Check if a node has a qconfig of None, i.e. user requested to not quantize
    the node
    N)rE   r+   name)rJ   rM   s     rA   rS   rS   H  s:     	4 	4I--	4 +t3rC   observedbackend_configc                     | j         j        D ]V}|j        dk    r|j        D ]@}|r<t	          ||          r,t          |          }|&t          | |          } |             AWdS )zExtract the subgraph that produces the weight for dynamic quant
    or weight only quant node and run the subgraph to observe the weight.
    Note that the observers of dynamic quant or weight only quant ops are
    run during the convert step.
    rk   N)rw   nodesopr}   r   r   r   )r   r   rJ   node_argweight_observer_nodesweight_observer_modules         rA   _run_weight_observersr   U  s     $ ) )7o%%	 
	) 
	)H ).tX>> )(>x(H(H%(0)I3* *& '&(((
	)) )rC   argc                    t          | t                    r;| j        dk    r0| j        dk    r%| j        d         }|                    | |           dS t          | t          t          f          r| D ]}t          |||           dS t          | t                    r*| 
                                D ]}t          |||           dS t          j        dt          |                       dS )zIf the arg is a dequantize Node, or a list/tuple/dict of dequantize Node,
    we'll recursively remove the dequantize Node
    r   r   r   z6Unsupported node type in recursive remove dequantize: N)rE   r+   r   rx   r}   replace_input_withr|   r   "_maybe_recursive_remove_dequantizedictvalueswarningswarnrH   )r   rJ   rw   quantize_nodearg_elements        rA   r   r   k  s    #t 
=!8!8SZ<=W=W 	]33333	C$	'	' 	
 	I 	IK.{D%HHHH	I 	I	C		 
::<< 	I 	IK.{D%HHHH	I 	I 	PT#YYPP	
 	
 	
 	
 	
rC   obs_nodec                    | j         d         }t          |t                    sJ d|             |j        |v r||j                 du nd}|r\t	          | j                  }|r|d         nd}d}|D ]0}|j        dk    r#|j        t          j	        j
        j        k    r|} n1|r|}d}	n|}d}	|r|j        |v r||j                 \  }
}nd}
|
|	fS )ai  Given and observer node, get the `Scope` or the fully qualified name for
    the submodule containing the observed node, also return a prefix of "_input"
    when the observed node is an input of a F.linear op, and not the output of another
    quantized op.
    TODO: this logic is hacky, we should think about how to remove it or make it more
    general
    r   z.Expecting observed node to be a Node, but got Nrk   _input )r}   rE   r+   r   r|   r~   r   rx   r^   nn
functionallinear)r   rL   rM   observed_nodeis_input_observer_onlyr~   first_linear_use_or_first_uselinear_noderV   r   r   _s               rA   ry   ry     s>    M!$M
 mT**  HHH *
 !555 	]/0D88 
   X^$$49(Cat% 	 	At&&18ux7J7Q+Q+Q 	8,7) )6% 	&	).2DDD+,I,NOQQ
 rC   c                     |                     |           5  |                    d| f          }t          | j                  D ]}||ur|                    | |           	 ddd           dS # 1 swxY w Y   dS )z-Inserts dequantize node for `node` in `graph`r   N)inserting_afterr   r   r~   r   )rJ   rw   dequantize_node	user_nodes       rA   r   r     s    			t	$	$ D D++L4'BBdj)) 	D 	DI//,,T?CCC	DD D D D D D D D D D D D D D D D D Ds   A	A--A14A1c                     | j                                         D ]:}|j        dk    r-|t          |j                           }t          |          r|c S ;dS )z\
    If the node is observed, return the observer
    instance. Otherwise, return None.
    call_moduleN)r~   r   r   rG   rx   r1   )rJ   rK   maybe_obs_node	maybe_obss       rA   _maybe_get_observer_for_noder     sd     *//++ ! !--N$9 : :;I*955 !    4rC   is_referencec                 j   |rt           j        j        j        j        }nt           j        j        j        j        }|t          | j                           }|j        d         j	        }t          | j                  }t          t          |                    D ]y}	|	|v rs||	         }
|
j        dk    r`|
j        dk    rU|
j        d         }|                     |
|           t          |
j                  dk    r|j                            |
           z|j        d         j        }t          |          dk    r,|d         dk    s
J d            	 t)          | |j                    |||          }t+          | j                  \  }}t-          ||         ||           ||t          | j                  <   dS )a  Converts a observed standalone module to a quantized standalone module by calling
    the fx convert api, currently using the same `is_reference` flag as parent, but we may
    changing this behavior in the future (e.g. separating quantization and lowering for
    standalone module as well)

    Args:
      - node: The call_module node of the observed standalone module
      - modules: named_module of original model
      - model: original model
      - is_reference: a flag from parent provided by user to decide if we want to
        produce a reference model or a fbgemm/qnnpack model
      - backend_config: backend configuration of the target backend of quantization
    _observed_graph_module_attrsr   r   r   zCurrently only quantized)r   N)r^   aoquantizationquantize_fxconvert_to_reference_fx
convert_fxrG   rx   r<   &standalone_module_input_quantized_idxsr|   r}   rangelenr   r   r~   rw   r   'standalone_module_output_quantized_idxsr   r#   r>   )rJ   rK   r7   r   r   
convert_fnobserved_standalone_modulesm_input_quantized_idxsr}   idxr   r   sm_output_quantized_idxsquantized_standalone_moduleparent_namer   s                   rA   r5   r5     s   *  BX*6N

X*6A
 /6c$+6F6F.G8=&,  	??DSYY 0 0)))s)Cv&&3:+E+E #''];;;sy>>Q&&K**3///9>& -  #$$q(('*a///1K///( 	 ek222 #-*"># # # %T[11KGK $(CDDD ;GCrC   Fobserved_node_namesis_decomposedc                 ^   |t          | j                           }|j        }	d}
t          |          }t	          ||          rI|j        }
|                                }t          | j                  \  }}t          ||         ||           | j	        |v }|	t          | |          s|sdS t          |          }|                    t          |          g           }t          |	|          sdS t          |	          }|sdS d}|}t	          |t           j        j        j        j                  r
|}|d         }d|i}t	          |t           j        j                  r|	                                }|	                                } ||j                    ||j                   t3          |          }t3          |          }|                    ||d           n6t	          |t           j        j        t           j        j        f          r|j        D ]}}t=          ||          rk|                    d          rVtA          ||          }|	                                }
|
j!        t           j"        k    r |
|           t3          |
          ||<   ~n|
du }|r?|	                                }
||}ntG          |          }|r|
$                    |           | }|r|r|s |
|j                   |                    t3          |
                     tK          |          }|                    tM          |          d          }|J dtM          |                       |'                    ||          } || |d<   dS t          | j                  \  }}t          ||         ||            dS )a  Convert a weighted module to reference quantized module in the model
    If the QConfig of a QAT module is not set, the module will still be converted to
    a float module.

    Args:
      - node: The call_module node of the observed standalone module
      - modules: named_module of original model
      - observed_node_names: names for the set of observed fx node, we can skip
        this conversion if the node is not observed
    Nr   r  )	weight_ih	weight_hhweightz3No reference quantized module class configured for )(rG   rx   qconfigr   rE   weight_fake_quantto_floatr#   r>   r   rS   r
   getrH   r   r'   r^   r  r   	intrinsic_FusedModuleRNNCellBaser  r  r  r$   updateLSTMGRU_flat_weights_namesrz   
startswithr   r]   r   r3   r   r   r/   
from_float)!rJ   rK   r  rM   r   r  r   rN   original_moduler  weight_post_processqat_module_classesr  r   is_observedpattern_to_dtype_configsdtype_configsis_weight_quantizedfused_modulefloat_modulewq_or_wq_dictweight_post_process_ihweight_post_process_hhweight_qparams_ihweight_qparams_hhwnr  is_ptqdeviceis_qat)root_module_to_quantized_reference_moduleref_qmodule_clsref_qmodules!                                    rA   r6   r6     s2   ( c$+../O)1G/??/#566 = .?)2244(55T$dO<<<)22K 	T#788 	 	 	  <NKK,00o1F1FKKM1'=II  .g66  L"L/58;#8#EFF '##A %m4M, 455 :C!(!1!1!(!1!1|5666|5666+,BCC+,BCC.. 	
 	
 	
 	
 
L58=%(,"?	@	@ -C 2 	I 	IB|R(( IR]]8-D-D I r22&-nn&6&6#&,;;''///$34G$H$Hb!	I %, 	/").."2"2'%6|DD /#&&v...(  	5, 	56 	5 3444_-@AABBB 	6nEE . @CC$\22D O &&j>Z[g>h>hjj '&& ",,\=IIK%Q(55T$dK88888rC   Tconvert_custom_configis_standalone_module_remove_qconfig_flagqconfig_mappingkeep_original_weightsc	                    |t                      }t          |t                    r0t          j        dt
          d           t          j        |          }t          |t                    r4t          j        dt
          d           |rt          j        |          nd}t          j	        |          }|t          |t                    sJ t          |t                    r0t          j        dt
          d           t          j        |          }|t                      }t          |           s
J d            | j        d         }	|	j        }
|	j        }|	j        }|	j        }t          |                     d	
                    }|r|	j        }t          j	        |          }|	j        rt+          ||           t-          | |           t/          ||           t1          | || j        ||
          }|                                D ]N\  }}||v sJ d| d            ||         /t7          |||                   sJ d| d| d||                      O|}|	j        !t;          | |          }t=          | ||           t?          | |           d}|j         }|j!        }tE          |          }tG          |$                                          }tK          |          }tM          |          }tO          |           }tQ          | j        j)                  D ](}|j*        dk    r!|}|dz  }||v rtW          || j                   /|j*        dk    rtY          |          dk    rN|}|j-        d         } t          | tP          tF          f          r"|D ]}!t]          | |!         || j                   t          | t^          t          f          rd|v rt]          | || j                   t          j        dta          |                       |j*        dk    r%tc          ||          }"|"J te          |"          r.|rtg          | |||
||           >ti          | |||
||           Tt          |"tj                    rtm          || j                   to          |"          rtq          ||| ||           ts          |"          tu          |          ;                    |          ;                    |          v r@ts          |"          |v rts          |"d                   |vrty          ||||||||           *| j        =                                 t}          | | j                  } |st          | ||
|          } |rt          |            | A                                 | j        B                    dd           | S )a  
    We will convert an observed model (a module with observer calls) to a reference
    quantized model, the rule is simple:
    1. for each observer module call in the graph, we'll convert it to calls to
       quantize and dequantize functions based on the observer instance
    2. for weighted operations like linear/conv, we need to convert them to reference
       quantized module, this requires us to know whether the dtype configured for the
       weight is supported in the backend, this is done in prepare step and the result
       is stored in observed_node_names, we can decide whether we need to swap the
       module based on this set

    Args:
       * `is_standalone_module`: when this flag is True, it means we are quantizing
       a submodule that is not inlined in parent module, and will be quantized
       separately as one unit.

       * `is_decomposed`: a boolean flag to indicate whether we want to use the
        quantize operator for decomposed quantized tensor
        (torch.ops.quantized_decomposed.quantize_per_tensor) or default/standalone
        quantized tensor (torch.quantize_per_tensor)

    Returns:
         a quantized standalone module, whether input/output is quantized is
         specified by prepare_custom_config, with
         input_quantized_idxs, output_quantized_idxs, please
         see docs for :func:`~torch.ao.quantization.prepare_fx` for details
    NPassing a convert_custom_config_dict to convert is deprecated and will not be supported in a future version. Please pass in a ConvertCustomConfig instead.   
stacklevelzPassing a QConfig dictionary to convert is deprecated and will not be supported in a future version. Please pass in a QConfigMapping instead.zPassing a backend_config_dict to prepare is deprecated and will not be supported in a future version. Please pass in a BackendConfig instead.z-incoming model must be produced by prepare_fxr   F)remove_duplicatezExpected key z  in convert node_name_to_qconfigzExpected k zD to have the same value in prepare and convert QConfigMappings, but z was updated to r   placeholderrs   outputz1Unsupported node type for output_quantized_idxs: r   )Cr   rE   r   r   r   FutureWarning	from_dictr    r;   deepcopyr   r   r   r<   rL   prepare_custom_configr  rM   named_modulesr<  r5  r   r   r   r   rw   r=   r   !equalization_node_name_to_qconfigr   r   r   input_quantized_indexesoutput_quantized_indexesr   r   r   r   r	   r3   r|   r   r   r   r  r}   r   r+   rH   r   r1   r   r   r"   r   r   r5   r/   setunionr6   eliminate_dead_coder(   r   r!   delete_all_unused_submodulespop)#r7   r   r9  r:  r;  r<  r   r  r=  observed_graph_module_attrsrL   rI  r  rM   rK   prepare_qconfig_mappingmodules_copyconvert_node_name_to_qconfigkvweight_eq_obs_dictplaceholder_node_seen_cntinput_quantized_idxsoutput_quantized_idxsr6  root_module_classesr&  fused_module_classesrN   rJ   cur_placeholder_node_idxreturn_noderE  r  mods#                                      rA   r4   r4     s)   L $ 3 5 5'.. UQ		
 	
 	
 	
 !4 =>S T T/4(( 	
L		
 	
 	
 	
 :IRN$_555d 	 mO44O"j.&Q&Q""Q.$'' AK		
 	
 	
 	
 '0@@244u%%VV'VVV%"'*-K"L#6  	$9  %@$S#8  5&&&>>??G  <'7 	  }W--&- 	E#O^DDD"5/:::1#_	
 	
 	
 (F<o?Q(
 (
$ )..00 	 	DAq4444CCCC 544 ,A.:%a)Ea)HII  P! P PP P.J1.MP P I  <"DP 9HHug'9::: %000 !"&;&S'<'U 	6nEE .   I N N P PQQ/??3NCC077LU[&'' V V7m##'@$%*%'+???
 (ek:::W  ())Q.. KYq\F&4-00 0  C6s[%+    FT4L11 	 ---6v{EKXXXVVVV    W%%dG,,C???*3// 0  N*,$    D*,$    C-- F%+    044 )'5,   
 .c22c:M6N6N6T6T"7 7e())* * 1559MMM4SV<<DWWW''("!  	 	 	 
K##%%%u{++E  
');=R
 
  	&&(((	JNN14888LrC   graph_moduler!   c	                 J    |t                      }t          |t                    r0t          j        dt
          d           t          j        |          }t                      |j        }	 fd|	D             }
t           ||||||||	  	        }t          ||
           |S )z_`is_standalone_module`: see docs in :func:`~torch.ao.quantization.prepare_standalone_module_fx`Nr?     rA  c                 R    i | ]#}t          |          |t          |          $S  )rz   r   )rU   r@   rb  s     rA   
<dictcomp>z_convert_fx.<locals>.<dictcomp>  sE       <&&glD))  rC   )r;  r<  r   r  r=  )r   rE   r   r   r   rF  rG  rI   preserved_attributesr4   rB   )rb  r   r9  r:  r!   r<  r   r  r=  preserved_attr_namesr8   r   s   `           rA   _convert_fxrj    s     $ 3 5 5'.. UQ		
 	
 	
 	
 !4 =>S T T<(((0E   (  O ,'%#3
 
 
I $I???rC   c           	      .    t          | d|d||d          S )a  Convert a calibrated or trained model to a reference quantized model, with
    decomposed representation for quantized Tensor
    see https://github.com/pytorch/rfcs/blob/master/RFC-0019-Extending-PyTorch-Quantization-to-Custom-Backends.md for more details,
    reference quantized model is a standard representation of a quantized model provided
    by FX Graph Mode Quantization, it can be further lowered to run on the target
    hardware, like accelerators

    Note: this is not public API

    Args:
        * `graph_module` (GraphModule): A prepared and calibrated/trained model (GraphModule)

        * `convert_custom_config` (ConvertCustomConfig): custom configurations for convert function.
            See :func:`~torch.ao.quantization.quantize_fx.convert_fx` for more details.

        * `_remove_qconfig` (bool): Option to remove the qconfig attributes in the model after convert.

        * `qconfig_mapping` (QConfigMapping): config for specifying how to convert a model for quantization.
            See :func:`~torch.ao.quantization.quantize_fx.convert_fx` for more details.

         * `backend_config` (BackendConfig): A configuration for the backend which describes how
            operators should be quantized in the backend. See
            :func:`~torch.ao.quantization.quantize_fx.convert_fx` for more details.

    Return:
        A reference quantized model (GraphModule) with operators working with decomposed quantized Tensor

    Example::

        # prepared_model: the model after prepare_fx/prepare_qat_fx and calibration/training
        # TODO: add backend_config after we split the backend_config for fbgemm and qnnpack
        # e.g. backend_config = get_default_backend_config("fbgemm")
        reference_quantized_model = _convert_to_reference_decomposed_fx(prepared_model)

    TF)r   r9  r!   r<  r   r  )rj  )rb  r9  r<  r   s       rA   #_convert_to_reference_decomposed_fxrl    s1    R 3'%   rC   rQ   )FFN)FNFTNNFF)NFTNNFF)NNN)|r;   r   r   typingr   r   r   r   r^   $torch.ao.quantization.backend_configr   r   *torch.ao.quantization.backend_config.utilsr	   r
   r   r   $torch.ao.quantization.fx._decomposedr   "torch.ao.quantization.fx._equalizer   r   &torch.ao.quantization.fx.custom_configr   r   %torch.ao.quantization.fx.graph_moduler   r   (torch.ao.quantization.fx.lower_to_fbgemmr   .torch.ao.quantization.fx.qconfig_mapping_utilsr   r   r   r   r   torch.ao.quantization.fx.utilsr   r   r   r   torch.ao.quantization.qconfigr   r   %torch.ao.quantization.qconfig_mappingr    torch.ao.quantization.quantizer!   torch.ao.quantization.stubsr"   torch.ao.quantization.utilsr#   r$   r%   r&   r'   torch.fxr(   torch.fx.graphr)   r*   r+   torch.fx.graph_moduler,   torch.fx.tracebackr-   r.   torch.nn.utils.parametrizer/   torchao.quantization.pt2er0   "torchao.quantization.pt2e.observerr1   torchao.quantization.pt2e.utilsr2   torchao.utilsr3   __all__r   r   r   r   r   uint16int16int32r   r   r   r   r   r   choose_qparamsr   per_tensor_symmetricchoose_qparams_symmetricr   r   Moduler   rG   rB   rI   fxr   rH   r4  r   r   r   boolr   rS   r   r   ry   r   r   r5   rN  r6   r4   rj  rl  rf  rC   rA   <module>r     s_
      1 1 1 1 1 1 1 1 1 1 1 1                    J I I I I I                      E D D D D D                         E D D D D D D D @ @ @ @ @ @ : : : : : : 3 3 3 3 3 3              !           0 0 0 0 0 0 0 0 0 0 @ @ @ @ @ @ ; ; ; ; ; ; ; ; C C C C C C 3 3 3 3 3 3 J J J J J J E E E E E E 7 7 7 7 7 7   
L	K	L	K	J	L	K	K		  
UY;JQ		 > W ^! 	(eho-.	(#s(^	( 
	( 	( 	( 	(
%(/ 
d 
 
 
 
" ,0P# P#8P#
P# #ux&'P# S%T	"223	P#
 sJ/P# 5<(P# 
P# P# P# P#x ,0O# O#8O#
O# #ux&'O# S%T	"223	O#
 sJ/O# 5<(O# 
O# O# O# O#t	<
	<	<		< 	< 	< 	<eho $    


*.sJ*?
	
 
 
 
)K ) )SW ) ) ) ),
C 
t 
E 
d 
 
 
 
*66S%T	"2236 sJ/6 38_	6 6 6 6rD$ Du D D D D D
c58?23eho   =<
=<#ux&'=< 8=< 	=<
 ]+=< 
=< =< =< =<L  +/Q9 Q9
Q9#ux&'Q9 SQ9 sJ/	Q9
 "Q9 Q9 Q9 5<(Q9 
Q9 Q9 Q9 Q9l NR!&!%CGAE"'F FFF !!4d38nd!JKF 	F
 F >4S>4?@F -c3h=>F F  F F F F FX OS!& CGAE"'- --- !!4d38nd!JK- 	-
 - >4S>4?@- -c3h=>- -  - - - - -d OSCGAE	1 11 !4d38nd!JK1 >4S>4?@1 -c3h=>	1
 1 1 1 1 1 1rC   