o
    I&iG                  	   @   sf  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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mZmZmZ d dlmZ d dlmZmZmZ d dlZd dl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# d d
l$m%Z% d dl&m'Z' ddl(m)Z)m*Z* ddl+m,Z,m-Z-m.Z.m/Z/m0Z0 ddl1m2Z2 e3e4Z5ee Z6e 7dddgZ8g dZ9e:dde;fddZ<d5dee, fddZ=dee, dej>fddZ?		 d6de6dee@e@f dee@ d eAfd!d"ZBdee@e@f fd#d$ZCd%ejj de6ddfd&d'ZDejEd(d) ZFG d*d+ d+ZGG d,d- d-ZHejIG d.d/ d/ZJeK ZLd0d1 ZMd2e@fd3d4ZNdS )7    N)AnyDictListOptional)patch)
draw_graphget_aot_graph_nameget_graph_being_compiled)fx)save_graph_reprowrap_compiler_debug)get_debug_dir)GraphModule)_extract_tensor_metadataTensorMetadata)legalize_graph)tree_map   )configir)BaseSchedulerNodeFusedSchedulerNodeNopKernelSchedulerNode
OutputNodeSchedulerNode)VBufMetanameZn_origin)dotz-Gnslimit=2z-Gnslimit1=2z-Gmaxiter=5000returnc                   C   s2   zt jddgt jd W dS  t jy   Y dS w )Nwhichr   )stderrTF)
subprocesscheck_outputPIPESubprocessError r&   r&   @C:\wamp64\www\opt\env\Lib\site-packages\torch/_inductor/debug.pyhas_dot.   s   r(   Fnodesc           	   	   C   s   t  s
td dS |du rt }t| }|jD ]?}d|jvr q|jd j}t|t	r<t|d t
r8|d f}n|d }d}t|tjrH|jj}t||ddddd}||jd< q|r^t| ti |}t| |j  t||dtjjd dS )z$
    Draw a graph in fname.svg.
    z*draw_buffers() requires `graphviz` packageNfusion_metar   Ztensor_metaF)
clear_metadot_graph_shape)r(   logwarningr	   create_fx_from_snodesr)   metagroup
isinstancetupleintr   ZComputedBufferdatadtyper   printr   r   graphZlintr   r   tracer,   )	r)   Zprint_graphfnamer8   noder1   r6   metadatagmr&   r&   r'   draw_buffers7   s6   






r>   snodesc              
      s8  dd }t dg d}i }tj }d}g }d}| D ]}| r&d}	|	}n-| r/d}	|	}n$t|tr9d}	|	}nt|t	rDd	}	|j
}nt|trOd
}	|j
}ntdtjj| d}
|	 d|
 }||}i }t|drud| i}|j|d|d} fdd  |r|| | }||_||||	|jd< t|tr|jD ]}||| < q|||< |du r|}q| D ]J}| }|jj}|| }g }|D ]2}|j|v r||j }n || ||j}|||j< W d   n1 sw   Y  || qt||_q|t |dkr|d  |S t| |S )B
    Creates a FX Graph from a list of SchedulerNode objects.
    c                 S   s   dd }| |_ |S )Nc                  W   s   dS Nr   r&   )argsr&   r&   r'   func1g      z;create_fx_from_snodes.<locals>.get_fake_func.<locals>.func1)__name__)r   rC   r&   r&   r'   get_fake_funcf   s   z,create_fx_from_snodes.<locals>.get_fake_func
FusionMeta)r1   snodetypeNZexterntemplateZnopZcomputeZfusedzUnknown node typeZoriginal_atenz: 
get_devicedevicer&   rB   kwargsc                    s6   t | trt fdd| jD S tdd | jD S )Nc                 3   s    | ]} |V  qd S Nr&   ).0x	in_outputr&   r'   	<genexpr>   s    z;create_fx_from_snodes.<locals>.in_output.<locals>.<genexpr>c                 s   s    | ]	}t |jtV  qd S rO   )r2   r;   r   )rP   userr&   r&   r'   rT      s    )r2   r   anyr?   Zusers)rH   rR   r&   r'   rS      s   
z(create_fx_from_snodes.<locals>.in_outputr*   r   r   )!collections
namedtupletorchr
   GraphZ	is_externZis_templater2   r   r   r1   r   RuntimeErrorZ	_inductorutilsZget_fused_kernel_name	get_nodeshasattrrK   call_functionappendget_namer   r0   r?   Zread_writesZreadsZinserting_beforeplaceholderr3   rB   outputlen)r?   rF   rG   Zbuf_to_fx_noder8   Z
first_nodeZoutputsr1   rH   Z	node_typeZ
fused_name	func_nameZ	node_funcrN   Zfx_noder   rQ   depsnew_argsdepZdep_noder&   rR   r'   r/   a   s   









r/   node_name_to_buf_nameparent_buf_name	n_originsc           
      C   s   | d u rd S | D ]S}|  }| }|d ur)t|dkr)t|||d u r%|n| qt|dkr5|d |ks7J |j}|d u sC|jd u rDq|jD ]}|j}	|	|vrZ|d u rV|n|||	< qGqd S )Nr   r   )ra   r]   rd   $update_orig_fx_node_name_to_buf_namer;   Zoriginsr   )
r)   ri   rj   rk   r;   buf_nameZchildren_nodesZir_nodeorigin	node_namer&   r&   r'   rl      s0   
rl   c                 C   sl   i }|   D ]\}}||vr|h||< q|| | qi }|   D ]\}}t|| }t||||< q"|S rO   )itemsaddrd   r   )ri   Zbuf_name_to_n_nodero   rm   node_name_to_buf_metaZn_noder&   r&   r'   get_node_name_to_buf_meta   s   rs   r=   c                 C   sP   i }t || |du rdS t|}| jjD ]}|j|v r%||j|jd< qdS )r@   NZbuf_meta)rl   rs   r8   r)   r   getr0   )r=   r?   ri   rr   r;   r&   r&   r'   annotate_orig_fx_with_snodes   s   

ru   c               	   c   s   t jdddk} dd l}t|jjj}t	
 }| s,z
d V  W |  d S |  w |tdd t jt d}t j|sGt | tt j|dt  d	}|tj |td
 || zd V  W || |  d S || |  w )NZTORCH_COMPILE_DEBUG01r   z*functorch.compile.config.debug_partitionerTtorchinductorZaot_z
_debug.log3[%(filename)s:%(lineno)d %(levelname)s] %(message)s)osenvironrt   Ztorch._functorch.aot_autogradlogging	getLoggerZ
_functorchZaot_autogradrE   
contextlib	ExitStackcloseenter_contextr   pathjoinr   existsmakedirsFileHandlerr   setLevelDEBUGsetFormatter	Formatter
addHandlerremoveHandler)Zcompile_debugrY   r-   stackr   fhr&   r&   r'   enable_aot_logging   s@   





r   c                   @   s   e Zd Ze Zedd Zedede	e fddZ
dd Zd	efd
dZdefddZdefddZdd Zdd ZdedefddZdd Zdd Zdd ZdS ) DebugContextc                    s"   t   fdd}t|ddS )Nc                     s8   t    | i |W  d    S 1 sw   Y  d S rO   )r   rM   fnr&   r'   inner.  s   $z DebugContext.wrap.<locals>.innerinductor)Zcompiler_name)	functoolswrapsr   )r   r   r&   r   r'   wrap,  s   zDebugContext.wrapfolder_namer   c                 C   sV   t jjpt }tjD ]}tj|d|  d| }tj	|s(t
| |  S q
d S )Nrx   .)r   r9   	debug_dirr   r   _counterrz   r   r   r   r   )r   r   ndirnamer&   r&   r'   create_debug_dir5  s   

zDebugContext.create_debug_dirc                 C   s   d | _ d | _t | _d S rO   )_prof_pathr~   r   _stack)selfr&   r&   r'   __init__C  s   zDebugContext.__init__new_pathc                 C   sr   | j sd S |dsJ |tj|rt| zt| j | || _ W d S  ty8   t	
d| j | Y d S w )Nz.debugz(Failed to copy debug files from %s to %s)r   endswithrz   r   r   shutilrmtreecopytreeOSErrorr-   r.   )r   r   r&   r&   r'   copyH  s   
zDebugContext.copyfilenamec                 C   s    | j sJ ttj| j |dS )Nw)r   openrz   r   r   r   r   r&   r&   r'   fopenW  s   
zDebugContext.fopensuffixc                 C   s   | j sJ tj| j |S rO   )r   rz   r   r   )r   r   r&   r&   r'   r   [  s   
zDebugContext.filenamec                 C   s   t jjd urJdd l}| jsJ tj| jtj| j d}|	|d}|j
| jtj| jd W d    n1 s=w   Y  t j| d S d S )Nr   z.tar.gzzw:gz)arcname)r   r9   
upload_tartarfiler   rz   r   r   basenamer   rq   )r   r   Ztar_filetarr&   r&   r'   r   _  s   
zDebugContext.upload_tarc                    s   t jrtd  j} tj  fdd}| j|| | j	t
|  t jjs-d S | t | _t jjr?| dtj t jjrJ| dtj t jjrZt | _| j  d S d S )Nztorch._dynamoc                    s     |  d S rO   )r   )levelr-   r&   r'   reset_log_levelq  s   z/DebugContext.__enter__.<locals>.reset_log_levelz	debug.logzinfo.log)r   debugr|   r}   r   r   r   r   callbackr   r   Zset_debug_handlerr9   enabledr   r   r   	debug_log_setup_log_captureZinfo_logINFOZcompile_profilecProfileZProfiler   enable)r   Z
prev_levelr   r&   r   r'   	__enter__k  s$   

zDebugContext.__enter__r   c                 C   sp   t d}| j| |}t |}|| |t d |	| |t
|j| | j|j| d S )Nztorch._inductorry   )r|   r}   r   r   r   StreamHandlerr   r   r   r   minr   r   r   )r   r   r   r-   fdchr&   r&   r'   r     s   



zDebugContext._setup_log_capturec                 C   sF   | j r| j   |   | jr|   tdt | j | j	  d S )Nz%s debug trace: %s)
r   disable_save_profile_datar   r   r-   r.   r	   r   r   )r   exc_typeexc_valexc_tbr&   r&   r'   __exit__  s   
zDebugContext.__exit__c                 C   s   | j sJ | j | d | d)}tj| j |d}|  |d |d |d |d W d    d S 1 s?w   Y  d S )Nzcompile.profzcompile.stats)streamZcumtimed   Ztottime)	r   Z
dump_statsr   r   pstatsZStatsZ
strip_dirsZ
sort_statsZprint_stats)r   r   statsr&   r&   r'   r     s   



"zDebugContext._save_profile_datac                 C   sT   t jjr$tt j|r$ztt| |W S  ty#   tjddd Y d S w dd }|S )Nz Ignoring exception in debug codeT)exc_infoc                  _   s   d S rO   r&   rM   r&   r&   r'   ignored  rD   z)DebugContext.__getattr__.<locals>.ignored)r   r9   r   getattrDebugFormatter	Exceptionr-   r.   )r   r   r   r&   r&   r'   __getattr__  s   zDebugContext.__getattr__N)rE   
__module____qualname__	itertoolscountr   staticmethodr   strr   r   r   r   r   r   r   r   r4   r   r   r   r   r&   r&   r&   r'   r   )  s     

r   c                   @   s   e Zd Zdd Zdejjdeej fddZ	dejjdeej fddZ
d	efd
dZd	efddZded	efddZd	efddZdejjd	efddZdd ZdS )r   c                 C   s   |j | _ |j| _|| _d S rO   )r   r   handler)r   r   r&   r&   r'   r     s   
zDebugFormatter.__init__r=   inputsc                 C   sz   |  d}t|||d W d    n1 sw   Y  |  d}||jdd W d    d S 1 s6w   Y  d S )Nzfx_graph_runnable.pyr   zfx_graph_readable.pyFZprint_output)r   r   writeprint_readabler   r=   r   r   r&   r&   r'   fx_graph  s   "zDebugFormatter.fx_graphc                 C   sB   |  d}||jdd W d    d S 1 sw   Y  d S )Nzfx_graph_transformed.pyFr   )r   r   r   r   r&   r&   r'   fx_graph_transformed  s   "z#DebugFormatter.fx_graph_transformedr)   c                 C      |  d| d S )Nzir_pre_fusion.txt	_write_irr   r)   r&   r&   r'   ir_pre_fusion     zDebugFormatter.ir_pre_fusionc                 C   r   )Nzir_post_fusion.txtr   r   r&   r&   r'   ir_post_fusion  r   zDebugFormatter.ir_post_fusionr   c                 C   s`   |  |!}td|j |D ]}||  |d qW d    d S 1 s)w   Y  d S )NzWriting debug ir to  %sz


)r   r-   infor   r   Z	debug_str)r   r   r)   r   r;   r&   r&   r'   r     s   "zDebugFormatter._write_irc                 C   s   t || dd d S )Nzgraph_diagram.svg)r:   )r>   r   r   r&   r&   r'   graph_diagram     zDebugFormatter.graph_diagramc                 C   s,   t || t|| ddtdtjjd d S )Nzorig_fx_graph_diagram.svgFT)r:   r+   progZparse_stack_tracer,   )ru   r   r   GRAPHVIZ_COMMAND_SCALABLEr   r9   r,   )r   r=   r)   r&   r&   r'   draw_orig_fx_graph  s   

z!DebugFormatter.draw_orig_fx_graphc                 C   s   t || d d S )Nzoutput_code.py)r   r   r   r   r&   r&   r'   output_code  r   zDebugFormatter.output_codeN)rE   r   r   r   rY   r
   r   r   Tensorr   r   SchedulerNodeListr   r   r   r   r   r   r   r&   r&   r&   r'   r     s    
r   c                   @   s    e Zd ZU eed< ejed< dS )TensorMetadataHoldertensor_metadatarL   N)rE   r   r   r   __annotations__rY   rL   r&   r&   r&   r'   r     s   
 r   c            
      O   s   d}t j|st | dd }t|| |f\}}d}| d| dtt d}t|d}t	||f| W d	   n1 sAw   Y  t
tjr[d
| d|d}	t|	 d	S d	S )z
    This function is used to save arguments for a compile_fx_inner function call
    to the file system.  Later on one can replay the compile_fx_inner call
    with the saved arguments using load_args_and_run_compile_fx_inner.
    z/tmp/inductor_saved_argsc                 S   s    t | tjrtt| | jS | S )z
        Pickle FakeTensor will result in error:
        AttributeError: Can't pickle local object 'WeakValueDictionary.__init__.<locals>.remove'

        Convert all Tensor to metadata. This may also makes pickle faster.
        )r2   rY   r   r   r   rL   rQ   r&   r&   r'   handle_tensor  s   z5save_args_for_compile_fx_inner.<locals>.handle_tensorcompile_fx_inner/_z.pklwbNz3
Arguments for a compile_fx_inner call is saved to z. To replay the call,
run the following:

from torch._inductor.debug import load_args_and_run_compile_fx_inner
load_args_and_run_compile_fx_inner(z
)
        )rz   r   r   mkdirr   nextsave_args_cntr   pickledumpr-   isEnabledForr|   r   r7   )
rB   rN   folderr   Zargs_to_saveZkwargs_to_savefn_namer   fmessager&   r&   r'   save_args_for_compile_fx_inner  s$   
r  r   c              	   C   s   ddl m} t| d}t|\}}W d    n1 sw   Y  dd }tjjdd}|6 t	dd	 t
|||f\}}||i |W  d    W  d    S 1 sXw   Y  W d    d S 1 shw   Y  d S )
Nr   )r   rbc                 S   s0   t | trtjj| jj| jj| jj	| j
S | S rO   )r2   r   rY   Z_dynamotestingZrand_stridedr   shapeZstrider6   rL   r   r&   r&   r'   r   #  s   
z9load_args_and_run_compile_fx_inner.<locals>.handle_tensorT)Zallow_non_fake_inputsZ	save_argsF)Ztorch._inductor.compile_fxr   r   r   loadrY   Z_subclassesZFakeTensorModer   r   r   )r   r   r  rB   rN   r   Z	fake_moder&   r&   r'   "load_args_and_run_compile_fx_inner  s   Rr  )FNrA   )OrW   r~   r   dataclassesr   r   r|   rz   Zos.pathr   r   r   r"   typingr   r   r   r   Zunittest.mockr   Zfunctorch.compiler   r   r	   rY   r
   Ztorch._dynamo.repro.after_aotr   r   Ztorch._dynamo.utilsr   Ztorch.fx.graph_moduler   Ztorch.fx.passes.shape_propr   r   Ztorch.fx.passes.tools_commonr   Ztorch.utils._pytreer    r   r   Z	schedulerr   r   r   r   r   Zvirtualizedr   r}   rE   r-   r   rX   r   r   	lru_cacheboolr(   r>   rZ   r/   r   r4   rl   rs   ru   contextmanagerr   r   r   	dataclassr   r   r   r  r  r&   r&   r&   r'   <module>   s    
*_

#

) 2.