U
    ªÊ¹j%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< edœdd„ZdS )ÚGraphOutputEntryÚindexÚvariable)Úotherc                 C   s   | j  |¡| _ d S ©N)r   Úadd_options)Úselfr   © r   úT/var/www/html/bwave/python/venv/lib/python3.8/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dAejjedœdd„Zdd„ Z	dBd	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dCd$d%„Zd&d'„ Zd(d)„ ZeZd*d+„ Zd,d-„ ZdDd/d0„Zd1d2„ Zd3d4„ ZdEee j!e"d5œd6d7„Z#d8d9„ Z$ee%e& d:œd;d<„Z'd=d>„ Z(d?d@„ Z)dS )FÚ	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
ƒsHt‚| j}| j}| j|krn| tƒ ¡ 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t |jtƒ�s| |j | ¡¡ �n(| ¡ �r<t| ¡ ƒ�r<| |  | ¡ ¡¡ �nøt |tƒ�r–|j}|  |¡}| | j| ¡ ddd�¡ |  || j ¡ | t!ddƒ¡ �nžt |t"t#t$t%fƒ�r0|  |¡}t |t%ƒ�rÎ|  &t'j(d¡ |  || j ¡ t |t%ƒ�rü| t!ddƒ¡ n0t |t$ƒ�r4|j)�r4| |  *d¡gt!ddƒ ¡ �nt |t+ƒ�r¾|j, -d¡}|d | j.d	 k�r~| |  |d ¡¡ |dd… }n"| j/dk	�sŽt‚| |  0| j/¡¡ |D ]}| |  *|¡¡ �q¤nv| j1|  d7  < z| | | ¡¡ W n$ t2k
�r   t3d
|› �ƒ Y nX |�r4|| jk�r4| j tƒ ¡ |  4|¡ || _dS )z:Generate code such that top-of-stack (TOS) is set to valueNT©Úaddr   Zto_numpy_helperÚitemr   Ú.Úco_varnameszreconstruct: )5Ú
isinstancer   r0   ÚextendÚreconstructÚ	clear_tosr2   r3   ZguardsÚupdater   ÚAssertionErrorr/   r*   Úappendr   Úmutable_localr1   Úcreate_loadÚgetÚsourcer   Zis_python_constantr   Zas_python_constantÚcreate_load_constr   Útensor_variableÚadd_graph_outputr   Zglobal_class_nameÚload_graph_outputr   r   r   r   r   r   Úload_import_fromr   r"   Zneed_unwrapÚcreate_load_attrr   Z
module_keyÚsplitr4   r(   Úcreate_load_outputr-   ÚNotImplementedErrorr   Ú	add_cache)	r   ÚvalueZallow_cacher3   r/   rP   Úgraph_outputs_keyÚpartsÚpartr   r   r    Ú__call__F   s–    

ÿþ
ýÿ
ÿüþ	
ÿ
zPyCodegen.__call__c                 C   sB   t | ¡ ƒ}|| jkr.tt| jƒ|ƒ| j|< n| j|  |¡ |S r   )ÚidZas_proxyr/   r   Úlenr!   )r   rY   rZ   r   r   r    rQ   Ÿ   s    
 ÿzPyCodegen.add_graph_outputc                 C   s:   | j }| |  | j¡¡ | |  |¡¡ | tdƒ¡ d S )NÚBINARY_SUBSCR)r0   rJ   rL   r)   Ú_create_load_constr   )r   r   r3   r   r   r    rR   ª   s    zPyCodegen.load_graph_outputc                 C   s:   |   ¡ }|| j|< |jr$|| j|j< | j |  |¡¡ d S r   )r6   r1   rK   r0   rJ   Úcreate_store)r   rY   Úvarr   r   r    rX   °   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}||kr8t|| ƒt|ƒks@t‚n|||< | j||dd�gS )zStore value in a new globalz[^a-zA-Z0-9_]+Ú_Tr?   )ÚreÚsubr2   Ú	f_globalsr^   rI   r   )r   ÚnamerY   Ú	push_nullrj   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t‚| j |¡ |  ¡  d S r   )rD   r
   rI   r0   rJ   rG   )r   Ú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 r   )rD   r
   r8   r   r   r    Ú	<genexpr>Î   s     z*PyCodegen.extend_output.<locals>.<genexpr>)ÚallrI   r0   rE   rG   )r   Z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@   ||   ¡ krtd|d�S || jd ks4t|› d�ƒ‚td|d�S )NÚ
LOAD_DEREF©ÚargvalrC   z missingÚ	LOAD_FAST©r5   r   r4   rI   ©r   rk   r   r   r    rL   Õ   s    zPyCodegen.create_loadc                 C   s   ||   ¡ kst‚td|d�S )NÚLOAD_CLOSUREru   )r5   rI   r   ry   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_DEREFru   rC   Ú
STORE_FASTrx   ry   r   r   r    rb   ß   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)r2   r3   Zupdate_co_namesr4   rI   r   )r   rk   rl   r@   r   r   r    r   å   s    zPyCodegen.create_load_globalc                 C   s    t |ƒstd|› �ƒ‚|  |¡S )Nzunsafe constant )r   rI   ra   ©r   rY   r   r   r    rO   ë   s    zPyCodegen.create_load_constc                 C   s   t d|d�S )NÚ
LOAD_CONSTru   )r   r   r   r   r    ra   ï   s    zPyCodegen._create_load_constc                 C   s.   || j d kr"| j d  |f7  < td|d�S )Nr~   Ú	LOAD_ATTRru   )r4   r   ry   r   r   r    rT   ô   s    zPyCodegen.create_load_attrc                    s   ‡ fdd„|  d¡D ƒS )Nc                    s   g | ]}ˆ   |¡‘qS r   )rT   )r9   rk   r=   r   r    r;   ú   s     z/PyCodegen.create_load_attrs.<locals>.<listcomp>rB   )rU   )r   Únamesr   r=   r    Úcreate_load_attrsù   s    zPyCodegen.create_load_attrsr   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   FTr?   )ÚsysÚversion_inforE   r   Úrot_nr   )r   Úfn_namerl   Únum_on_stackr3   r   r   r    Úload_function_nameü   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©Úargé   ÚCALL_FUNCTION_EXr   ÚUNPACK_SEQUENCE)r	   ÚAttributeErrorr   ra   r   )r   Únr   r   r    rŠ     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 r   r   r   r   r   r    Ú<lambda>  ó    z$PyCodegen.pop_null.<locals>.<lambda>r   FÚPOP_TOP)rˆ   r‰   rI   ra   r   r   r=   r   r   r    Úpop_null  s    ÿýzPyCodegen.pop_null)r‹   Úcoderl   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   rz   ru   rŽ   r�   ÚMAKE_FUNCTIONé   )Úco_freevarsrI   r0   rˆ   r‰   rJ   r   rE   rŠ   r5   r_   rO   rG   )r   r‹   rš   rl   rŒ   Zfreevarsr3   rc   r   r   r    Úmake_function_with_closure"  s     
z$PyCodegen.make_function_with_closurec                 C   sv   | j jj}t dd|j¡}| |d¡|kr:| j||dd�S d|› dt|ƒ› �}||krf| j j 	||¡ | j||dd�S )zT
        Generate a LOAD_GLOBAL instruction to fetch a given python module.
        z^.*[.]Ú NTr?   Z
___module_rg   )
r2   r3   Úglobal_scoperh   ri   r"   rM   r   r^   Zinstall_global)r   Úmodrl   r    rk   Zmangled_namer   r   r    Úcreate_load_python_module6  s    
z#PyCodegen.create_load_python_module)r‹   Úreturnc                 C   s’   |   |  |d¡¡ | jjj}|D ]X}|jrh|   |  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)rr   r�   r2   r3   Ú	graphargsZis_unspecializedr¢   ÚtorchrT   Úloadr   r_   )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   )rr   r   r2   Zimport_sourcerF   )r   Úmodule_nameZobject_namer   r   r    rS   W  s
    ÿÿzPyCodegen.load_import_fromc                 C   sX   t jdkrBt||ƒ}|d jdks&t‚td|d�}| d|¡ |S |  |¡td|d�gS )Nr„   éþÿÿÿZPRECALLZKW_NAMESru   ÚCALL_FUNCTION_KWr�   )rˆ   r‰   r   ÚopnamerI   r   ÚinsertrO   )r   ÚnargsZkw_namesrl   r3   Zkw_names_instr   r   r    Úcreate_call_function_kw^  s    


þz!PyCodegen.create_call_function_kw)NNNN)T)F)r   )r   )*r"   r#   r$   Ú__doc__r¥   ÚnnÚModuleÚstrr7   r>   r]   rQ   rR   rX   rf   rm   rG   ro   rr   rs   rL   r{   rb   r   rO   ra   rV   rT   rƒ   r�   rŠ   r™   ÚtypesÚCodeTypeÚboolrž   r¢   r   r
   r§   rS   r®   r   r   r   r    r'   +   sT       ûü
Y


 ÿ  ÿr'   )'r+   Údataclassesrh   rˆ   r³   Útypingr   Ztorch.nnr¥   rŸ   r   Zbytecode_transformationr   r   r   r   r	   r
   Úexcr   rN   r   r   r   r   r   Zvariables.baser   Zvariables.nn_moduler   Zvariables.tensorr   r   r   r   r   Ú	dataclassr   r'   r   r   r   r    Ú<module>   s"    		