o
    I&i{7                     @   s  d dl Z d dlZ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 ddlmZmZ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 dd
lmZ ddl m!Z!m"Z"m#Z#m$Z$ ddl%m&Z& ej'G dd dZ(G dd dZ)dS )    N)CounterDictListOptional   )utils)create_call_functioncreate_dup_topcreate_instructioncreate_load_globalcreate_rot_nInstruction)unimplemented)
AttrSourceSource)is_safe_constantrot_n_helper)VariableTracker)NNModuleVariable)NumpyNdarrayVariableSymNodeVariableTensorVariableUnspecializedPythonVariable)TensorWithTFOverrideVariablec                   @   s   e Zd ZU eed< eed< dS )GraphOutputEntryindexvariableN)__name__
__module____qualname__int__annotations__r    r"   r"   @C:\wamp64\www\opt\env\Lib\site-packages\torch/_dynamo/codegen.pyr   !   s   
 r   c                   @   sz  e Zd ZdZ				dFdeejj dee fddZ	dd Z
d	d
 ZdGddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdee fdd Zdefd!d"Zdefd#d$Zdefd%d&ZdHd(d)Zdefd*d+Zdefd,d-ZeZdefd.d/Zd0d1 Z dId3d4Z!d5d6 Z"d7d8 Z#	2dId9ed:e$j%d;e&fd<d=Z'd>d? Z(d9eddfd@dAZ)dJdBdCZ*dee fdDdEZ+dS )K	PyCodegenz<
    Helper class uses for constructing Python bytecode
    Nrootgraph_output_varc                 C   sd   || _ d | _t | _i | _g | _|pi | _|| _|| _	| jj
j| _| jj| _| jj
j| _d| _d S )NF)r%   top_of_stackcollectionsr   usesgraph_outputs_outputtempvarstxr&   outputcode_optionscell_and_freevarsnew_var mutable_side_effects_from_source)selfr-   r%   r&   r,   r"   r"   r#   __init__,   s   



zPyCodegen.__init__c                 C   s,   | j }d| _ z| | W || _ d S || _ w )NT)r2   foreach)r3   Zstack_valuesZpriorr"   r"   r#   restore_stack@   s
   zPyCodegen.restore_stackc                 C   s   dd | j  D S )Nc                 S   s   g | ]}|j qS r"   )r   .0xr"   r"   r#   
<listcomp>I   s    z/PyCodegen.graph_output_vars.<locals>.<listcomp>)r*   valuesr3   r"   r"   r#   graph_output_varsH   s   zPyCodegen.graph_output_varsTc           	      C   s0  t |tr| j||  |   dS t |tsJ | j}| j}| j|u r.|	t
  dS | jrEddlm} t |j|rE| |jj dS |ry|jra|j| jv ra|	| | j|j  || _dS | j|dury|	| | j|  || _dS |jdur|r||j|  n| rt| r|	| |  nt |tr| |}|	| j| ddd | || j |tdd nt |ttt t!fr| |}t |t!r| "t#j$d | || j t |t!r|tdd nt |t r|j%r|| &dgtdd  nt |t'rY|j()d	}|d | j*d
 v r9|	| |d  |dd }n| j+dusAJ |	| ,| j+ |D ]}|	| &| qLn:| j-|  d7  < z
|||  W n t.y}   t/d|  Y nw |r|| jv r| j	t
  | 0| || _dS )z:Generate code such that top-of-stack (TOS) is set to valueNr   )MutableSideEffectsTaddZto_numpy_helperitemr   .co_varnameszreconstruct: )1
isinstancer   r+   extendreconstruct	clear_tosr   r*   r'   appendr	   r2   Zside_effectsr>   mutable_localsourcer,   create_loadgetZis_python_constantr   Zas_python_constantcreate_load_constr   add_graph_outputr   Zglobal_mangled_class_nameload_graph_outputr   r   r   r   r   r   load_import_fromr   r   Zneed_unwrapcreate_load_attrr   Z
module_keysplitr/   r%   create_load_outputr)   NotImplementedErrorr   	add_cache)	r3   valueZallow_cacher.   r*   r>   graph_outputs_keypartspartr"   r"   r#   __call__K   s   






	



zPyCodegen.__call__c                 C   s0   t | }|| jvrtt| j|| j|< |S N)idZas_proxyr*   r   len)r3   rV   rW   r"   r"   r#   rN      s   


zPyCodegen.add_graph_outputc                 C   s:   | j }|| | j || | |td d S )NBINARY_SUBSCR)r+   rH   rK   r&   _create_load_constr
   )r3   r   r.   r"   r"   r#   rO      s   zPyCodegen.load_graph_outputc                 C   s:   |   }|| j|< |jr|| j|j< | j| | d S r[   )r1   r,   rI   r+   rH   create_store)r3   rV   varr"   r"   r#   rU      s
   
zPyCodegen.add_cachec                 C   s   |D ]}| | qd S r[   r"   )r3   itemsir"   r"   r#   r5      s   
zPyCodegen.foreachc                 C   sR   t dd|}| jj}||v rt|| t|ksJ n|||< | j||ddgS )zStore value in a new globalz[^a-zA-Z0-9_]+_Tr?   )resubr-   	f_globalsr\   r   )r3   namerV   	push_nullrg   r"   r"   r#   setup_globally_cached   s   zPyCodegen.setup_globally_cachedc                 C   s
   d | _ d S r[   )r'   r<   r"   r"   r#   rG      s   
zPyCodegen.clear_tosc                 C   s&   t |tsJ | j| |   d S r[   )rD   r   r+   rH   rG   )r3   instr"   r"   r#   append_output   s   zPyCodegen.append_outputc                 C   s.   t dd |D sJ | j| |   d S )Nc                 s   s    | ]}t |tV  qd S r[   )rD   r   r7   r"   r"   r#   	<genexpr>   s    z*PyCodegen.extend_output.<locals>.<genexpr>)allr+   rE   rG   )r3   Zinstsr"   r"   r#   extend_output   s   zPyCodegen.extend_outputreturnc                 C   s   | j S r[   )r+   r<   r"   r"   r#   get_instructions   s   zPyCodegen.get_instructionsc                 C   s@   ||   v rtd|dS || jd v sJ | dtd|dS )N
LOAD_DEREFargvalrC   z missing	LOAD_FASTr0   r
   r/   r3   rh   r"   r"   r#   rK      s   zPyCodegen.create_loadc                 C   s   ||   v sJ td|dS )NLOAD_CLOSURErs   )r0   r
   rw   r"   r"   r#   create_load_closure   s   zPyCodegen.create_load_closurec                 C   s6   ||   v rtd|dS || jd v sJ td|dS )NSTORE_DEREFrs   rC   
STORE_FASTrv   rw   r"   r"   r#   r`      s   zPyCodegen.create_storeFc                 C   s8   |r	| j j| || jd v sJ | dt||S )Nco_namesz not in co_names)r-   r.   Zupdate_co_namesr/   r   )r3   rh   ri   r@   r"   r"   r#   r      s   
zPyCodegen.create_load_globalc                 C   s    t |sJ d| | |S )Nzunsafe constant )r   r_   r3   rV   r"   r"   r#   rM      s   
zPyCodegen.create_load_constc                 C   s   t d|dS )N
LOAD_CONSTrs   )r
   r}   r"   r"   r#   r_      s   zPyCodegen._create_load_constc                 C   s.   || j d vr| j d  |f7  < td|dS )Nr|   	LOAD_ATTRrs   )r/   r
   rw   r"   r"   r#   rQ      s   zPyCodegen.create_load_attrc                    s    fdd| dD S )Nc                    s   g | ]}  |qS r"   )rQ   )r8   rh   r<   r"   r#   r:     s    z/PyCodegen.create_load_attrs.<locals>.<listcomp>rB   )rR   )r3   namesr"   r<   r#   create_load_attrs  s   zPyCodegen.create_load_attrsr   c                 C   sZ   g }|rt jdkr|tdg| |d  || j|dddg| |d  |S )z6Load the global fn_name on the stack num_on_stack down      	PUSH_NULLr   FTr?   )sysversion_inforE   r
   rot_nr   )r3   fn_nameri   num_on_stackr.   r"   r"   r#   load_function_name  s   zPyCodegen.load_function_namec                 C   sX   zt |W S  ty+   td|d| t|gt dtdddtd|d Y S w )NBUILD_TUPLEarg   CALL_FUNCTION_EXr   UNPACK_SEQUENCE)r   AttributeErrorr
   r_   r   )r3   nr"   r"   r#   r     s   



zPyCodegen.rot_nc                 C   s0   t jdksJ | dd gtddtdS )Nr   c                   S   s   d S r[   r"   r"   r"   r"   r#   <lambda>%  s    z$PyCodegen.pop_null.<locals>.<lambda>r   FPOP_TOP)r   r   r_   r   r
   r<   r"   r"   r#   pop_null   s   zPyCodegen.pop_nullr   coderi   c                 C   s   |j }|sJ | j}tjdkr"|r"|td || |d  |D ]}||  v s.J |td|d q$|tdt	|d || 
| tjdk rX|| 
| |tdd	d || |d  |   d S )
Nr   r   r   rx   rs   r   r   MAKE_FUNCTION   )co_freevarsr+   r   r   rH   r
   rE   r   r0   r]   rM   rG   )r3   r   r   ri   r   Zfreevarsr.   ra   r"   r"   r#   make_function_with_closure*  s    
z$PyCodegen.make_function_with_closurec                 C   sv   | j jj}tdd|j}||d|u r| j||ddS d| dt| }||vr3| j j	|| | j||ddS )zT
        Generate a LOAD_GLOBAL instruction to fetch a given python module.
        z^.*[.] NTr?   Z
___module_rd   )
r-   r.   global_scopere   rf   r   rL   r   r\   Zinstall_global)r3   modri   r   rh   Zmangled_namer"   r"   r#   create_load_python_module>  s   
z#PyCodegen.create_load_python_modulec                 C   s   |  | |d | jjj}|D ],}|jr4|  | td| dg |  |	|  |  t
dd q|  |	|  q|  t
t|d dS )z2Call the generated code function stored in fn_nameTZ	as_tensorr   FN)ro   r   r-   r.   	graphargsZis_unspecializedr   torchrQ   loadr   r]   )r3   r   r   r   r"   r"   r#   make_call_generated_codeK  s   

z"PyCodegen.make_call_generated_codec                 C   s"   |  t| j|||  d S r[   )ro   r   r-   Zimport_sourcerF   )r3   module_nameZobject_namer"   r"   r#   rP   _  s
   zPyCodegen.load_import_fromc                 C   sX   t jdkr!t||}|d jdksJ td|d}|d| |S | |td|dgS )Nr   ZPRECALLZKW_NAMESrs   CALL_FUNCTION_KWr   )r   r   r   opnamer
   insertrM   )r3   nargsZkw_namesri   r.   Zkw_names_instr"   r"   r#   create_call_function_kwf  s   


z!PyCodegen.create_call_function_kw)NNNN)T)F)r   )rp   N),r   r   r   __doc__r   r   nnModulestrr4   r6   r=   rZ   rN   rO   rU   r5   rj   rG   rl   ro   r   r   rq   rK   ry   r`   r   rM   r_   rS   rQ   r   r   r   r   typesCodeTypeboolr   r   r   rP   r   r"   r"   r"   r#   r$   '   s^    


_




r$   )*r(   dataclassesre   r   r   typingr   r   r   r   Ztorch.nnr   r   r   Zbytecode_transformationr   r	   r
   r   r   r   excr   rJ   r   r   r   r   Zvariables.baser   Zvariables.nn_moduler   Zvariables.tensorr   r   r   r   Zvariables.torch_functionr   	dataclassr   r$   r"   r"   r"   r#   <module>   s&     