U
    zhl                     @   s   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m	Z	m
Z
 ddlmZmZmZmZmZmZmZmZmZmZ ddlmZ dZdZdZdZd	Zd
ZdZdZdZ dZ!dZ"ej#ddG dd dZ$ej#G dd dZ%dd Z&dd Z'G dd dZ(dS )    N)AnycastDictListOptionalTuple   )
create_call_functioncreate_call_methodcreate_dup_topcreate_instructioncreate_jump_absolutecreate_load_methodInstructionInstructionExnTabEntrytransform_code_object	unique_id)ExactWeakKeyDictionary                @         i   Ztorch_dynamo_resume_inT)frozenc                   @   sH   e Zd ZU eed< dZeeedf  ed< e	e
 dddZdd	 ZdS )
ReenterWithstack_indexN.target_values)cleanupc                    s  g }| j rdd | j D }td| j   |d krH|d   f7  < dD ]"}||d krL|d  |f7  < qLttjdk rdnd	}td}|tt|d
td dtd dtdft	dtdf}tjdk r|
td|d n2td}td}	t||	|| jd d|_|
|  fdd}
tjdk rTtdtd|f|
 tdf}ntjdk rtdf|
 td|d|f|
 td|f}nftddd}tddd}t|||| jd  d
|_|	f|
 td|d|f|
 ||td!tddd|f}|| |d"d"< |S )#z
        Codegen based off of:
        load args
        enter context
        try:
            (rest)
        finally:
            exit context
        c                 S   s   g | ]}t d |dqS 
LOAD_CONSTargvalr   .0val r)   P/var/www/html/venv/lib/python3.8/site-packages/torch/_dynamo/resume_execution.py
<listcomp>:   s   z*ReenterWith.try_except.<locals>.<listcomp>Z___context_manager_co_varnames)	__enter____exit__co_names      NOPPUSH_EXC_INFOT
STORE_FASTr#   	LOAD_FASTr-   r   POP_TOPSETUP_FINALLYtargetr   Fc                      s6   t d dtdt dd dt t ftdt dfS )Nr6   r#   r.   r"   r1   r7   )r   r   r   r
   r)   Zctx_namer)   r*   create_resetd   s    

z,ReenterWith.try_except.<locals>.create_resetr1   	   	POP_BLOCKBEGIN_FINALLYEND_FINALLYJUMP_FORWARDRERAISEargCOPYr1   r   
POP_EXCEPTN)r   r   r   r   sysversion_infor	   lenr   r
   appendr   exn_tab_entry)selfcode_optionsr    	load_argsnameZexcept_jump_targetcleanup_complete_jump_targetZsetup_finallyZexn_tab_beginZexn_tab_endr<   epilogueZfinally_exn_tab_endZfinally_exn_tab_targetr)   r;   r*   
try_except-   s    









zReenterWith.try_exceptc                 C   s  g }| j rdd | j D }tjdk rtd}td}td||tdtdg| |d	d	< |td
t|dtd|dtdfd	fS tjdk rFtd}td}td}tdtdd	dtdtdtd
ddtdtd|d|td|dtd|tdtdtdtd|g| |d	d	< |td
t|dtd|dtdfd	fS td}td}dd }	td}
td}td}tddd}tddd}t|
||| jd d |
_t|||| jd d |_t|||| jd d |_||	 |	 |	 ftdd!tdtd|d|tdttjd"k rd#nd|d||tdtddd|tdtdtd|f| |d	d	< |tt|d td$|
f|fS d	S )%zR
        Codegen based off of:
        with ctx(args):
            (rest)
        c                 S   s   g | ]}t d |dqS r!   r%   r&   r)   r)   r*   r+      s   z(ReenterWith.__call__.<locals>.<listcomp>r=   WITH_CLEANUP_STARTr@   r?   WITH_CLEANUP_FINISHrA   NCALL_FUNCTIONrD   
SETUP_WITHr9   r7   r0   ZWITH_EXCEPT_STARTr3   r"   r#   DUP_TOPr1   rB   POP_JUMP_IF_TRUErC   rG   c                   S   s   t dd dS )Nr"   r#   r%   r)   r)   r)   r*   create_load_none   s    z.ReenterWith.__call__.<locals>.create_load_noner4   r   rF   r   TFr1      ZPOP_JUMP_FORWARD_IF_TRUEZBEFORE_WITH)	r   rH   rI   r   rJ   r   r   rL   r	   )rM   rN   r    rO   Zwith_cleanup_startZbegin_finallyZwith_except_startZpop_top_after_with_except_startrQ   rZ   Zexn_tab_1_beginZexn_tab_1_endZexn_tab_1_targetZexn_tab_2_endZexn_tab_2_targetr)   r)   r*   __call__   s    
	



 
	

zReenterWith.__call__)__name__
__module____qualname__int__annotations__r   r   r   r   r   r   rS   r]   r)   r)   r)   r*   r   &   s   
nr   c                   @   s`   e Zd ZU ejed< ejedZ	e
e ed< ejedZe
e ed< dZeeeef  ed< dS )ResumeFunctionMetadatacode)default_factoryinstructions prefix_block_target_offset_remapNblock_target_offset_remap)r^   r_   r`   typesCodeTyperb   dataclassesfieldlistrf   r   r   rg   ra   rh   r   r   r)   r)   r)   r*   rc      s   

rc   c                 C   sX   t |}g }z2t|}| D ] }|||r|| t|}qW n tk
rR   Y nX |S )z
    Two-pointer conditional filter.
    e.g. _filter_iter(insts, sorted_offsets, lambda i, o: i.offset == o)
    returns the instructions with offsets in sorted_offsets
    )iternextrK   StopIteration)l1l2Zconditrescurr(   r)   r)   r*   _filter_iter0  s    

rv   c                 C   sb   g }t jdkr.|td |tddd | D ]}|td|d q2|tt| d |S )	Nr0   	PUSH_NULLZSWAPr   rD   r"   r#   F)rH   rI   rK   r   extendr	   rJ   )tupZinstsr(   r)   r)   r*   _load_tuple_and_callC  s    
rz   c                   @   s   e Zd Ze Ze Zedd Zeee	e ee	e
 e	e
 e	e e	ee	e f e	e
e	e f e	e ejd
ddZeee dddZeee	ed	f d
ddZdS )ContinueExecutionCachec                 G   sV   || j krt | j |< t|}|| j | krH| j||f| | j | |< | j | | S N)cachedicttuplegenerate)clsrd   linenokeyr)   r)   r*   lookupR  s    
zContinueExecutionCache.lookup)
offsetsetup_fn_target_offsetsnstackargnamesargnames_null	setup_fnsstack_ctx_varsargnames_ctx_vars
null_idxesreturnc                    s   	d k	st |jttB tB tB @ r&t |jt@ s4t |tjkr\	|	
 S t
jdkt|tt tttf d 	
fdd}t||}tj|< |S )Nr0   rf   rN   c                    s>  t | _dd tD    fddD  t|d pBg t|d pPg  }tt|}t d|d  d	 |d< r|d
 jddd}t	|dkr|d |d
< n6t	|dkst
|\}}| dt d| d	 |d
< |d< t |d< ||d< t	 |d< d|d< d|d< t  fddD   fdd|d D  |d< |d ttB  @ |d< t
fdd| D }g }r|r|tdt	|d |tddd g }dd D }	fddtD }
dd | D }i }d}t}tD ]}|t		k r>	| || kr>|td  |d7 }q|td!d"| d# ||	kr|	|}|||\}}|| r|
|}|| }j| |||< || }||kr |t||  q rttj_|	rt
D ]<\}}|td!|d# |t| |td$|d# qrtjd%ksNt
D ].}| ksdt
|td td$|d#g qR|t| | D ]2}|j|jkr qd |_tjd&krd |_q|r|| || |r*st
| D ],}|jr|jj|kr||jj |j_q||  | d d < d S )'Nc                 S   s   g | ]}d | qS )___stackr)   r'   ir)   r)   r*   r+     s     zCContinueExecutionCache.generate.<locals>.update.<locals>.<listcomp>c                 3   s   | ]}| kr|V  qd S r|   r)   r'   vargsr)   r*   	<genexpr>  s      zBContinueExecutionCache.generate.<locals>.update.<locals>.<genexpr>co_cellvarsco_freevars_co_nameZ_at_Zco_qualname.r   )maxsplitr   co_firstlinenoco_argcountr   co_posonlyargcountco_kwonlyargcountc                    s   g | ]}| kr|qS r)   r)   r   r   r)   r*   r+     s      c                    s   g | ]}| kr|qS r)   r)   r   r   r)   r*   r+     s      r,   co_flagsc                 3   s   | ]}|j  kr|V  qd S r|   r   r   r   r)   r*   r     s     
 ZCOPY_FREE_VARSrD   RESUMEc                 S   s   i | ]}|j |qS r)   r   )r'   fnr)   r)   r*   
<dictcomp>  s      zCContinueExecutionCache.generate.<locals>.update.<locals>.<dictcomp>c                    s   i | ]\}}|j  | qS r)   r   )r'   r   r   )r   r)   r*   r     s    c                 S   s   i | ]}|j |qS r)   r   )r'   instr)   r)   r*   r     s      rw   r6   r   r#   r5   r[   r0   ) copydeepcopyrf   rangerx   r   sortedTORCH_DYNAMO_RESUME_IN_PREFIXrsplitrJ   AssertionError
CO_VARARGSCO_VARKEYWORDSro   rK   r   	enumerater~   poprg   rz   rm   reversedrH   rI   r   r   starts_lineZ	positionsunreachable_codesrL   r:   )rf   rN   ZfreevarsZqualified_pathmodule_namer   r:   prefixr    hooksZhook_target_offsetsZoffset_to_instZold_hook_target_remapZnull_idxes_iZstack_ctx_vars_dr   hookZ
hook_instsZ
exn_targetZhook_target_offsetZold_hook_targetZreal_irP   valsr   r   r   r   r   r   Zis_py311_plusr   metar   r   r   r   r   r   r   r*   update  s    















z/ContinueExecutionCache.generate.<locals>.update)r   r   CO_GENERATORCO_COROUTINECO_ITERABLE_COROUTINECO_ASYNC_GENERATORCO_OPTIMIZEDr{   generated_code_metadata&generate_based_on_original_code_objectrH   rI   rc   r   r   r   strr   r   )r   rd   r   r   r   r   r   r   r   r   r   r   r   Znew_coder)   r   r*   r   [  s6    

8 

zContinueExecutionCache.generate)r   c                 C   s   t dddt dddgS )zACodegen a `raise None` to make analysis work for unreachable coder"   Nr#   RAISE_VARARGSr   rD   r%   )rN   r)   r)   r*   r     s    

z(ContinueExecutionCache.unreachable_codes.)r   r   c                    s   t j| dtt tttf dfdd}t|| tj	dkrj
si   _
tt tttf d fdd}t|| tfdd	D t jj|f| S )
a>  
        This handles the case of generating a resume into code generated
        to resume something else.  We want to always generate starting
        from the original code object so that if control flow paths
        converge we only generated 1 resume function (rather than 2^n
        resume functions).
        Nr   c                    sR   fdd| D \  fddt t| tjD \} j|jksHt|jd S )Nc                 3   s   | ]}|j  kr|V  qd S r|   r   r   r   r)   r*   r   .  s     
 ziContinueExecutionCache.generate_based_on_original_code_object.<locals>.find_new_offset.<locals>.<genexpr>c                 3   s   | ]\}}| kr|V  qd S r|   r)   )r'   i1i2r9   r)   r*   r   0  s   )zipr   rf   opcoder   r   )rf   rN   
new_target)r   
new_offsetr   r9   r*   find_new_offset*  s    
zVContinueExecutionCache.generate_based_on_original_code_object.<locals>.find_new_offsetr0   c           
         s   g }| D ].}t |t jkr" q8|jdkr|| qt|jD ]\}}|tt|j< qD|rrtt|d jnd t fddD }t	| |dd }t	tt
| t
j|dd }t||D ]\}}	|d j|	j< qd S )	Nr4   c                 3   s   | ]}| kr|V  qd S r|   r)   r'   nZold_start_offsetr)   r*   r   ^  s     zmContinueExecutionCache.generate_based_on_original_code_object.<locals>.remap_block_offsets.<locals>.<genexpr>c                 S   s
   | j |kS r|   r   )r   or)   r)   r*   <lambda>b      zlContinueExecutionCache.generate_based_on_original_code_object.<locals>.remap_block_offsets.<locals>.<lambda>c                 S   s   | d |kS )Nr   r)   )Zv1Zv2r)   r)   r*   r   g  r   r   )rJ   rg   opnamerK   r   r   ra   r   r   rv   r   rf   )
rf   rN   Zprefix_blocksr   r   Zold_inst_offsetstargetsZnew_targetsnewold)rh   r   r   r   r*   remap_block_offsetsB  s<    
   zZContinueExecutionCache.generate_based_on_original_code_object.<locals>.remap_block_offsetsc                 3   s   | ]} j | V  qd S r|   )rh   r   )r   r)   r*   r   o  s    zPContinueExecutionCache.generate_based_on_original_code_object.<locals>.<genexpr>)r{   r   r   r   r   r   r   r   rH   rI   rh   r   r   rd   )r   rd   r   r   r   r   r   r   r)   )rh   r   r   r   r   r*   r     s4     



 
*
   z=ContinueExecutionCache.generate_based_on_original_code_objectN)r^   r_   r`   r   r}   r   classmethodr   ra   r   r   r   r   ri   rj   r   staticmethodr   r   r   r   r)   r)   r)   r*   r{   N  s.   
 6 
r{   ))r   rk   rH   ri   typingr   r   r   r   r   r   Zbytecode_transformationr	   r
   r   r   r   r   r   r   r   r   utilsr   r   ZCO_NEWLOCALSr   r   	CO_NESTEDr   Z	CO_NOFREEr   r   r   r   	dataclassr   rc   rv   rz   r{   r)   r)   r)   r*   <module>   s8    0
 z  +