o
    i>                     @   s  d dl Z d dlmZmZmZ d dlZd dlm  mZ	 d dl
mZ d dlmZ ejjZdZdZdZ		ddejjd	ejjd
eej dee ddf
ddZd	ejjdeee  defddZG dd dejjZ	ddejjdeeejjgef  ddfddZ			d dejjdedeee  deeejjgef  ddf
ddZ			d dejjdedeee  deeejjgef  dejjf
ddZ dS )!    N)AnyCallableOptional)maybe_set_is_frozen_param)
OrderedSetMODULE_TYPE_MAIN_MODULE_CONST_MODULEgmnodeconstantnamereturnc                 C   s   | j }|r|}n!t| dsd| _| j}	 d| }t| |sn|d7 }q|d | _||2 |d ur<|d|di }n|d|di }|| |j|j || |j	|_	W d    n1 scw   Y  |d ur~| 
|| t| || t| d S d S )	N_frozen_param_countr   T_frozen_param   get_attr placeholder)graphhasattrr   inserting_beforecreate_nodereplace_all_uses_withmetaupdate
erase_noder   register_buffersetattrr   )r
   r   r   r   gqualnameinew_input_noder   r   [/home/ubuntu/.local/lib/python3.10/site-packages/torchao/quantization/pt2e/constant_fold.pyreplace_node_with_constant   s6   






r$   lifted_constant_namesc                 C   s   | j dkp| j|p
dv S )Nr   r   )opr   )r   r%   r   r   r#   is_const_sourceC   s   r'   c                       sJ  e Zd Z			d!dejjdedeee	  dee
ejjgef  ddf
 fdd	Zdeejj fd
dZdefddZdejjdef fddZdejjjdefddZdeejjeejj f fddZdejjdef fddZdejdefddZdejjdejddfddZdef fddZdeejjef ddfdd Z  ZS )"ConstantFolderFNr
   skip_constructorsr%   skip_folding_node_fnr   c                    sV   t  | i | _t | _t | _|| _| 	 | _
|| _t | _|| _|  | _d S N)super__init__node_replacementscollectionsCounterreplaced_usesobjectunknown_valuer)   node_to_last_non_output_useuser_to_last_usesr%   deferred_valuer*   _find_mutable_buffersmutable_buffers)selfr
   r)   r%   r*   	__class__r   r#   r-   J   s   

zConstantFolder.__init__c                 C   sp   t  }| jjjD ]-}|jdkr5t|jdr5dt|jv r5t|j	dkr5t
|j	d tjjr5||j	d  q|S )zsFind mutable buffers by identifying copy_ operations.
        The first argument of copy_ op is the mutable buffer.call_function_schemacopy_r   )setmoduler   nodesr&   r   targetstrlenargs
isinstancetorchfxNodeadd)r9   r8   r   r   r   r#   r7   a   s   

"z$ConstantFolder._find_mutable_buffersc                 C      dS )NFr   r9   r   r   r#   _support_dynamic_shapep   s   z%ConstantFolder._support_dynamic_shaper   c                    s   | j d u rt |S | jd ur| |r| jS tj|ji |j}|D ]}t	|t
jjrB|j| j p3dvrB| j| | jkrB| j  S q$| jS )Nr   )r%   r,   run_noder*   r3   pytreearg_tree_leavesrE   kwargsrF   rG   rH   rI   r   envr6   )r9   r   flattened_node_inpsinpr:   r   r#   _deduce_valuet   s   

zConstantFolder._deduce_valuec                 C   s   dt jjjdtfdd}||s)|jt jjjj	kr4t
|jdkr4|tt|jr4t|jd | jr4dS t jjjj	t jjjj	t jjjjt jjjjt jjjg}|j|v rUdS |jD ]}t|t jjri|| jv ri dS qXdS )	Nr   r   c                 S   s^   | j tjjjjko.t| jd tjj	o.d| jd j
v o.| jd j
d jtjko.| jd tjkS )Nr   valr   )rB   rG   opsprimsconvert_element_typedefaultrF   rE   rH   rI   r   dtypeint8bfloat16)r   r   r   r#   is_woq_int8_pattern   s   z5ConstantFolder.is_impure.<locals>.is_woq_int8_patternr   r   TF)rG   rH   r   rI   boolrB   rW   atenpermuterZ   rD   usersnextiterr'   rE   r%   quantized_decomposeddequantize_per_channeldequantize_per_tensortensorrY   no_fusetorchaodequantize_affinerF   r8   )r9   r   r^   DEQUANT_OPSargr   r   r#   	is_impure   s4   
	





zConstantFolder.is_impurec                    s   t t ttjj  ttt	| j
jj}t	| j
jjD ]7jdkr&qdtjjdd f fdd}ttjj|jjf tjdkrU|jv rU   q S )NoutputrT   r   c                    s(   | v rd S  |    |  d S r+   )rJ   append)rT   last_non_output_user   	seen_usesr   r#   add_use   s   
z;ConstantFolder.node_to_last_non_output_use.<locals>.add_user   )r/   defaultdictlistr   rG   rH   rI   rc   rd   reversedr@   r   rA   rB   rO   tree_map_only_rE   rQ   rD   rb   rp   )r9   output_nodert   r   rq   r#   r4      s   

z*ConstantFolder.node_to_last_non_output_usec           
         s:  |j dkr"dtjjdd f fdd}ttjj||j t |S  	|\}}tj
|i |}t fdd|D r? jS |jdkrN|j tjjkrN jS |jdkr[|jd	kr[ jS  jrpt| jsptd
d |D sp jS t|j tjjrtjj|j jv r jS |jdkrt|j tjjr jS  |}t|tjjr|S | jkr jS t| jst|tjs| j kr| j kr|j!j"dkr|S  #|s|S  $|r؈ jS  %|| tj
|ji |j&}|D ]}t|tjjsq j'|  d7  < q j()|g D ]}	 j'|	 t*|	j+kr j,-|	d  q|S )Nro   rm   r   c                    s    j  j| < d S r+   )r3   rR   )rm   rL   r   r#   set_env   s   z(ConstantFolder.run_node.<locals>.set_envc                 3   s,    | ]}t  jt |ko j|kV  qd S r+   )typer3   ).0input_rL   r   r#   	<genexpr>   s
    
z*ConstantFolder.run_node.<locals>.<genexpr>r<   &triton_kernel_wrapper_functional_proxyc                 s   s    | ]	}t |tjV  qd S r+   )rF   rG   Tensor)r|   er   r   r#   r~      s    r   r   ).rB   rG   rH   rI   rO   rx   rE   r,   rN   fetch_args_kwargs_from_envrP   anyr3   r&   r`   _efficientzerotensorrZ   r   r)   r'   r%   rF   _ops
OpOverloadTagnondeterministic_seededtagsHigherOrderOperatorrU   _CScriptObjectr   r6   devicer{   insertable_tensor_checkrn   add_node_replacementrQ   r1   r5   getrD   rb   r.   pop)
r9   r   rz   rE   rQ   flattened_inputsoutrS   n	to_deleter:   rL   r#   rN      sr   










zConstantFolder.run_noderh   c                 C   rK   )NTr   )r9   rh   r   r   r#   r   ,  s   z&ConstantFolder.insertable_tensor_checkc                 C   s   || j |< d S r+   )r.   )r9   r   rh   r   r   r#   r   /  s   z#ConstantFolder.add_node_replacementc                    s   i }|  | t j|dS )N)initial_env)insert_placerholder_valuesr,   run)r9   rR   r:   r   r#   r   2  s   
zConstantFolder.runrR   c                 C   s\   | j jjddD ]}| j||< q| jd u rd S | j jjD ]}|j| jp$dv r+| j||< qd S )Nr   r&   r   )r@   r   
find_nodesr3   r%   rA   r   r6   )r9   rR   r   r   r   r#   r   7  s   

z)ConstantFolder.insert_placerholder_values)FNN)__name__
__module____qualname__rG   rH   GraphModuler_   r   rv   rC   r   rI   r-   r?   r7   rM   r   rU   r   rn   dictr4   rN   r   r   r   r   r   __classcell__r   r   r:   r#   r(   I   s2    
"/_&r(   constraint_fnc                 C   s   t jj i t| dd}|  |j D ]\}}|d ur#||s#qt| || qg }| j	j
ddD ]}t|jdkrMt| |jrHt| |j || q3|D ]}| j	| qP| j	  | j	  |   W d    d S 1 srw   Y  d S )NT)r)   r   r   r   )rG   utils_python_dispatch_disable_current_modesr(   r   r.   itemsr$   r   r   rD   rb   r   rB   delattrrp   r   eliminate_dead_codelint	recompile)r
   r   cfr   r   erased_paramsr   r   r#   constant_foldA  s(   



"r   Tr)   r*   c                 C   s   t jj D t| |||d}|  | jjD ]*}|d ur'||r't|j	t
< qt||s6||jv s6||jv r<t|j	t
< qt|j	t
< qW d    d S 1 sMw   Y  d S )N)r)   r%   r*   )rG   r   r   r   r(   r   r   rA   
MODULE_TAGr   META_TAGr'   r.   r1   CONST_MODULE_TAG)r
   r)   r%   r*   r   r   r   r   r#   constant_graph_tag]  s(   


"r   c                    s   t | ||| dtjjdtfdd}| jjD ]}|jdks$|j|p"dv r(|| qtj	 }i  g }| jjD ],}|j
t tkr@q6|| fdd}| |< |jD ]}	|	j
t tkra||  nqQq6|t| |  tj| |}
|
S )	zr
    Construct a GraphModule which corresponds to the part which could be
    constant folded in provided gm.
    r   r   c                 S   s8   d}| j D ]}|jt tkrd} nq|st| jt< |S )NFT)rb   r   r   r   r   )r   used_to_foldur   r   r#   untag  s   

z)run_and_get_constant_graph.<locals>.untaggetattrr   c                    s    |  S r+   r   )xnode_remappingr   r#   <lambda>  s    z,run_and_get_constant_graph.<locals>.<lambda>)r   rG   rH   rI   r_   r   rA   r&   r   Graphr   r   r   	node_copyrb   rp   ro   tupler   r   )r
   r)   r%   r*   r   r   	new_graphoutput_nodesnew_nodeusernew_gmr   r   r#   run_and_get_constant_graphz  s4   


r   )NNr+   )TNN)!r/   typingr   r   r   rG   torch.utils._pytreer   _pytreerO   torch._inductor.freezing_utilsr   torch.utils._ordered_setr   rW   r`   r   r   r   rH   r   rI   r   rC   r$   rv   r_   r'   Interpreterr(   r   r   r   r   r   r   r#   <module>   s   
*

 {



