U
    zhx@                     @   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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_call_methodcreate_dup_topcreate_instructioncreate_load_attrcreate_load_globalcreate_load_method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%   G/var/www/html/venv/lib/python3.8/site-packages/torch/_dynamo/codegen.pyr   %   s   
r   c                   @   s  e Zd ZdZd^eejj ee dddZ	dddd	Z
d
d Zdd Zd_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d Zee d d!d"Zed d#d$Zed d%d&Zed d'd(Zd`ed d*d+Zed d,d-Zed d.d/ZeZd0d1 Z d2d3 Z!d4d5 Z"ed d6d7Z#d8d9 Z$d:d; Z%ed d<d=Z&d>d? Z'dadAdBZ(dCdD Z)dEdF Z*dGdH Z+e,e-dIdJdKZ.dLdM Z/dNdO Z0dbee1j2e-dPdQdRZ3ed dSdTZ4eddUdVdWZ5dd dXdYZ6ee d dZd[Z7ed d\d]Z8dS )c	PyCodegenz<
    Helper class uses for constructing Python bytecode
    N)rootgraph_output_varc                 C   sj   || _ d | _t | _i | _g | _|p(i | _|| _|| _	| jj
j| _| jj| _| jj
j| _d| _d| _d S )NFT)r(   top_of_stackcollectionsr   usesgraph_outputs_outputtempvarstxr)   outputcode_optionscell_and_freevarsnew_var mutable_side_effects_from_sourcevalue_from_source)selfr0   r(   r)   r/   r%   r%   r&   __init__0   s    


zPyCodegen.__init__T)r6   c                C   sB   | j }d| _ | j}|  j|M  _z| | W 5 || _ || _X d S )NT)r5   r6   foreach)r7   Zstack_valuesr6   Zpriorprevr%   r%   r&   restore_stackE   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>Q   s     z/PyCodegen.graph_output_vars.<locals>.<listcomp>)r-   valuesr7   r%   r%   r&   graph_output_varsP   s    zPyCodegen.graph_output_varsc                 C   s$   | | }|d ks td| d S )Nzreconstruct!=None )ZreconstructAssertionError)r7   valueresr%   r%   r&   call_reconstructS   s    
zPyCodegen.call_reconstructc           	      C   s  t |tr | | |   dS t |ts.t| j}| j}| j|krX|rX|	t
  dS | jrddlm} t |j|r| |jj dS |r|jr|j| jkr|	| | j|j  || _dS | j|dk	r|	| | j|  || _dS |jdk	r|r| jr| |j n| rHt| rH|	| |  nbt |tr| |}| tjd | || j |	| j| | j!ddd |"t#dd nt |t$r|% t&kr| j!j's| |(| j!}| || j |"| )d	gt#d
d  nt |t*t$t+t,fr| |}t |t,rL| tjd | || j t |t,rz|"t#dd n0t |t+r|j-r|"| )d	gt#d
d  nt |t.r:|j/0d}|d
 | j1d kr|	| |d
  |dd }n"| j2dk	s
t|	| 3| j2 |D ]}|	| )| q np| j4|  d7  < z| | W n$ t5k
r~   t6d|  Y nX |r|| jkr| j	t
  | 7| || _dS )z:Generate code such that top-of-stack (TOS) is set to valueNr   )MutableSideEffectsZto_subclassFTadd   itemr   Zto_numpy_helper.co_varnameszreconstruct: )8
isinstancer   rF   	clear_tosr   rC   r.   r-   r*   appendr
   r5   Zside_effectsrG   mutable_localsourcer/   create_loadgetr6   Zis_python_constantr   Zas_python_constantcreate_load_constr   add_graph_outputload_import_fromr   r    load_graph_outputr   r   Zglobal_mangled_class_namer0   extendr   r   Zpython_typefloatZexport	as_tensorr   r   r   r   Zneed_unwrapr   Z
module_keysplitr2   r(   create_load_outputr,   NotImplementedErrorr   	add_cache)	r7   rD   Zallow_cacher1   r-   rG   graph_outputs_keypartspartr%   r%   r&   __call__W   s    



  
	

zPyCodegen.__call__c                 C   s0   t | }|| jkr,tt| j|| j|< |S N)idZas_proxyr-   r   len)r7   rD   r`   r%   r%   r&   rV      s    
 
zPyCodegen.add_graph_outputc                 C   s:   | j }|| | j || | |td d S )NBINARY_SUBSCR)r.   rP   rS   r)   _create_load_constr   )r7   r   r1   r%   r%   r&   rX      s    zPyCodegen.load_graph_outputc                 C   s:   |   }|| j|< |jr$|| j|j< | j| | d S rd   )r4   r/   rQ   r.   rP   create_store)r7   rD   varr%   r%   r&   r_      s
    
zPyCodegen.add_cachec                 C   s   |D ]}| | qd S rd   r%   )r7   itemsir%   r%   r&   r9      s    zPyCodegen.foreachc                 C   sR   t dd|}| jj}||kr8t|| t|ks@tn|||< | j||ddgS )zStore value in a new globalz[^a-zA-Z0-9_]+_TrH   )resubr0   	f_globalsre   rC   r   )r7   namerD   	push_nullrp   r%   r%   r&   setup_globally_cached   s    zPyCodegen.setup_globally_cachedc                 C   s
   d | _ d S rd   )r*   rA   r%   r%   r&   rO      s    zPyCodegen.clear_tosc                 C   s&   t |tst| j| |   d S rd   )rN   r   rC   r.   rP   rO   )r7   instr%   r%   r&   append_output   s    zPyCodegen.append_outputc                 C   s.   t dd |D st| j| |   d S )Nc                 s   s   | ]}t |tV  qd S rd   )rN   r   r<   r%   r%   r&   	<genexpr>   s     z*PyCodegen.extend_output.<locals>.<genexpr>)allrC   r.   rY   rO   )r7   Zinstsr%   r%   r&   extend_output   s    zPyCodegen.extend_output)returnc                 C   s   | j S rd   )r.   rA   r%   r%   r&   get_instructions   s    zPyCodegen.get_instructionsc                 C   s@   ||   krtd|dS || jd ks4t| dtd|dS )N
LOAD_DEREFargvalrM   z missing	LOAD_FASTr3   r   r2   rC   r7   rq   r%   r%   r&   rS      s    zPyCodegen.create_loadc                 C   s   ||   ksttd|dS )NLOAD_CLOSUREr|   )r3   rC   r   r   r%   r%   r&   create_load_closure  s    zPyCodegen.create_load_closurec                 C   s6   ||   krtd|dS || jd ks*ttd|dS )NSTORE_DEREFr|   rM   
STORE_FASTr   r   r%   r%   r&   ri     s    zPyCodegen.create_storeFc                 C   s8   |r| j j| || jd ks.t| dt||S )Nco_namesz not in co_names)r0   r1   update_co_namesr2   rC   r   )r7   rq   rr   rI   r%   r%   r&   r     s    zPyCodegen.create_load_globalc                 C   s    t |std| | |S )Nzunsafe constant )r   rC   rh   r7   rD   r%   r%   r&   rU     s    zPyCodegen.create_load_constc                 C   s   t d|dS )N
LOAD_CONSTr|   r   r   r%   r%   r&   rh     s    zPyCodegen._create_load_constc                 C   s   | j j| t|S rd   )r0   r1   r   r   r   r%   r%   r&   r     s    zPyCodegen.create_load_methodc                 C   s   |  | | d S rd   )ru   r   r   r%   r%   r&   load_method  s    zPyCodegen.load_methodc                 C   s   |  t| d S rd   )rx   r	   )r7   nargsr%   r%   r&   call_method"  s    zPyCodegen.call_methodc                 C   s*   || j d kr"| j d  |f7  < t|S )Nr   )r2   r   r   r%   r%   r&   r   %  s    zPyCodegen.create_load_attrc                 C   s   |  | | d S rd   )ru   r   r   r%   r%   r&   	load_attr*  s    zPyCodegen.load_attrc                    s    fdd| dD S )Nc                    s   g | ]}  |qS r%   )r   )r=   rq   rA   r%   r&   r?   .  s     z/PyCodegen.create_load_attrs.<locals>.<listcomp>rL   )r\   )r7   namesr%   rA   r&   create_load_attrs-  s    zPyCodegen.create_load_attrsc                 C   s.   || j d kr"| j d  |f7  < td|dS )Nr   
STORE_ATTRr|   )r2   r   r   r%   r%   r&   create_store_attr0  s    zPyCodegen.create_store_attrc                 C   s   |  | | d S rd   )ru   r   r   r%   r%   r&   
store_attr5  s    zPyCodegen.store_attrr   c                 C   sZ   g }|r0t jdkr0|tdf| |d  || j|dddf| |d  |S )z6Load the global fn_name on the stack num_on_stack down      	PUSH_NULLr   FTrH   )sysversion_inforY   r   rot_nr   )r7   fn_namerr   num_on_stackr1   r%   r%   r&   load_function_name8  s    zPyCodegen.load_function_namec              
   C   s\   z
t |W S  tk
rV   td|d| t|ft dtdddtd|df Y S X d S )NBUILD_TUPLEargrJ   CALL_FUNCTION_EXr   UNPACK_SEQUENCE)r   AttributeErrorr   rh   r   )r7   nr%   r%   r&   r   G  s    



zPyCodegen.rot_nc                 C   s0   t jdkst| dd ftddtdfS )Nr   c                   S   s   d S rd   r%   r%   r%   r%   r&   <lambda>Y      z$PyCodegen.pop_null.<locals>.<lambda>r   FPOP_TOP)r   r   rC   rh   r   r   rA   r%   r%   r&   pop_nullT  s    zPyCodegen.pop_nullc                 C   s   |  td d S )Nr   )ru   r   rA   r%   r%   r&   pop_top^  s    zPyCodegen.pop_top)r   rr   c                 C   s   |  t||d d S )N)rr   )rx   r   )r7   r   rr   r%   r%   r&   call_functiona  s    zPyCodegen.call_functionc                 C   s   |  t  d S rd   )ru   r
   rA   r%   r%   r&   dup_topd  s    zPyCodegen.dup_topc                 C   s   |  | | d S rd   )ru   ri   )r7   varnamer%   r%   r&   storeg  s    zPyCodegen.store)r   coderr   c                 C   s   |j }|st| j}tjdkrD|rD|td || |d  |D ]&}|| 	 ks\t|td|d qH|tdt
|d || | tjdk r|| | |tdd	d || |d  |   d S )
Nr   r   r   r   r|   r   r   MAKE_FUNCTION   )co_freevarsrC   r.   r   r   rP   r   rY   r   r3   rf   rU   rO   )r7   r   r   rr   r   Zfreevarsr1   rj   r%   r%   r&   make_function_with_closurej  s     
z$PyCodegen.make_function_with_closurec                 C   sh   | j j}|j}tdd|j}||d|kr>| j||ddS d| }| j j||}| j||ddS )zT
        Generate a LOAD_GLOBAL instruction to fetch a given python module.
        z^.*[.] NTrH   Z
___module_)	r0   r1   global_scopern   ro   r    rT   r   Zinstall_global_by_id)r7   modrr   r1   r   rq   prefixZglobal_namer%   r%   r&   create_load_python_module~  s    
z#PyCodegen.create_load_python_module)r   ry   c                 C   s   |  | |d | jjj}|D ]L}|jrb|  | td| dg | 	| |  t
dd q | 	| q |  t
t|d dS )z2Call the generated code function stored in fn_nameTr[   r   FN)rx   r   r0   r1   	graphargsZpass_arg_as_tensorr   torchr   rF   r   rf   )r7   r   r   r   r%   r%   r&   make_call_generated_code  s    


z"PyCodegen.make_call_generated_codec                 C   s   | t | j|| d S rd   )r   r0   Zimport_source)r7   module_nameZobject_namer%   r%   r&   rW     s    zPyCodegen.load_import_fromc                 C   st   t jdkr^t||}t jdkr(d}d}nd}d}|| j|ksBttd|d}||| |S | |td	|d
gS )Nr   )r      CALLZPRECALLZKW_NAMESr|   CALL_FUNCTION_KWr   )r   r   r   opnamerC   r   insertrU   )r7   r   Zkw_namesrr   r1   idxZexpected_instZkw_names_instr%   r%   r&   create_call_function_kw  s    



z!PyCodegen.create_call_function_kwc                 C   s   t d|dS )NDELETE_FASTr|   r   r   r%   r%   r&   create_delete  s    zPyCodegen.create_delete)NNNN)T)F)r   )r   )9r    r!   r"   __doc__r   r   nnModulestrr8   r;   rB   rF   rc   rV   rX   r_   r9   rs   rO   ru   rx   r   r   rz   rS   r   ri   r   rU   rh   r]   r   r   r   r   r   r   r   r   r   r   r   r   r#   boolr   r   r   typesCodeTyper   r   r   rW   r   r   r%   r%   r%   r&   r'   +   sn       

r


   r'   )-r+   dataclassesrn   r   r   typingr   r   r   r   Ztorch.nnr   r   r   Zbytecode_transformationr   r	   r
   r   r   r   r   r   r   excr   rR   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$   ,