o
    h7                     @   s  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 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-m.Z. ddl/m0Z0 e1e2Z3e4ddd Z5d%ddZ6dee* dej7fddZ8ej9dd Z:G dd dZ;ee Z<G dd dZ=ej>G dd  d Z?e@ ZAd!d" ZBd#d$ ZCdS )&    N)AnyList)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)Vc                   C   s2   zt jddgt jd W dS  t jy   Y dS w )Nwhichdot)stderrTF)
subprocesscheck_outputPIPESubprocessError r!   r!   K/var/www/html/ai/venv/lib/python3.10/site-packages/torch/_inductor/debug.pyhas_dot*   s   r#   Fc           	   	   C   s   t  s
td dS |du rt }t| }|jD ]2}d|jvr q|jd j}t|t	r/|d }d}t|t
jr;|jj}t||ddddd}||jd< q|rQt| ti |}t| |j  t||dd dS )zR
    Draw a graph in fname.svg.
    nodes is a list of SchedulerNode objects.
    z*draw_buffers() requires `graphviz` packageNfusion_metar   tensor_metaF)
clear_meta)r#   logwarningr   create_fx_from_snodesnodesmetagroup
isinstancetupler   ComputedBufferdatadtyper   printr   r   graphlintr   )	r*   print_graphfnamer3   noder,   r1   metadatagmr!   r!   r"   draw_buffers3   s.   





r:   snodesreturnc              
      s  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|
 }||}|j|d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 )zB
    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"   func1_      z;create_fx_from_snodes.<locals>.get_fake_func.<locals>.func1)__name__)namer>   r!   r!   r"   get_fake_func^   s   z,create_fx_from_snodes.<locals>.get_fake_func
FusionMeta)r,   snodetypeNexterntemplatenopcomputefusedzUnknown node typeoriginal_atenz: r!   r=   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 rN   )r-   r7   r   )rO   userr!   r!   r"   rS      s    )r-   r   anyr;   users)rD   rQ   r!   r"   rR      s   
z(create_fx_from_snodes.<locals>.in_outputr$   r   r   )collections
namedtupletorchr   Graph	is_externis_templater-   r   r   r,   r   RuntimeError	_inductorutilsget_fused_kernel_name	get_nodescall_functionappendget_namerA   r+   r;   read_writesreadsinserting_beforeplaceholderr.   r=   outputlen)r;   rB   rC   buf_to_fx_noder3   
first_nodeoutputsr,   rD   	node_type
fused_name	func_name	node_funcfx_noderA   rP   depsnew_argsdepdep_noder!   rQ   r"   r)   Y   sz   








r)   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 )NTORCH_COMPILE_DEBUG01r   z*functorch.compile.config.debug_partitionerTtorchinductoraot_z
_debug.log3[%(filename)s:%(lineno)d %(levelname)s] %(message)s)osenvirongettorch._functorch.aot_autogradlogging	getLogger
_functorchaot_autogradr@   
contextlib	ExitStackcloseenter_contextr   pathjoinr   existsmakedirsFileHandlerr   setLevelDEBUGsetFormatter	Formatter
addHandlerremoveHandler)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d Zdd Z	de
f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S )DebugContextc                    s"   t   fdd}t|ddS )Nc                     s8   t    | i |W  d    S 1 sw   Y  d S rN   )r   rL   fnr!   r"   inner   s   $z DebugContext.wrap.<locals>.innerinductor)compiler_name)	functoolswrapsr
   )r   r   r!   r   r"   wrap   s   zDebugContext.wrapc                 C   sJ   t jD ]}tjt d|  d| }tj|s"t| |  S qd S )Nrz   .)r   _counterr}   r   r   r   r   r   )folder_namendirnamer!   r!   r"   create_debug_dir   s   

zDebugContext.create_debug_dirc                 C   s   d | _ d | _t | _d S rN   )_prof_pathr   r   _stack)selfr!   r!   r"   __init__   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   endswithr}   r   r   shutilrmtreecopytreeOSErrorr'   r(   )r   r   r!   r!   r"   copy   s   
zDebugContext.copyc                 C   s    | j sJ ttj| j |dS )Nw)r   openr}   r   r   r   filenamer!   r!   r"   fopen  s   
zDebugContext.fopenc                 C   s   t j| j|S rN   )r}   r   r   r   )r   suffixr!   r!   r"   r        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   trace
upload_tartarfiler   r}   r   r   basenamer   add)r   r   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 rN   )r   )levelr'   r!   r"   reset_log_level!  s   z/DebugContext.__enter__.<locals>.reset_log_levelz	debug.logzinfo.log)r   debugr   r   r   r   r   r   callbackr   r   set_debug_handlerr   enabledr   r   r   	debug_log_setup_log_captureinfo_logINFOcompile_profilecProfileProfiler   enable)r   
prev_levelr   r!   r   r"   	__enter__  s$   

zDebugContext.__enter__c                 C   sp   t d}| j| |}t |}|| |t d |	| |t
|j| | j|j| d S )Nztorch._inductorr|   )r   r   r   r   r   StreamHandlerr   r   r   r   minr   r   r   )r   r   r   r'   fdchr!   r!   r"   r   5  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__A  s   
zDebugContext.__exit__c                 C   s   | 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)streamcumtimed   tottime)	r   
dump_statsr   r   pstatsStats
strip_dirs
sort_statsprint_stats)r   r   statsr!   r!   r"   r   K  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 rN   r!   rL   r!   r!   r"   ignored]  r?   z)DebugContext.__getattr__.<locals>.ignored)r   r   r   getattrDebugFormatter	Exceptionr'   r(   )r   rA   r   r!   r!   r"   __getattr__U  s   zDebugContext.__getattr__N)r@   
__module____qualname__	itertoolscountr   staticmethodr   r   r   strr   r   r   r   r   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d ZdS )r   c                 C   s   |j | _ |j| _|| _d S rN   )r   r   handler)r   r   r!   r!   r"   r   g  s   
zDebugFormatter.__init__r9   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print_output)r   r	   writeprint_readabler   r9   r   r   r!   r!   r"   fx_graphl  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_transformeds  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_fusiony  r   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   sR   |  |}|D ]}||  |d qW d    d S 1 s"w   Y  d S )Nz


)r   r   	debug_str)r   r   r*   r   r7   r!   r!   r"   r     s   "zDebugFormatter._write_irc                 C   s   t || dd d S )Nzgraph_diagram.svg)r6   )r:   r   r   r!   r!   r"   graph_diagram     zDebugFormatter.graph_diagramc                 C   s   t || d d S )Nzoutput_code.py)r   r   r   r   r!   r!   r"   output_code  r  zDebugFormatter.output_codeN)r@   r   r   r   rY   r   r   r   Tensorr   r   SchedulerNodeListr  r  r   r   r  r  r!   r!   r!   r"   r   f  s    
r   c                   @   s    e Zd ZU eed< ejed< dS )TensorMetadataHoldertensor_metadatadeviceN)r@   r   r   r   __annotations__rY   r  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.
        )r-   rY   r  r	  r   r  rP   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
)
        )r}   r   r   mkdirr   nextsave_args_cntr   pickledumpr'   isEnabledForr   r   r2   )
r=   rM   folderr  args_to_savekwargs_to_savefn_namer   fmessager!   r!   r"   save_args_for_compile_fx_inner  s$   
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 rN   )r-   r	  rY   _dynamotestingrand_stridedr
  shapestrider1   r  r  r!   r!   r"   r    s   
z9load_args_and_run_compile_fx_inner.<locals>.handle_tensorT)allow_non_fake_inputs	save_argsF)torch._inductor.compile_fxr  r   r  loadrY   _subclassesFakeTensorModer   r   r   )r   r  r  r=   rM   r  	fake_moder!   r!   r"   "load_args_and_run_compile_fx_inner  s   Rr-  )FN)DrW   r   r   dataclassesr   r   r   r}   os.pathr  r   r   r   typingr   r   unittest.mockr   functorch.compiler   r   r   rY   r   torch._dynamo.repro.after_aotr	   r
   torch._dynamo.utilsr   torch.fx.graph_moduler   torch.fx.passes.shape_propr   r   torch.fx.passes.tools_commonr   torch.utils._pytreer    r   r   	schedulerr   r   r   r   r   virtualizedr   r   r@   r'   	lru_cacher#   r:   rZ   r)   contextmanagerr   r   r  r   	dataclassr	  r   r  r  r-  r!   r!   r!   r"   <module>   sV    


&Y
) &.