o
    i:1                     @   s   d dl m Z  d dl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	m
Z
mZ ddlZddlZddlZddlZddlZddlZddlZddlZejG dd	 d	eZejd
d Zejdd ZejdddZejdd ZdS )   )patched_boxed_run)patched_lazy_format_graph_code)patched_load_by_key_path)patched__exec_with_source    )ListTupleDictUnionCallableOptionalAnyNc                   @   s<   e Zd ZU eed< eed< ejeddZ	e
ed< dd ZdS )	DebuggableHookdump_src_dirlog_bytecodeF)default_factoryinitoptimized_code_and_modulec              
   C   s  t  }dd l}	 |j}|jj}|jj|jj	d }|dkr$|dkr$nq	|j
d }|j|ks1J | j||jg ddlm} zdd l}|jdd	d
d	dd	dd	}|j| jd| d}	ddlm}
 ddlm} |
|	 |j|||	d}|j}W d    n1 sw   Y  | jr|
|l dd l}tt ||t|d d W d    n1 sw   Y  tt ||t|d d W d    n1 sw   Y  tt ||t|d d W d    n1 sw   Y  W d    n	1 sw   Y  ddlm} ddl m!} |"| |||< |W S  |t#fyd } z2ddl$m%} | }dd l&}t'd|d |j&||d t'd|d t()|*  t+,  W Y d }~d S d }~ww )Nr   T_compilezconvert_frame.pyframe)DecompilationError._<> z__transformed_code_%s_for_z.py)lock_on_file)
Decompiler)code_to_decompilereference_codefilepath_templatez.original_bytecodewbz.transformed_bytecodez&.decompiled_and_compiled_back_bytecode)orig_code_map)output_codes)StringIOzEThere is a problem when decompiling and compiling the following code:)filezGPlease consider submitting an issue to https://github.com/thuml/depyf .)-sys	_getframeosf_backf_codeco_nameco_filenamesplitpathsepf_localsr   append	f_globalsdepyf.decompilerr   replacejoinr   depyf.explain.utilsr   r   decompile_and_compile_liker   dill
contextlibsuppress	Exceptiondumpopentorch._dynamo.utilsr#   torch._dynamo.convert_framer$   addSyntaxErrorior%   disprintwarningswarngetvalue	traceback	print_exc)selfcodenew_coder   r)   	code_name	file_namer   	func_namer!   r   r   !decompiled_and_compiled_back_codefilenamer9   r#   r$   er%   	string_iorD    rU   [/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/depyf/explain/enable_debugging.py__call__   sp   
&



zDebuggableHook.__call__N)__name__
__module____qualname__str__annotations__booldataclassesfieldlistr   r   rW   rU   rU   rU   rV   r      s
   
 r   c              
   c   s`    t | |d }|d urt| || zd V  W |d ur"t| || d S d S |d ur/t| || w w )N)getattrsetattr)parentnamevalue	old_valuerU   rU   rV   patchT   s   rg   c                 c   s8    dd l }|jj| }z
d V  W |  d S |  w )Nr   )torch_dynamoconvert_frameregister_bytecode_hookremove)hookrh   handlerU   rU   rV   enable_bytecode_hook`   s   ro   TFc                 #   s   t | ts
tdddl}ddl}t jd }t	t
 d| dtdd ddlm} |j| s7||  |j| } dd	lm} | |d
< |jjj|d< |jjjj|d< |jjjj|d< d|d< t| |}t|jjdt  t|jjjdt! t|jj"j#dt$j% t&| zdV  W dd |j'D }	|j'D ]p\ }
 j()drt* fdd|	D rq j()drt* fdd|	D rqddl+m,} ddl-m.} ddl/m0}m1} | }|st jd }t	t
 d| d  dtdd | |
}|j2| d j( d }|||}q|3| D ]4}|4|jj5d! }|r(|)d"s.|6d#rGz|7|j2| | W q t8yF   Y qw qd$|d< ndd |j'D }	|j'D ]x\ }
 j()drrt* fdd|	D rrqY j()drt* fdd|	D rqYddl+m,} ddl-m.} ddl/m0}m1} | }|st jd }t	t
 d| d  dtdd | |
}|j2| d j( d }|||}qY|3| D ]4}|4|jj5d! }|r|)d"s|6d#r
z|7|j2| | W q t8y	   Y qw qd$|d< w W d   n	1 sw   Y  W d   n	1 s,w   Y  W d   n1 s<w   Y  W d   dS W d   dS 1 sUw   Y  dS )%a|  
    A context manager to dump debugging information for torch.compile.
    It should wrap the code that actually triggers the compilation, rather than
    the code that applies ``torch.compile``.

    Example:

    .. code-block:: python

        import torch

        @torch.compile
        def toy_example(a, b):
            x = a / (torch.abs(a) + 1)
            if b.sum() < 0:
                b = b * -1
            return x * b

        def main():
            for _ in range(100):
                toy_example(torch.randn(10), torch.randn(10))

        if __name__ == "__main__":
            # main()
            # surround the code you want to run inside `with depyf.prepare_debug`
            import depyf
            with depyf.prepare_debug("./dump_src_dir"):
                main()

    After running the code, you will find the dumped information in the directory ``dump_src_dir``. The details are organized into the following:

    - ``full_code_for_xxx.py`` for each function using torch.compile
    - ``__transformed_code_for_xxx.py`` for Python code associated with each graph.
    - ``__transformed_code_for_xxx.py.xxx_bytecode`` for Python bytecode, dumped code object, can be loaded via ``dill.load(open("/path/to/file", "wb"))``. Note that the load function might import some modules like transformers. Make sure you have these modules installed.
    - ``__compiled_fn_xxx.py`` for each computation graph and its optimization:
        - ``Captured Graph``: a plain forward computation graph
        - ``Joint Graph``: joint forward-backward graph from AOTAutograd
        - ``Forward Graph``: forward graph from AOTAutograd
        - ``Backward Graph``: backward graph from AOTAutograd
        - ``kernel xxx``: compiled CPU/GPU kernel wrapper from Inductor.

    Arguments:

    - ``dump_src_dir``: the directory to dump the source code.
    - ``clean_wild_fx_code``: whether to clean the wild fx code that are not recognized for parts of compiled functions. They are usually used by PyTorch internally.
    - ``log_bytecode``: whether to log bytecode (original bytecode, transformed bytecode from Dynamo, and decompiled_and_compiled_back_code).
    zYou are using an obsolete usage style`depyf.prepare_debug(func=function, dump_src_dir="/path")`. Please use `depyf.prepare_debug(dump_src_dir="/path")` instead, which will automatically capture all compiled functions.r   Nr   :z|: You are trying to debug `torch.compile`. Please make sure the code runs multiple times to cover all the possible branches. )safe_create_directorydatar   unpatched__exec_with_sourceunpatched_load_by_key_pathunpatched___call__Tis_inside_prepare_debug_exec_with_sourceload_by_key_path__code__c                 S   s   h | ]}|d  j qS )r   r,   ).0xrU   rU   rV   	<setcomp>   s    z prepare_debug.<locals>.<setcomp>
resume_in_c                 3        | ]}d |  j v V  qdS )r   Nr|   r}   rd   rL   rU   rV   	<genexpr>       z prepare_debug.<locals>.<genexpr>torch_dynamo_resume_in_c                 3   r   )r   Nr|   r   r   rU   rV   r      r   )dump_src)write_code_to_file_template)innermost_fn_debug_get_cache_entry_listz: Code object z is compiled but does not have any compiled cache entries. Probably some torch.nn.Module instances are destroyed too early. It is recommended to make sure the torch.nn.Module instances exist after `with depyf.prepare_debug`.full_code_for_z_%s.pyr   fx_graph_codez.lockF)9
isinstancer[   RuntimeErrorr)   rh   inspectcurrentframef_linenorF   warn_explicit__file__UserWarningdepyf.utilsrr   r/   existsabspathglobal_variablesrt   fxgraph_modulery   	_inductor	codecachePyCodeCacherz   ri   
eval_frameOptimizeContextrW   r   rg   r   r   utilslazy_format_graph_coder   r{   ro   r   r,   
startswithanydepyf.explainr   r7   r   torch._dynamo.eval_framer   r   r6   listdirr.   r0   endswithrl   OSError)r   clean_wild_fx_coder   r)   rh   current_line_numberrr   rt   bytecode_hook
code_namesmoduler   r   r   r   entriesfull_srcr!   full_code_pathr&   rd   rU   r   rV   prepare_debugj   s   
2

"""

&&"
T r   c               
   c   s    ddl m}  | d rtd| d }ddl}|jjjd}t|j	j
jd	tj- zd
| d}t| t  dV  W |jjj| n	|jjj| w W d   dS 1 sYw   Y  dS )a  
    A context manager to debug the compiled code. Essentially, it sets a breakpoint to pause the program and allows you to check the full source code in files with prefix ``full_code_for_`` in the ``dump_src_dir`` argument of :func:`depyf.prepare_debug`, and set breakpoints in their separate ``__transformed_code_`` files according to the function name. Then continue your debugging.
    r   rs   rx   z:You cannot use `depyf.debug` inside `depyf.prepare_debug`.r   r   NFr{   z`depyf` places a breakpoint here to pause the program. You can check the full source code in files with prefix `full_code_for_` in zq first, and set breakpoints in their separate files according to the function name. Then continue your debugging.)r   rt   r   rh   _Cri   r   set_eval_framerg   r   Interpreter	boxed_runr   r{   rE   
breakpoint)rt   r   rh   callbackmsgrU   rU   rV   debug   s   &"r   )TF)r   r   r   r   typingr   r   r	   r
   r   r   r   r:   rF   rI   r^   	itertoolsr'   r)   r   	dataclassobjectr   contextmanagerrg   ro   r   r   rU   rU   rU   rV   <module>   s.    $A

	y