o
    h%3                     @   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 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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"m#Z# ej$G dd dZ%G dd dZ&dS )    N)List   )utils)create_call_functioncreate_dup_topcreate_instructioncreate_load_globalcreate_rot_nInstruction)unimplemented)
AttrSourceGeneratorStateSourceSource)is_safe_constantrot_n_helper)VariableTracker)NNModuleVariable)NumpyNdarrayVariableSymNodeVariableTensorVariableTensorWithTFOverrideVariableUnspecializedPythonVariablec                   @   s,   e Zd ZU eed< eed< defddZdS )GraphOutputEntryindexvariableotherc                 C   s   | j || _ d S N)r   add_options)selfr    r   K/var/www/html/ai/venv/lib/python3.10/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                   @   s4  e Zd ZdZ				dDdejjdefddZdd Z	dEd
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! Zd"d# ZdFd%d&Zd'd( Zd)d* ZeZd+d, Zd-d. ZdGd0d1Zd2d3 Zd4d5 Z	/dGd6ed7e j!d8e"fd9d:Z#d;d< Z$d6ed=e%e& fd>d?Z'd@dA Z(dBdC Z)dS )H	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   r2   r(   r)   r1   r   r   r    __init__0   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>D   s    z/PyCodegen.graph_output_vars.<locals>.<listcomp>)r/   valuesr   r   r   r    graph_output_varsC   s   zPyCodegen.graph_output_varsTc           	      C   s&  t |tr| j||  |   dS | jjj	|j t |t
s$J | j}| j}| j|u r7|t  dS |rk|jrS|j| jv rS|| | j|j  || _dS | j|durk|| | j|  || _dS |jdur|rt |jts||j|  n| rt| r|| |  nt |tr|j}| |}|| 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*rT|j+,d}|d | j-d	 v r4|| |d  |dd }n| j.dus<J || /| j. |D ]}|| )| qGn:| j0|  d7  < z
|||  W n t1yx   t2d
|  Y nw |r|| jv r| jt  | 3| || _dS )z:Generate code such that top-of-stack (TOS) is set to valueNTaddr   to_numpy_helperitemr   .co_varnameszreconstruct: )4
isinstancer   r0   extendreconstruct	clear_tosr2   r3   guardsupdater   r/   r*   appendr   mutable_localr1   create_loadgetsourcer   is_python_constantr   as_python_constantcreate_load_constr   tensor_variableadd_graph_outputr   global_class_nameload_graph_outputr   r   r   r   r   r   load_import_fromr   r"   need_unwrapcreate_load_attrr   
module_keysplitr4   r(   create_load_outputr-   NotImplementedErrorr   	add_cache)	r   valueallow_cacher3   r/   rS   graph_outputs_keypartspartr   r   r    __call__F   s   







	



zPyCodegen.__call__c                 C   sD   t | }|| jvrtt| j|| j|< |S | j| | |S r   )idas_proxyr/   r   lenr!   )r   r_   ra   r   r   r    rT      s   


zPyCodegen.add_graph_outputc                 C   s:   | j }|| | j || | |td d S )NBINARY_SUBSCR)r0   rK   rM   r)   _create_load_constr   )r   r   r3   r   r   r    rV      s   zPyCodegen.load_graph_outputc                 C   s:   |   }|| j|< |jr|| j|j< | j| | d S r   )r6   r1   rL   r0   rK   create_store)r   r_   varr   r   r    r^      s
   
zPyCodegen.add_cachec                 C   s   |D ]}| | qd S r   r   )r   itemsir   r   r    foreach   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subr2   	f_globalsre   r   )r   namer_   	push_nullrr   r   r   r    setup_globally_cached   s   zPyCodegen.setup_globally_cachedc                 C   s
   d | _ d S r   )r*   r=   r   r   r    rH      s   
zPyCodegen.clear_tosc                 C   s&   t |tsJ | j| |   d S r   )rE   r
   r0   rK   rH   )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   )rE   r
   r8   r   r   r    	<genexpr>   s    z*PyCodegen.extend_output.<locals>.<genexpr>)allr0   rF   rH   )r   instsr   r   r    extend_output   s   zPyCodegen.extend_outputc                 C   s   | j S r   )r0   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argvalrD   z missing	LOAD_FASTr5   r   r4   r   rs   r   r   r    rM      s   zPyCodegen.create_loadc                 C   s   ||   v sJ td|dS )NLOAD_CLOSUREr~   )r5   r   r   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_DEREFr~   rD   
STORE_FASTr   r   r   r   r    rj      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)r2   r3   update_co_namesr4   r   )r   rs   rt   r@   r   r   r    r      s   
zPyCodegen.create_load_globalc                 C   s    t |sJ d| | |S )Nzunsafe constant )r   ri   r   r_   r   r   r    rR      s   
zPyCodegen.create_load_constc                 C   s   t d|dS )N
LOAD_CONSTr~   )r   r   r   r   r    ri      s   zPyCodegen._create_load_constc                 C   s.   || j d vr| j d  |f7  < td|dS )Nr   	LOAD_ATTRr~   )r4   r   r   r   r   r    rY      s   zPyCodegen.create_load_attrc                    s    fdd| dD S )Nc                    s   g | ]}  |qS r   )rY   )r9   rs   r=   r   r    r;      s    z/PyCodegen.create_load_attrs.<locals>.<listcomp>rC   )r[   )r   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_inforF   r   rot_nr   )r   fn_namert   num_on_stackr3   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   ri   r   )r   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   ri   r   r   r=   r   r   r    pop_null  s   zPyCodegen.pop_nullr   codert   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   r   r~   r   r   MAKE_FUNCTION   )co_freevarsr0   r   r   rK   r   rF   r   r5   rg   rR   rH   )r   r   r   rt   r   freevarsr3   rk   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?   
___module_ro   )
r2   r3   global_scoperp   rq   r"   rN   r   re   install_global)r   modrt   r   rs   mangled_namer   r   r    create_load_python_module6  s   
z#PyCodegen.create_load_python_modulereturnc                 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_nameT	as_tensorr   FN)r{   r   r2   r3   	graphargsis_unspecializedr   torchrY   loadr   rg   )r   r   r   r   r   r   r    make_call_generated_codeC  s   

z"PyCodegen.make_call_generated_codec                 C   s"   |  t| j|||  d S r   )r{   r   r2   import_sourcerG   )r   module_nameobject_namer   r   r    rW   W  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   PRECALLKW_NAMESr~   CALL_FUNCTION_KWr   )r   r   r   opnamer   insertrR   )r   nargskw_namesrt   r3   kw_names_instr   r   r    create_call_function_kw^  s   


z!PyCodegen.create_call_function_kw)NNNN)T)F)r   )*r"   r#   r$   __doc__r   nnModulestrr7   r>   rd   rT   rV   r^   rn   ru   rH   rw   r{   r|   rM   r   rj   r   rR   ri   r\   rY   r   r   r   r   typesCodeTypeboolr   r   r   r
   r   rW   r   r   r   r   r    r'   +   s\    

Y



r'   )'r+   dataclassesrp   r   r   typingr   torch.nnr   r   r   bytecode_transformationr   r   r   r   r	   r
   excr   rO   r   r   r   r   r   variables.baser   variables.nn_moduler   variables.tensorr   r   r   r   r   	dataclassr   r'   r   r   r   r    <module>   s$     		