a
    d8/                     @   s   d dl Z d dlZd dlZd dlZd dlmZ d dl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mZ ddlmZ dd	lmZ dd
lmZmZmZmZ ejG dd dZ G dd dZ!dS )    N)List   )create_dup_topcreate_instructioncreate_rot_nInstruction)unimplemented)
AttrSourceSource)is_safe_constantistyperot_n_helper)VariableTracker)NNModuleVariable)SymNodeVariableTensorVariableTensorWithTFOverrideVariableUnspecializedPythonVariablec                   @   s,   e Zd ZU eed< eed< edddZdS )GraphOutputEntryindexvariable)otherc                 C   s   | j || _ d S N)r   add_options)selfr    r   ^/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torch/_dynamo/codegen.pymerge!   s    zGraphOutputEntry.mergeN)__name__
__module____qualname__int__annotations__r   r   r   r   r   r   r      s   
r   c                   @   s  e Zd ZdZd=ejjed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dd Zdd Zd?d d!Zd"d# Zed$d% Zd&d' ZeZd(d) Zd*d+ Zd@d-d.Zd/d0 ZdAeej d1d2d3Z!d4d5 Z"ee#e$ d6d7d8Z%d9d: Z&d;d< Z'dS )B	PyCodegenz<
    Helper class uses for constructing Python bytecode
    N)rootgraph_output_varc                 C   sb   || _ d | _t | _t | _g | _|p,i | _|| _	|| _
| j	jj| _| j	j| _| j	jj| _d S r   )r$   top_of_stackcollectionsCounterusesOrderedDictgraph_outputs_outputtempvarstxr%   outputcode_optionscell_and_freevarsnew_var)r   r.   r$   r%   r-   r   r   r   __init__+   s    



zPyCodegen.__init__c                 C   s   dd | j  D S )Nc                 S   s   g | ]
}|j qS r   )r   .0xr   r   r   
<listcomp>?       z/PyCodegen.graph_output_vars.<locals>.<listcomp>)r+   valuesr   r   r   r   graph_output_vars>   s    zPyCodegen.graph_output_varsTc                 C   s  t |tr(| j||  |   dS | jjj	|j t |t
sHJ | j}| j}| j|u rn|t  dS |r|jr|j| jv r|| | j|j  || _dS | j|dur|| | j|  || _dS |jdur|r||j|  n| r*t| r*|| |  nt |ttttfrt |trP|j}t|j}||vrxtt ||||< n|| !| || | j" || #|| j$ |t%d t |tr|j&r|| 'dt%ddg nt |t(r||j)*d}|d | j+d v r<|| |d  |dd }n"| j,dusLJ || -| j, |D ]}|| '| qbnt| j.|  d7  < z|||  W n" t/y   t0d	|  Y n0 |r|| jv r| jt  | 1| || _dS )
z:Generate code such that top-of-stack (TOS) is set to valueNBINARY_SUBSCRitemCALL_FUNCTIONr   .co_varnamesr   zreconstruct: )2
isinstancer
   r,   extendreconstruct	clear_tosr.   r/   Zguardsupdater   r+   r&   appendr   mutable_localr-   create_loadgetsourceZis_python_constantr   Zas_python_constantcreate_load_constr   r   r   r   Ztensor_variableidproxyr   lenr   r%   _create_load_constr   r   Zneed_unwrapcreate_load_attrr   Z
module_keysplitr0   r$   create_load_outputr)   NotImplementedErrorr   	add_cache)r   valueZallow_cacher/   r+   Zgraph_outputs_keypartspartr   r   r   __call__A   s    

	



zPyCodegen.__call__c                 C   s:   |   }|| j|< |jr$|| j|j< | j| | d S r   )r2   r-   rG   r,   rF   create_store)r   rU   varr   r   r   rT      s
    
zPyCodegen.add_cachec                 C   s   |D ]}| | qd S r   r   )r   itemsir   r   r   foreach   s    zPyCodegen.foreachc                 C   sP   t dd|}| jj}||v r8t|| t|ks@J n|||< | j|ddgS )zStore value in a new globalz[^a-zA-Z0-9_]+_Tadd)resubr.   	f_globalsrL   create_load_global)r   namerU   rc   r   r   r   setup_globally_cached   s    zPyCodegen.setup_globally_cachedc                 C   s
   d | _ d S r   )r&   r:   r   r   r   rD      s    zPyCodegen.clear_tosc                 C   s&   t |tsJ | j| |   d S r   )rA   r   r,   rF   rD   )r   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   )rA   r   r4   r   r   r   	<genexpr>   r8   z*PyCodegen.extend_output.<locals>.<genexpr>)allr,   rB   rD   )r   Zinstsr   r   r   extend_output   s    zPyCodegen.extend_outputc                 C   s   | j S r   )r,   r:   r   r   r   get_instructions   s    zPyCodegen.get_instructionsc                 C   sV   ||   v r"td|   ||S || jd v s>J | dtd| jd ||S )N
LOAD_DEREFr@   z missing	LOAD_FASTr1   r   r   r0   r   re   r   r   r   rH      s    zPyCodegen.create_loadc                 C   s&   ||   v sJ td|   ||S )NLOAD_CLOSURE)r1   r   r   rp   r   r   r   create_load_closure   s    zPyCodegen.create_load_closurec                 C   sL   ||   v r"td|   ||S || jd v s4J td| jd ||S )NSTORE_DEREFr@   
STORE_FASTro   rp   r   r   r   rY      s    zPyCodegen.create_storeFc                 C   sF   |r| j j| || jd v s.J | dtd| jd ||S )Nco_namesz not in co_namesLOAD_GLOBAL)r.   r/   Zupdate_co_namesr0   r   r   )r   re   r`   r   r   r   rd      s    zPyCodegen.create_load_globalc                 C   s    t |sJ d| | |S )Nzunsafe constant )r   rO   )r   rU   r   r   r   rK      s    zPyCodegen.create_load_constc                 C   sr   | d }t |tsJ d }t|D ](\}}t|t|u r"||kr"|} qLq"|d u rnt|}||f }|| d< |S )N	co_consts)r   tuple	enumeratetyperN   )r0   rU   rw   r   r\   vr   r   r   get_const_index   s    
zPyCodegen.get_const_indexc                 C   s   |  | j|}td||S )N
LOAD_CONST)r|   r0   r   )r   rU   r   r   r   r   rO      s    zPyCodegen._create_load_constc                 C   s<   || j d vr$| j d |f | j d< td| j d ||S )Nru   	LOAD_ATTR)r0   r   r   rp   r   r   r   rP      s
    zPyCodegen.create_load_attrc                    s    fdd| dD S )Nc                    s   g | ]}  |qS r   )rP   )r5   re   r:   r   r   r7     r8   z/PyCodegen.create_load_attrs.<locals>.<listcomp>r?   )rQ   )r   namesr   r:   r   create_load_attrs   s    zPyCodegen.create_load_attrsr   c                 C   s   | j |ddg| |d  S )z6Load the global fn_name on the stack num_on_stack downTr_   r   )rd   rot_n)r   fn_namenum_on_stackr   r   r   load_function_name  s    zPyCodegen.load_function_namec                 C   sV   z
t |W S  tyP   td|| t|gt d tddtd|g  Y S 0 d S )NBUILD_TUPLE   CALL_FUNCTION_EXr   UNPACK_SEQUENCE)r   AttributeErrorr   rO   r   )r   nr   r   r   r   	  s    
zPyCodegen.rot_n)r   codec                 C   s   |j }|sJ | j}|D ]0}||  v s,J |td|  || q|tdt| || | || | |tdd || 	|d  | 
  d S )Nrq   r   MAKE_FUNCTION   r   )co_freevarsr,   r1   rF   r   r   rN   rK   rB   r   rD   )r   r   r   r   Zfreevarsr/   rZ   r   r   r   make_function_with_closure  s     z$PyCodegen.make_function_with_closurec                 C   sr   | j jj}tdd|j}||d|u r8| j|ddS d| dt| }||vrd| j j	|| | j|ddS )zT
        Generate a LOAD_GLOBAL instruction to fetch a given python module.
        z^.*[.] NTr_   Z
___module_r^   )
r.   r/   root_globalsra   rb   r   rI   rd   rL   Zinstall_global)r   modr   re   Zmangled_namer   r   r   create_load_python_module.  s    
z#PyCodegen.create_load_python_module)r   returnc                 C   s   |  | | | jjj}|D ]X}|jrf|  | t| dg |  |	|  |  t
ddg q|  |	|  q| t
dt| dS )z2Call the generated code function stored in fn_nameZtensorr>   r   N)rk   r   r.   r/   	graphargsZis_unspecializedr   torchrP   loadr   rh   rN   )r   r   r   argr   r   r   make_call_generated_code;  s     
z"PyCodegen.make_call_generated_codec                 C   s"   |  t| j|||  d S r   )rk   r	   r.   Zimport_sourcerC   )r   module_nameZobject_namer   r   r   load_import_fromS  s
    zPyCodegen.load_import_fromc                 C   s   t dS )NZBEGIN_FINALLY)r   r:   r   r   r   create_begin_finallyZ  s    zPyCodegen.create_begin_finally)NNNN)T)F)r   )r   )(r   r   r    __doc__r   nnModulestrr3   r;   rX   rT   r]   rf   rD   rh   rk   rl   rH   rr   rY   rd   rK   staticmethodr|   rO   rR   rP   r   r   r   typesCodeTyper   r   r   r   r   r   r   r   r   r   r   r#   &   sN       
X





 r#   )"r'   Zdataclassesra   r   typingr   Ztorch.nnr   Zbytecode_transformationr   r   r   r   excr   rJ   r	   r
   utilsr   r   r   Zvariables.baser   Zvariables.nn_moduler   Zvariables.tensorr   r   r   r   Z	dataclassr   r#   r   r   r   r   <module>   s   	