a
    d;                     @   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 d dlmZmZmZmZmZ d dlmZ d dlZd dlZd dlmZmZ ddlmZmZ ddlm Z  e!e"Z#eej$ej$f Z%zd d	l&m'Z' W n e(y   d
d Z'Y n0 e)ddd Z*e)ddd Z+dd Z,dd Z-dd Z.dd Z/e0e0dddZ1eee0ej2f  eej$ dddZ3eee0ej$f  eee0ej2f  dddZ4d d! Z5d"d# Z6dcd$d%Z7ddd)d*Z8d+d, e_9d-d, e_9d.d/ Z:ee;d0d1d2Z<eee; d3d4d5Z=d6d7 Z>d8d9 Z?d:d; Z@d<d= ZAej$d>d?d@ZBdAdB ZCej$eeef dCdDdEZDej$e;dFdGdHZEdIdJ ZFe GdKdLdMgZHejIdedNdOZJdPdQ ZKe)dRdSdT ZLG dUdV dVZMG dWdX dXZNe)ddYdZ ZOd[d\ ZPG d]d^ d^ZQd_d` ZRdadb ZSdS )f    N)StringIO)AnyDictListOptionalUnion)mock)immutable_dictimmutable_list   )configr   )get_device_capability)do_benchc                  O   s   t dd S )Nzrequires TritonNotImplementedError)argskwargs r   ^/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/torch/_inductor/utils.pyr   #   s    r   c                  C   sD   t j sdS zdd l} | d uo(t dkW S  ty>   Y dS 0 d S )NFr   )   r   )torchcudais_availabletritonr   ImportError)r   r   r   r   
has_triton'   s    
r   c                  C   sD   z*ddl m}  | d uo(tttjdd dW S  ty>   Y dS 0 d S )Nr   	roi_alignZtorchvisionr   F)Ztorchvision.opsr   hasattrgetattrr   opsr   r   r   r   r   has_torchvision_roi_align3   s    
r!   c                  G   s   t tjdd | D S )Nc                 S   s   g | ]}|r|qS r   r   .0xr   r   r   
<listcomp>@       z'conditional_product.<locals>.<listcomp>)	functoolsreduceoperatormulr   r   r   r   conditional_product?   s    r,   c                 C   s   t tj| tdS )Nr   )r'   r(   r)   r*   sympyIntegeritr   r   r   sympy_productC   s    r1   c                 C   s2   t | t |ksJ ttdd t| |D S )Nc                 s   s   | ]\}}|| V  qd S Nr   )r#   abr   r   r   	<genexpr>I   r&   zsympy_dot.<locals>.<genexpr>)lenr-   expandsumzip)Zseq1Zseq2r   r   r   	sympy_dotG   s    r:   c                 C   s   dd | D   S )Nc                 S   s   i | ]}t ||qS r   )idr"   r   r   r   
<dictcomp>M   r&   zunique.<locals>.<dictcomp>)valuesr/   r   r   r   uniqueL   s    r>   ZnumerZdenomc                 C   s$   t | trt |tsJ | |   S r2   )
isinstanceintr?   r   r   r   ceildivP   s    rB   )lstreturnc                 C   s   dd | D S )z
    Gets the shape and stride of a tensor. For non-symbolic tensors, this is
    trivial. But for symbolic tensors, we need to map from SymIntNode into
    sympy.Expr.
    c                 S   s*   g | ]"}t |tjr|jjnt|qS r   )r@   r   SymIntnodeexprr-   r.   r#   ir   r   r   r%   [   s   z-convert_shape_to_inductor.<locals>.<listcomp>r   rC   r   r   r   convert_shape_to_inductorU   s    rK   c                    s   ddl m   fdd| D S )zz
    Takes a list of shapes from Inductor and converts them into symints (or just
    ints if all shapes are static).
    r   Vc                    sB   g | ]:}t |tr|n&t |tjr*t|n jjjj|d dqS )N)hint)r@   rA   r-   r.   graphZsizevarsZ	shape_envZcreate_symintnoderH   rL   r   r   r%   i   s   

z+convert_shape_to_symint.<locals>.<listcomp>)ZvirtualizedrM   rJ   r   rL   r   convert_shape_to_symint`   s    
rP   c           
      C   s   t j }g }g }t|D ]@\}}t|t jrP||d|  || q|| qtdd |	 D svJ |
| t||}t| jjdkrt| jjd jdkr|f}|| t ji |}	|	|fS )Nargc                 s   s   | ]}t |tj V  qd S r2   )r@   r   Tensorr"   r   r   r   r5   }   r&   z$gen_gm_and_inputs.<locals>.<genexpr>r   r   rR   )r   ZfxZGraph	enumerater@   rR   appendplaceholderallr=   call_functiontupler6   Z_schemareturnsstrtypeoutputZGraphModule)
targetr   r   gZg_argsZa_argsnrQ   rF   gmr   r   r   gen_gm_and_inputss   s$    

ra   c                   C   s   t j rt j  d S r2   )r   r   r   synchronizer   r   r   r   rb      s    
rb   c                 C   sP   t   td t }t|D ]}| | }t   q t }|d usHJ || S )Ni9  )rb   r   Zmanual_seedtimeperf_counterrange)modelZexample_inputstimest0_resultt1r   r   r   timed   s    
rl   r   
         ?c                    s>   t  fddt|D }t |}t|| d |S )Nc                    s   g | ]}t  qS r   )rl   )r#   ri   r   fnrg   r   r   r%      r&   z%print_performance.<locals>.<listcomp>z.6f)r   Ztensorre   Zmedianprint)rp   r   rg   repeatZbaselineZtimingsZtookr   ro   r   print_performance   s     
rs   c                 C   s   t t|  S r2   )hashrX   itemsselfr   r   r   <lambda>   r&   rx   c                 C   s   t t| S r2   )rt   rX   rv   r   r   r   rx      r&   c                    s,   dd t   fdd} j|_|S )zB
    Useful for wrapping lists in tuples for caching purposes
    c                 S   s:   t | ttfr| S t | tr$t| S t | tr6t| S | S r2   )r@   r	   r
   listdict)r$   r   r   r   freeze_value   s    

z#freeze_inputs.<locals>.freeze_valuec                     s   fdd| D }  |  S )Nc                    s   g | ]} |qS r   r   r"   )r{   r   r   r%      r&   z2freeze_inputs.<locals>.wrapped.<locals>.<listcomp>r   r+   fr{   r   r   wrapped   s    zfreeze_inputs.<locals>.wrapped)r'   wraps
cache_info)r}   r~   r   r|   r   freeze_inputs   s
    	r   objmethodc                    s$   t | |  t| | fdd dS )zKReplace obj.method() with a new method that returns a precomputed constant.c                      s    S r2   r   r   rj   r   r   rx      r&   z#precompute_method.<locals>.<lambda>N)r   setattrr   r   r   r   precompute_method   s    r   )r   methodsc                 C   s   |D ]}t | | qdS )zFReplace methods with new methods that returns a precomputed constants.N)r   )r   r   r   r   r   r   precompute_methods   s    r   c                 C   s   t | |kt | |k  S r2   )rA   )r3   r4   r   r   r   cmp   s    r   c                    s*   d j  dt  fdd}|S )N___cachec                    s$   t | st|  |  t| S r2   )r   r   r   rv   rp   keyr   r   wrapper   s    
zcache_on_self.<locals>.wrapper)__name__r'   r   )rp   r   r   r   r   cache_on_self   s    r   c              
   C   s<   d dgtdd ttjdd | D D dtj  S )Nri   Zfusedc                 S   s    g | ]}|j d krt|jqS )rW   )oprZ   name)r#   originr   r   r   r%      s   
z)get_fused_kernel_name.<locals>.<listcomp>c                 S   s   g | ]}t |d r|jjqS )rF   )r   rF   origins)r#   rF   r   r   r   r%      s   
r   )joinsortedr'   r(   r)   or_r   Zkernel_name_max_ops)Znode_scheduler   r   r   get_fused_kernel_name   s     r   c                    sf   dd l }ddlm m  fddfdd| D }fdd| D }t|jg ||R  S )	Nr   r   ComputedBufferIRNodec                    s   t | ot |   S r2   )r@   )r_   r   r   r   is_unrealized_node   s    z*gather_origins.<locals>.is_unrealized_nodec                    s   g | ]} |r|j qS r   r   )r#   valr   r   r   r%      r&   z"gather_origins.<locals>.<listcomp>c                    s   g | ]} |r|j qS r   r   )r#   rQ   r   r   r   r%      r&   )	itertoolsirr   r   r=   setchain)r   r   r   Zkwarg_originsZarg_originsr   )r   r   r   r   gather_origins   s    r   )rG   c                 C   s   t | tjr| jS t | tjr0dtt| jS t | tj	rNdtt| jS ddl
m}m}m} t | |||fr| jj ddtt| j dS t| S )z
    Normal sympy str is very slow, this is a lot faster.  The result are
    somewhat worse, as it doesn't do as much simplification.  So don't
    use this for final codegen.
    z + z * r   )CleanDivFloorDivModularIndexing(, ))r@   r-   Symbolr   Addr   map	sympy_strr   ZMulr   r   r   r   funcr   rZ   )rG   r   r   r   r   r   r   r      s    "r   c                 C   s    | d dksJ t j| dddS )Nr   sT)integerZpositive)r-   r   )r   r   r   r   sympy_symbol  s    r   rG   replacementsc                    s$   dd  |   fdd| D S )z=
    xreplace is faster than subs, but is way more picky
    c                 S   s   t | trt| S | S r2   )r@   rZ   r   )r   r   r   r   promote_strings  s    
z#sympy_subs.<locals>.promote_stringsc                    s   i | ]\}} | |qS r   r   )r#   kvr   r   r   r<   !  r&   zsympy_subs.<locals>.<dictcomp>)Zxreplaceru   r   r   r   r   
sympy_subs  s    r   indexprefixc                    s   t  fdd| jD S )Nc                 3   s   | ]}|j  V  qd S r2   )r   
startswith)r#   r   r   r   r   r5   &  r&   z)free_symbol_startswith.<locals>.<genexpr>)anyZfree_symbolsr   r   r   r   free_symbol_startswith%  s    r   c                 C   s.   h d}| j jD ]}t|j|v r dS qdS )N>   zfbgemm.dense_to_jagged.defaultz7aten._fused_moving_avg_obs_fq_helper_functional.defaultz,aten._fused_moving_avg_obs_fq_helper.defaultz%fbgemm.jagged_to_padded_dense.defaultTF)rO   nodesrZ   r]   )r`   Zforbidden_listrF   r   r   r   has_incompatible_cudagraph_ops)  s
    r   instance_descriptorZdivisible_by_16Z
equal_to_1c              
   #   s   t  }tjtjd|i tj|d tjtjd ib dV  t	| trt
| dkshJ dtj rt }|  fdd|D  W d   n1 s0    Y  W d   n1 s0    Y  W d   n1 s0    Y  dS )	z
    Contextmanager that provides a clean tmp cachedir for inductor.

    Optionally, pass a dict as 'cache_entries' to get a list of filenames and sizes
    generated with this cache instance.
    ZTORCHINDUCTOR_CACHE_DIRr   ZTRITON_CACHE_DIRNr   z!expected empty cache_entries dictc              	      s,   i | ]$}d |vr|t jt j |qS )z.lock)ospathgetsizer   )r#   r}   Ztriton_cache_dirr   r   r<   O  s   z(fresh_inductor_cache.<locals>.<dictcomp>)tempfileTemporaryDirectoryr   patchrz   r   environr   r   r@   r6   existslistdirupdate)Zcache_entriesZinductor_cache_dirfilesr   r   r   fresh_inductor_cache;  s     




r   c                 C   s(   | j }tt| }ttt||ddS )NT)r   reverse)__getitem__re   r6   ry   reversedr   )seqgetterZa_rr   r   r   argsortW  s    r      c                 C   s   t jd| d S )Nr   dtype)r   emptyZelement_sizer   r   r   r   get_dtype_size^  s    r   c                   @   sf   e Zd ZdZd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dZdddZdS )IndentedBuffer   r   c                 C   s   g | _ || _d S r2   )_lines_indent)rw   initial_indentr   r   r   __init__f  s    zIndentedBuffer.__init__c                 C   sV   t  }| jD ]@}t|tr*| }|d u r*qt|ts8J || |d q| S )N
)r   r   r@   DeferredLineBaserZ   writegetvaluerw   bufliner   r   r   r   j  s    


zIndentedBuffer.getvaluec                 C   st   t  }| jD ]^}t|tr*| }|d u r*qt|ts8J |drV||d d  q|| |d q| S )N\r   )r   r   r@   r   rZ   endswithr   r   r   r   r   r   getrawvaluex  s    



zIndentedBuffer.getrawvaluec                 C   s   | j   d S r2   )r   clearrv   r   r   r   r     s    zIndentedBuffer.clearc                 C   s
   t | jS r2   )boolr   rv   r   r   r   __bool__  s    zIndentedBuffer.__bool__c                 C   s   d| j | j  S )N )r   tabwidthrv   r   r   r   r     s    zIndentedBuffer.prefixc                 C   sT   t |tr"| j||   n.| rD| j|   |  n| jd d S N )r@   r   r   rT   with_prefixr   striprw   r   r   r   r   	writeline  s
    
zIndentedBuffer.writelinec                 C   s   |D ]}|  | qd S r2   )r   )rw   linesr   r   r   r   
writelines  s    zIndentedBuffer.writelinesr   c                    s   t j fdd}| S )Nc                   3   s&    j  7  _ d V   j  8  _ d S r2   )r   r   offsetrw   r   r   ctx  s    z"IndentedBuffer.indent.<locals>.ctx)
contextlibcontextmanager)rw   r   r   r   r   r   indent  s    zIndentedBuffer.indentFc                 C   s   t |trltd}|jD ]"}|rt|t|t|  }qt|rJd}|jD ]}t	| ||d   qPn@t
|}|r| }|sd S | }|dD ]}| 	| qd S )Ninfr   r   )r@   r   floatr   minr6   lstripmathisinfr   textwrapdedentrstripsplit)rw   Z
other_coder   r  r   r   r   r   splice  s"    




zIndentedBuffer.spliceN)r   )r   )F)r   
__module____qualname__r   r   r   r   r   r   r   r   r   r   r  r   r   r   r   r   c  s   

	r   c                   @   sb   e Zd ZdZdd Zee dddZed ddd	Zd
d Z	dd Z
dd Zdd Zdd ZdS )r   z.A line that can be 'unwritten' at a later timec                 C   s   |  sd}|| _d S r   )r   r   r   r   r   r   r     s    zDeferredLineBase.__init__)rD   c                 C   s
   t  dS )zJReturns either self.line or None to indicate the line has been 'unwritten'Nr   rv   r   r   r   __call__  s    zDeferredLineBase.__call__)r   rD   c                 C   s
   t  dS )z3Returns a new deferred line with the same conditionNr   r   r   r   r   	_new_line  s    zDeferredLineBase._new_linec                 C   s   |  | | j S r2   r  r   )rw   r   r   r   r   r     s    zDeferredLineBase.with_prefixc                 C   s   |  | j S r2   )r  r   r  rv   r   r   r   r    s    zDeferredLineBase.lstripc                 C   s   |  | j| S r2   r  )rw   r   r   r   r   r     s    zDeferredLineBase.__getitem__c                 C   s
   t | jS r2   )r   r   rv   r   r   r   r     s    zDeferredLineBase.__bool__c                 C   s
   t | jS r2   )r6   r   rv   r   r   r   __len__  s    zDeferredLineBase.__len__N)r   r  r  __doc__r   r   rZ   r  r  r   r  r   r   r  r   r   r   r   r     s   r   c                 C   s(   t j| j}|dk r$td dS dS )NP   z.not enough cuda cores to use max_autotune modeFT)r   r   Zget_device_propertiesZmulti_processor_countlogwarning)r   Zcoresr   r   r   
is_big_gpu  s
    
r  c                 C   s8   t jo6| jjdko6| jtjtjtjfv o6t	| jj
p4dS )Nr   r   )inductor_configZmax_autotuneZdevicer[   r   r   float16Zbfloat16float32r  r   )Zlayoutr   r   r   use_triton_template  s    
r  c                   @   s.   e Zd ZedZdd Zdd Zdd ZdS )	DebugDirManagerr   c                 C   s   t tj| _d | _d S r2   )nextr  counterr;   prev_debug_namerv   r   r   r   r     s    zDebugDirManager.__init__c                 C   s0   t jjj| _| j d| j | _| jt jj_d S )NZ_tmp_)r   _dynamor   debug_dir_rootr  r;   new_namerv   r   r   r   	__enter__  s    zDebugDirManager.__enter__c                 G   s   t | j | jtjj_d S r2   )shutilrmtreer!  r  r   r  r   r   )rw   r   r   r   r   __exit__  s    zDebugDirManager.__exit__N)	r   r  r  r   countr  r   r"  r%  r   r   r   r   r    s   
r  c                    s  ddl m} ddlm} tj  | }t  tj	
tjddh |@ || d|jdd d d }|d }t| | |i | |jd usJ  fd	d
t|D }t|dksJ | d|j tj|d d}	t|	dP}
|
 W  d    W  d    W  d    W  d    W  d    S 1 sV0    Y  W d    n1 sv0    Y  W d    n1 s0    Y  W d    n1 s0    Y  W d    n1 s0    Y  d S )Nr   )DebugContextrL   ZenabledT/r   z*inference*c                    s   g | ]}| vr|qS r   r   r"   Zexisting_dirsr   r   r%     r&   z+run_and_get_triton_code.<locals>.<listcomp>r   r   zoutput_code.pyr)Ztorch._inductor.debugr'  Ztorch._inductor.virtualizedrM   r   r  resetr  r   r   objectr   traceZset_debug_handlerr   _pathr
  globr6   r   r   openread)rp   r   r   r'  rM   contextdir_nameZfilZdir_dbgZ	full_namer}   r   r)  r   run_and_get_triton_code  s*    

 r4  c                 C   s    t jrt|  n
t|  dS )z
    Warnings that will be actionable for PyTorch developers, but not
    end users.  Allows us to easily disable them in stable releases but
    keep them on for nightly builds.
    N)r   Zdeveloper_warningsr  r  info)msgr   r   r   developer_warning  s    r7  )r   )r   rm   rm   rn   )N)Tcollectionsr   r'   r/  r   loggingr  r)   r   r#  r   r  rc   ior   typingr   r   r   r   r   Zunittestr   r-   r   Ztorch.fx.immutable_collectionsr	   r
   r   r   r  Zcuda_propertiesr   	getLoggerr   r  ExprZ	VarRangesZtriton.testingr   r   	lru_cacher   r!   r,   r1   r:   r>   rA   rB   rE   rK   rP   ra   rb   rl   rs   __hash__r   rZ   r   r   r   r   r   r   r   r   r   r   r   
namedtupler   r   r   r   r   r   r   r  r  r  r4  r7  r   r   r   r   <module>   s   


$




X 
	