U
    ©Ê¹jvx  ã                   @   sr  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Zd dlZd dl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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%m&Z& ddl'm(Z( dd	l)m*Z*m+Z+ e ,e-¡Z.ed
ƒZ/eej0ej0f Z1dd„ Z2e 3d¡e4dœdd„ƒZ5e 3d¡e4dœdd„ƒZ6dd„ Z7eeej8 e9f ej8dœdd„Z:dd„ Z;dd„ Z<ee/ ee/ dœdd„Z=e>e>e>dœdd „Z?e>e>d!œd"d#„Z@eee>ejAf  eej0 d$œd%d&„ZBeee>ej0f  eee>ejAf  d$œd'd(„ZCd)d*„ ZDd+d,„ ZEd»ed-ef e>eFd.œd/d0„ZGd¼d4d5„ZHd6d7„ e!_Id8d7„ e"_Iee9d9œd:d;„ZJeee9 d<œd=d>„ZKe>dœd?d@„ZLdAdB„ ZMdCdD„ ZNdEdF„ ZOdGdH„ ZPdIdJ„ ZQd½eejRjS eejRjS dKœdLdM„ZTdNdO„ ZUej0e9dPœdQdR„ZVe9ejWdSœdTdU„ZXej0eeef ej0dVœdWdX„ZYej0e9dYœdZd[„ZZej0e9d\œd]d^„Z[d_d`„ Z\e j]dadbdcdddege^ƒ e^ƒ e^ƒ e^ƒ gdf�Z_ej`d¾dgdh„ƒZaee> dœdidj„Zbe 3dk¡dldm„ ƒZcG dndo„ doeƒZdG dpdq„ dqƒZeG drds„ dsƒZfe 3d¡dtdu„ ƒZgdvdwœdxdy„Zhdzd{„ ZiG d|d}„ d}ƒZjd~d„ Zkd€d�„ Zlej`d‚dƒ„ ƒZmd¿d„d…„Znd†d‡„ Zod dˆœejpe>e>d‰œdŠd‹„ZqdÀd�dŽ„Zrd�d�„ Zsd‘d’„ Ztd“d”„ Zud•d–„ Zvej0ejwd—œd˜d™„Zxej`dšd›„ ƒZydœd�„ ZzdžZ{zd dl|Z|W n e}k
�rò   dvZ{Y nX dŸd „ Z~d¡d¢„ Zd£d¤„ Z€d¥d¦„ Z�d§d¨„ Z‚e 3d¡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 )Áé    N)ÚStringIO)ÚAnyÚCallableÚDictÚIterableÚListÚ
NamedTupleÚOptionalÚSetÚTypeVarÚUnionÚ
ValuesView)Úmock)Úimmutable_dictÚimmutable_list)ÚCleanDivÚFloorDivÚModularIndexingé   )Úconfig)Úcurrent_deviceÚget_device_capabilityÚ_Tc                  O   s:   t  d ¡dd„ ƒ}|ƒ \}}||kr,d||< || |Žd S )Nc                  S   sP   zddl m}  W n tk
r,   tdƒ‚Y nX | t | ¡j d¡d k	rJdndfS )Nr   )Údo_benchzrequires TritonZ	quantilesZpercentiles)Útriton.testingr   ÚImportErrorÚNotImplementedErrorÚinspectÚ	signatureÚ
parametersÚget)Útriton_do_bench© r"   úT/var/www/html/bwave/python/venv/lib/python3.8/site-packages/torch/_inductor/utils.pyÚload_triton0   s    	ÿÿüzdo_bench.<locals>.load_triton)g      à?gš™™™™™É?gš™™™™™é?r   )Ú	functoolsÚ	lru_cache)ÚargsÚkwargsr$   r!   Zquantile_field_namer"   r"   r#   r   /   s    

r   ©Úreturnc                  C   sF   t j ¡ sdS zdd l} | d k	o(tƒ dkW S  tk
r@   Y dS X d S )NFr   )é   r   )ÚtorchÚcudaÚis_availableÚtritonr   r   )r/   r"   r"   r#   Ú
has_tritonN   s    
r0   c                  C   sF   z*ddl m}  | d k	o(tttjdd ƒdƒW S  tk
r@   Y dS X d S )Nr   ©Ú	roi_alignZtorchvisionr2   F)Ztorchvision.opsr2   ÚhasattrÚgetattrr,   Zopsr   r1   r"   r"   r#   Úhas_torchvision_roi_alignZ   s    
 ÿr5   c                  G   s   t  tjdd„ | D ƒ¡S )Nc                 S   s   g | ]}|r|‘qS r"   r"   ©Ú.0Úxr"   r"   r#   Ú
<listcomp>g   s      z'conditional_product.<locals>.<listcomp>)r%   ÚreduceÚoperatorÚmul)r'   r"   r"   r#   Úconditional_productf   s    r=   )Údevicer*   c                 C   sP   | d krt  d¡jS t| tƒr(t  | ¡} | jdkrL| jd krLt jdtƒ d�S | S )Ng        r-   )Úindex)r,   Útensorr>   Ú
isinstanceÚstrÚtyper?   r   )r>   r"   r"   r#   Údecode_devicej   s    

rD   c                 C   s   t  tj| t d¡¡S )Nr   )r%   r:   r;   r<   ÚsympyÚInteger©Úitr"   r"   r#   Úsympy_productt   s    rI   c                 C   s2   t | ƒt |ƒkst‚t tdd„ t| |ƒD ƒƒ¡S )Nc                 s   s   | ]\}}|| V  qd S ©Nr"   )r7   ÚaÚbr"   r"   r#   Ú	<genexpr>z   s     zsympy_dot.<locals>.<genexpr>)ÚlenÚAssertionErrorrE   ÚexpandÚsumÚzip)Zseq1Zseq2r"   r"   r#   Ú	sympy_dotx   s    rS   )rH   r*   c                 C   s   dd„ | D ƒ  ¡ S )Nc                 S   s   i | ]}t |ƒ|“qS r"   )Úidr6   r"   r"   r#   Ú
<dictcomp>~   s      zunique.<locals>.<dictcomp>)ÚvaluesrG   r"   r"   r#   Úunique}   s    rW   )ÚnumerÚdenomr*   c              	   C   sF   t | tƒrt |tƒs:t| › dt| ƒ› d|› dt|ƒ› �ƒ‚| |   S )Nz: ú, )rA   ÚintrO   rC   )rX   rY   r"   r"   r#   Úceildiv�   s     ÿ þr\   )Únr*   c                 C   s`   | dkst dƒ‚| d8 } | | d? O } | | d? O } | | d? O } | | d? O } | | d? O } | d7 } | S )z9Return the smallest power of 2 greater than or equal to nl        z32-bit onlyr   é   é   é   é   )rO   ©r]   r"   r"   r#   Únext_power_of_2‹   s    rc   )Úlstr*   c                 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"   )rA   r,   ÚSymIntÚnodeÚexprrE   rF   ©r7   Úir"   r"   r#   r9   ž   s    z-convert_shape_to_inductor.<locals>.<listcomp>r"   ©rd   r"   r"   r#   Úconvert_shape_to_inductor˜   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)rA   r[   rE   rF   ÚgraphZsizevarsZ	shape_envZcreate_symintnoderh   rl   r"   r#   r9   ¬   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 ƒƒsvt
‚| | t|ƒ|¡}t| jjƒdkr´t| jjd jƒdkr´|f}| |¡ t j i |¡}	|	|fS )NÚargc                 s   s   | ]}t |tjƒ V  qd S rJ   )rA   r,   ÚTensorr6   r"   r"   r#   rM   À   s     z$gen_gm_and_inputs.<locals>.<genexpr>r   r   rr   )r,   ÚfxZGraphÚ	enumeraterA   rr   ÚappendÚplaceholderÚallrV   rO   Úcall_functionÚtuplerN   Z_schemaZreturnsrB   rC   ÚoutputZGraphModule)
Útargetr'   r(   ÚgZg_argsZa_argsr]   rq   rf   Úgmr"   r"   r#   Úgen_gm_and_inputs¶   s$    
ÿþ
r~   c                   C   s   t j ¡ rt j ¡  d S rJ   )r,   r-   r.   Úsynchronizer"   r"   r"   r#   r   Í   s    
r   .)ÚmodelÚtimesr*   c                 C   sP   t ƒ  t d¡ t ¡ }t|ƒD ]}| |Ž }t ƒ  q t ¡ }|d k	sHt‚|| S )Ni9  )r   r,   Zmanual_seedÚtimeÚperf_counterÚrangerO   )r€   Zexample_inputsr�   Út0Ú_ÚresultÚt1r"   r"   r#   ÚtimedÒ   s    
r‰   r"   é
   ç      ð?c                    s>   t  ‡ ‡‡fdd„t|ƒD ƒ¡}t  |¡}t|| d›ƒ |S )Nc                    s   g | ]}t ˆˆ ˆƒ‘qS r"   )r‰   )r7   r†   ©r'   Úfnr�   r"   r#   r9   à   s     z%print_performance.<locals>.<listcomp>z.6f)r,   r@   r„   ZmedianÚprint)r�   r'   r�   ÚrepeatZbaselineZtimingsZtookr"   rŒ   r#   Úprint_performanceß   s     
r�   c                 C   s   t t|  ¡ ƒƒS rJ   )Úhashry   Úitems©Úselfr"   r"   r#   Ú<lambda>æ   ó    r•   c                 C   s   t t| ƒƒS rJ   )r‘   ry   r“   r"   r"   r#   r•   ç   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 rJ   r"   r"   ©r‡   r"   r#   r•   í   r–   z#precompute_method.<locals>.<lambda>N)r4   Ú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 rJ   )r[   )rK   rL   r"   r"   r#   Úcmpö   s    rŸ   c                 C   s*   t | ƒdkr"t| ƒ| d gƒ| S | S d S )Nr   r   )rN   rC   )r8   Úsizer"   r"   r#   Úpad_listlikeú   s    r¡   c                    s*   dˆ j › d�‰t ˆ ¡‡ ‡fdd„ƒ}|S )NÚ__Ú_cachec                    s$   t | ˆƒst| ˆˆ | ƒƒ t| ˆƒS rJ   )r3   r›   r4   r“   ©r�   Úkeyr"   r#   Úwrapper  s    
zcache_on_self.<locals>.wrapper)Ú__name__r%   Úwraps)r�   r¦   r"   r¤   r#   Úcache_on_self  s    r©   c                 C   sN   ddl m} t| tƒr2t tjdd„ | D ƒtƒ ¡S t| |j	ƒrD| j
S tƒ S d S )Nr   ©Úirc                 S   s$   g | ]}t |d ƒr|jr|jj‘qS )rf   )r3   rf   Úorigins)r7   rf   r"   r"   r#   r9     s   
 þz%aggregate_origins.<locals>.<listcomp>)Ú r«   rA   Úlistr%   r:   r;   Úor_ÚsetZExternKernelr¬   )Únode_scheduler«   r"   r"   r#   Úaggregate_origins  s    
þù	r²   c                 C   sÔ   t | ƒ}|dkr,dd„ |D ƒ}tt|ƒƒ}n”|dkr¤g }|D ]X}|jdkr<d|jkr<t|jd d tƒr~| |jd d ¡ q<| |jd d j¡ q<tt|ƒƒ}n|dkr¼d	d„ |D ƒ}nt	‚|}d
 
dg| ¡S )NÚoriginal_atenc                 S   s.   g | ]&}|j d krd|jkr|jd jj‘qS )rx   r³   )ÚopÚmetaÚ_overloadpacketr§   ©r7   Úoriginr"   r"   r#   r9   $  s   
 
þz)get_fused_kernel_name.<locals>.<listcomp>r,   rx   Z	source_fnr   Zinductor_nodec                 S   s   g | ]}|j d kr|j‘qS ©rx   )r´   Únamer·   r"   r"   r#   r9   5  s    
 r†   Zfused)r²   Úsortedr°   r´   rµ   rA   rB   ru   r§   r   Újoin)r±   Zdescriptive_namesÚall_originsÚsourcesr¸   r"   r"   r#   Úget_fused_kernel_name   s*    þÿr¿   c                 C   s  t | ƒ}dd„ |D ƒ}t t¡}t t¡}|D ]Z}d|jkr\t|jd jƒ}||  |j¡ d|jkr.|jd d d }||  |j¡ q.|j	› dd 
t| ¡ ƒ¡› dd 
t| ¡ ƒ¡› d	�}g }	t| ¡ ƒD ].\}
}|	 |j	› d
|
› dd 
t|ƒ¡› �¡ qÎ|d 
|	¡fS )Nc                 S   s   g | ]}|j d kr|‘qS r¹   )r´   r·   r"   r"   r#   r9   @  s     
 z'get_kernel_metadata.<locals>.<listcomp>r³   Z	from_noder   z Source Nodes: [rZ   z], Original ATen: [ú]ú z => Ú
)r²   ÚcollectionsÚdefaultdictr®   rµ   rB   r¶   ru   rº   Úcommentr¼   r»   Úkeysr’   )r±   r¦   r½   Zinductor_nodesZfrom_node_dictZoriginal_aten_dictrf   r¥   ÚmetadataZdetailed_metadataZoriginal_nodeÚnodesr"   r"   r#   Úget_kernel_metadata>  s&    



2ÿÿrÉ   )Úinitial_queuer*   c                 C   sX   t | ƒ} t| ƒ}| rT|  ¡ }|jD ].}|r4||ƒr4q"||kr"| |¡ |  |¡ q"q|S )zJReturns the set of nodes whose values depend on those within initial_queue)r®   r°   ÚpopZusersÚaddru   )rÊ   Zskip_filterZdominated_setrf   Úuserr"   r"   r#   Údominated_nodesX  s    

rÎ   c                    s\   dd l }ddlm‰  ‡ ‡fdd„‰‡fdd„| ¡ D ƒ}‡fdd„| D ƒ}t|j||žŽ ƒS )	Nr   r   rª   c                    sD   t | ˆ jƒrˆ| jƒS t | ˆ jƒr,ˆ| jƒS t | ˆ jƒoBt | ˆ jƒS rJ   )rA   Ú	TensorBoxÚdataZ
StorageBoxZIRNodeZ	Pointwiserb   ©r«   Úis_unrealized_noder"   r#   rÒ   p  s
    

z*gather_origins.<locals>.is_unrealized_nodec                    s   g | ]}ˆ |ƒr|j ‘qS r"   ©r¬   )r7   Úval©rÒ   r"   r#   r9   w  s      z"gather_origins.<locals>.<listcomp>c                    s   g | ]}ˆ |ƒr|j ‘qS r"   rÓ   )r7   rq   rÕ   r"   r#   r9   x  s      )Ú	itertoolsr­   r«   rV   r°   Úchain)r'   r(   rÖ   Zkwarg_originsZarg_originsr"   rÑ   r#   Úgather_originsk  s    rØ   )rg   r*   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 t | t
t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 * ú(rZ   ú))rA   rE   ÚSymbolrº   ÚAddr¼   ÚmapÚ	sympy_strr'   ZMulr   r   r   Úfuncr§   rB   )rg   r"   r"   r#   rÞ   |  s    "rÞ   )rº   r*   c                 C   s    | d dkst ‚tj| ddd�S )Nr   ÚsT)ÚintegerZnonnegative)rO   rE   rÛ   ©rº   r"   r"   r#   Úsympy_symbolŽ  s    rã   )rg   Úreplacementsr*   c                    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 rJ   )rA   rB   rã   )r¥   r"   r"   r#   Úpromote_stringsœ  s    
z#sympy_subs.<locals>.promote_stringsc                    s   i | ]\}}ˆ |ƒˆ |ƒ“qS r"   r"   )r7   ÚkÚv©rå   r"   r#   rU   ¢  s      zsympy_subs.<locals>.<dictcomp>)Zxreplacer’   )rg   rä   r"   rè   r#   Ú
sympy_subs—  s    ÿré   ©r?   Úprefixc                    s   t ‡ fdd„| jD ƒƒS )Nc                 3   s   | ]}|j  ˆ ¡V  qd S rJ   )rº   Ú
startswith©r7   rç   ©rë   r"   r#   rM   §  s     z)free_symbol_startswith.<locals>.<genexpr>©ÚanyZfree_symbolsrê   r"   rî   r#   Úfree_symbol_startswith¦  s    rñ   ©r?   Úpatternc                    s   t ‡ fdd„| jD ƒƒS )Nc                 3   s   | ]}ˆ |j kV  qd S rJ   râ   rí   ©ró   r"   r#   rM   «  s     z"free_symbol_has.<locals>.<genexpr>rï   rò   r"   rô   r#   Úfree_symbol_hasª  s    rõ   c                 C   s`   dddddddh}t  ¡ r:| dd	d
ddddddddh¡ | jjD ]}t|jƒ|krB dS qBdS )Nz,aten._fused_moving_avg_obs_fq_helper.defaultz7aten._fused_moving_avg_obs_fq_helper_functional.defaultzaten.multinomial.defaultzfbgemm.dense_to_jagged.defaultz%fbgemm.jagged_to_padded_dense.defaultZrun_and_save_rng_stateZrun_with_rng_statezaten._unsafe_index_put.defaultzaten.index_put.defaultzaten.index_put_.defaultzaten.scatter.srczaten.scatter.reducezaten.scatter.value_reducezaten.scatter_add_zaten.scatter_add.defaultzaten.scatter_reduce.twozaten.scatter_reduce_.twozaten.scatter_reduce.two_outTF)r,   Z$are_deterministic_algorithms_enabledÚupdatero   rÈ   rB   r{   )r}   Zforbidden_setrf   r"   r"   r#   Úhas_incompatible_cudagraph_ops®  s6    ù	õÿr÷   Úinstance_descriptorZdivisible_by_16Z
equal_to_1Zids_of_folded_argsZdivisible_by_8)Údefaultsc                 #   s¸   t  ¡ �¦}tj tjd|i¡�† tj |d¡‰ tj tjdˆ i¡�X dV  t	| tƒr–t
| ƒdkshtdƒ‚tj ˆ ¡r–t ˆ ¡}|  ‡ fdd„|D ƒ¡ W 5 Q R X W 5 Q R X W 5 Q R X 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 |kr|t j t j ˆ |¡¡“qS )z.lock)ÚosÚpathÚgetsizer¼   )r7   Úf©Ztriton_cache_dirr"   r#   rU   é  s   þ z(fresh_inductor_cache.<locals>.<dictcomp>)ÚtempfileÚTemporaryDirectoryr   ÚpatchÚdictrú   Úenvironrû   r¼   rA   rN   rO   ÚexistsÚlistdirrö   )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__r„   rN   r®   Úreversedr»   )ÚseqÚgetterZa_rr"   r"   r#   Úargsortñ  s    r  r`   c                 C   s   t jd| d� ¡ S )Nr"   ©Údtype)r,   ÚemptyÚelement_sizer  r"   r"   r#   Úget_dtype_sizeø  s    r  c                   @   s   e Zd ZU eed< dS )ÚLineContextÚcontextN)r§   Ú
__module__Ú__qualname__r   Ú__annotations__r"   r"   r"   r#   r  ý  s   
r  c                   @   sn   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„ Zddd„Zddd„ZdS )ÚIndentedBufferr_   r   c                 C   s   g | _ || _d S rJ   )Ú_linesÚ_indent)r”   Úinitial_indentr"   r"   r#   Ú__init__  s    zIndentedBuffer.__init__c                 C   s’   t ƒ }d}g }| jD ]p}t|tƒr4|ƒ }|d krPqnt|tƒrP| ||jf¡ qt|tƒs^t‚| 	|¡ | 	d¡ |d| 
d¡ 7 }q| ¡ |fS )Nr   rÂ   )r   r  rA   ÚDeferredLineBaser  ru   r  rB   rO   ÚwriteÚcountÚgetvalue)r”   ÚbufÚpZlinemapÚliner"   r"   r#   Úgetvaluewithlinemap  s     




z"IndentedBuffer.getvaluewithlinemapc                 C   s   |   ¡ \}}|S rJ   )r$  )r”   rç   r†   r"   r"   r#   r     s    zIndentedBuffer.getvaluec                 C   s‚   t ƒ }| jD ]l}t|tƒr,|ƒ }|d kr8qnt|tƒr8qt|tƒsFt‚| d¡rd| |d d… ¡ q| |¡ | d¡ q| 	¡ S )Nú\éÿÿÿÿrÂ   )
r   r  rA   r  r  rB   rO   Úendswithr  r   )r”   r!  r#  r"   r"   r#   Úgetrawvalue  s    




zIndentedBuffer.getrawvaluec                 C   s   | j  ¡  d S rJ   )r  Úclearr“   r"   r"   r#   r)  0  s    zIndentedBuffer.clearc                 C   s
   t | jƒS rJ   )Úboolr  r“   r"   r"   r#   Ú__bool__3  s    zIndentedBuffer.__bool__c                 C   s   d| j | j  S )NrÁ   )r  Útabwidthr“   r"   r"   r#   rë   6  s    zIndentedBuffer.prefixc                 C   sl   t |tƒr| j |¡ nPt |tƒr:| j | |  ¡ ¡¡ n.| ¡ r\| j |  ¡ › |› �¡ n| j d¡ d S ©Nr­   )rA   r  r  ru   r  Úwith_prefixrë   Ústrip©r”   r#  r"   r"   r#   Ú	writeline9  s    

zIndentedBuffer.writelinec                 C   s   |D ]}|   |¡ qd S rJ   )r1  )r”   Úlinesr#  r"   r"   r#   Ú
writelinesC  s    zIndentedBuffer.writelinesr   c                    s   t j‡ ‡fdd„ƒ}|ƒ S )Nc                	   3   s.   ˆ j ˆ 7  _ z
d V  W 5 ˆ j ˆ 8  _ X d S rJ   )r  r"   ©Úoffsetr”   r"   r#   ÚctxH  s    
z"IndentedBuffer.indent.<locals>.ctx)Ú
contextlibÚcontextmanager)r”   r5  r6  r"   r4  r#   ÚindentG  s    zIndentedBuffer.indentFc                 C   sÖ   t |tƒr’tdƒ}|jD ],}t |tƒs|rt|t|ƒt| ¡ ƒ ƒ}qt 	|¡rTd}|jD ]4}t |tƒrv| j 
|¡ qZt | |t|ƒd … ¡ qZn@t |¡}|r¨| ¡ }|s°d S | ¡ }| d¡D ]}|  |¡ qÂd S )NÚinfr   rÂ   )rA   r  Úfloatr  r  ÚminrN   ÚlstripÚmathÚisinfru   r1  r[   ÚtextwrapÚdedentÚrstripÚsplit)r”   Z
other_coder/  rA  r#  r"   r"   r#   ÚspliceR  s&    





zIndentedBuffer.spliceN)r   )r   )F)r§   r  r  r,  r  r$  r   r(  r)  r+  rë   r1  r3  r9  rD  r"   r"   r"   r#   r    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#  r0  r"   r"   r#   r  m  s    zDeferredLineBase.__init__r)   c                 C   s
   t ƒ ‚dS )zJReturns either self.line or None to indicate the line has been 'unwritten'N©r   r“   r"   r"   r#   Ú__call__r  s    zDeferredLineBase.__call__)r#  r*   c                 C   s
   t ƒ ‚dS )z3Returns a new deferred line with the same conditionNrE  r0  r"   r"   r#   Ú	_new_linev  s    zDeferredLineBase._new_linec                 C   s   |   |› | j› �¡S rJ   ©rG  r#  )r”   rë   r"   r"   r#   r.  z  s    zDeferredLineBase.with_prefixc                 C   s   |   | j ¡ ¡S rJ   )rG  r#  r=  r“   r"   r"   r#   r=  }  s    zDeferredLineBase.lstripc                 C   s   |   | j| ¡S rJ   rH  )r”   r?   r"   r"   r#   r	  €  s    zDeferredLineBase.__getitem__c                 C   s
   t | jƒS rJ   )r*  r#  r“   r"   r"   r#   r+  ƒ  s    zDeferredLineBase.__bool__c                 C   s
   t | jƒS rJ   )rN   r#  r“   r"   r"   r#   Ú__len__†  s    zDeferredLineBase.__len__N)r§   r  r  Ú__doc__r  r	   rB   rF  rG  r.  r=  r	  r+  rI  r"   r"   r"   r#   r  j  s   r  c                 C   s(   t j | ¡j}|dk r$t d¡ dS dS )NéP   z,not enough SMs to use max_autotune_gemm modeFT)r,   r-   Zget_device_propertiesZmulti_processor_countÚlogÚwarning)r?   Zsmsr"   r"   r#   Ú
is_big_gpuŠ  s
    
rN  F)Úenable_int32c                C   st   t jt jt jg}|r(t jt jt jt jg}tjs:tjs:tjordtj	 
¡  d¡kor| jjdkor| j|kort| jjppdƒS )NZTRITONú,r-   r   )r,   Úfloat16Úbfloat16Úfloat32Zint32r   Zmax_autotuneZmax_autotune_gemmZsearch_autotune_cacheÚmax_autotune_gemm_backendsÚupperrC  r>   rC   r  rN  r?   )ZlayoutrO  Zlayout_dtypesr"   r"   r#   Úuse_triton_template“  s     ÿýû
úù÷rV  c                   C   s   dt j ¡  d¡kS )NZATENrP  )r   rT  rU  rC  r"   r"   r"   r#   Úuse_aten_gemm_kernels¤  s    rW  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 rJ   )ÚnextrX  ÚcounterrT   Úprev_debug_namer“   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[  rT   Únew_namer“   r"   r"   r#   Ú	__enter__¯  s    zDebugDirManager.__enter__c                 G   s   t  | j¡ | jtjj_d S rJ   )ÚshutilÚrmtreer^  r[  r,   r\  r   r]  )r”   r'   r"   r"   r#   Ú__exit__´  s    zDebugDirManager.__exit__N)	r§   r  r  rÖ   r  rZ  r  r_  rb  r"   r"   r"   r#   rX  ¨  s   
rX  c              	      s\   ddl m} |j‰ g ‰‡ ‡fdd„}tj |d|¡� tj ¡  | ||Ž}W 5 Q R X |ˆfS )Nr   )ÚGraphLoweringc              	      s0   ˆ | ƒ}t |jƒ�}ˆ | ¡ ¡ W 5 Q R X |S rJ   )ÚopenÚ__file__ru   Úread)r”   Úmodrý   ©Úcompile_to_moduleÚsource_codesr"   r#   Úpatched_compile_to_module¿  s    z3run_and_get_code.<locals>.patched_compile_to_moduleri  )	ro   rc  ri  r   r  Úobjectr,   r\  Úreset)r�   r'   r(   rc  rk  r‡   r"   rh  r#   Úrun_and_get_code¹  s      ÿ
rn  c                 O   sH   t | f|ž|Ž\}}dt|ƒ  kr,dks@n tdt|ƒ› �ƒ‚|d S )Nr   r^   z%expected one or two code outputs got r   )rn  rN   rO   )r�   r'   r(   r†   rj  r"   r"   r#   Úrun_and_get_triton_codeÍ  s     ÿÿ
þro  c              	   c   sD   ddl m} |j|  }zt ||¡|j| < dV  W 5 ||j| < X dS )z~
    Override the lowering of aten_op with overide_fn.
    The first argument of override_fn is the original lowering fn.
    r   )ÚloweringN)Ztorch._inductorrp  Z	loweringsr%   Úpartial)Zaten_opZoverride_fnrp  Úorig_fnr"   r"   r#   Úoverride_loweringÖ  s    

rs  c                    s4   ddl m} |j‰ ‡ ‡‡fdd„}tjj |d|¡S )zr
    Add hook functions to be called at the beginning and end of Scheduler.__init__.
    Used for unit tests.
    r   )Ú	Schedulerc                    s&   ˆ| |ƒ ˆ | |ƒ}ˆr"ˆ| |ƒ |S rJ   r"   )Z	schedulerrÈ   Úout©rr  Úpost_fnÚpre_fnr"   r#   r¦   ï  s
    


z(add_scheduler_init_hook.<locals>.wrapperr  )Ztorch._inductor.schedulerrt  r  Úunittestr   r  rl  )rx  rw  rt  r¦   r"   rv  r#   Úadd_scheduler_init_hookæ  s    rz  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_warningsrL  rM  Úinfo©Úmsgr"   r"   r#   Údeveloper_warningù  s    r~  ©Únum_in_out_args)r'   r€  r*   c                    s   t ‡ fdd„t|ƒD ƒƒS )zì
    Return the total number of bytes the arguments of tensor type takes.

    For in/out args, tensor sizes are counted twice: once for reading and
    once for writing.

    The first num_in_out_args arguments are in out tensors.
    c                 3   s>   | ]6\}}t |tjƒr| ¡ | ¡  d t|ˆ k ƒ  V  qdS ©r   N)rA   r,   rr   Znumelr  r[   )r7   ri   rq   r  r"   r#   rM     s   þz get_num_bytes.<locals>.<genexpr>)rQ   rt   )r€  r'   r"   r  r#   Úget_num_bytes  s    	þr‚  r­   c                 C   sx   |› | d›d|d›d|d›d|› �}z0dd l }| dkrR|dk rR|jj| |jj }W n tk
rr   t d	¡ Y nX |S )
Nz.3fzms    	z GB 	 z7.2fzGB/sr   gú~j¼t“ˆ?iŠ  z@Colorama is not installed. Install it if you want colored output)ÚcoloramaÚForeZREDÚRESETr   rL  rM  )ÚmsZnum_gbZgb_per_srë   ÚsuffixZinfo_strrƒ  r"   r"   r#   Úcreate_bandwidth_info_str  s    $rˆ  c                  C   s¢   z^t j d¡} | d tt jƒk r\tt j| d  ƒdkr\t j| d  d dkr\t j| d  W S W n tk
rr   Y nX t jD ]"}| d¡rz|tdƒd…   S qzdS )a  
    An experimental API used only when config.benchmark_kernel is true.

    The benchmark name is only available at codegen time. So we can not
    directly call it in benchmark_all_kernels which is run after codegen.

    The function assumes the argument after --only is the benchmark name.
    It works for torchbench.py/hugginface.py/timm_models.py. But for ad-hoc
    scripts, this function may return None.

    There are 2 flavors of --only argument we need handle:
    1. --only model_name
    2. --only=model_name
    z--onlyr   r   ú-z--only=N)ÚsysÚargvr?   rN   Ú
ValueErrorrì   )Úidxrq   r"   r"   r#   Úget_benchmark_name"  s    ÿþý

rŽ  c                 C   s   t dd„ | D ƒƒS )Nc                 s   s   | ]}|d kV  qdS r�  r"   r6   r"   r"   r#   rM   B  s     zis_ones.<locals>.<genexpr>©rw   ©r’   r"   r"   r#   Úis_onesA  s    r‘  c                 C   s   t dd„ | D ƒƒS )Nc                 s   s   | ]}|d kV  qdS )r   Nr"   r6   r"   r"   r#   rM   F  s     zis_zeros.<locals>.<genexpr>r�  r�  r"   r"   r#   Úis_zerosE  s    r’  c                 C   s   t dd„ | D ƒƒS )Nc                 s   s*   | ]"}t |tjƒr|jt d ¡kV  qdS )ÚcpuN)rA   r,   rr   r>   )r7   Úitemr"   r"   r#   rM   J  s   þz is_cpu_device.<locals>.<genexpr>r�  )Úinputsr"   r"   r#   Úis_cpu_deviceI  s    þr–  )rÔ   r*   c                 C   s*   t | tjƒstdƒ‚| jr tjS tjS d S )Nz8only support sympy.Expr as input to get_sympy_Expr_dtype)rA   rE   ÚExprrO   Ú
is_integerr,   Zint64Zfloat64)rÔ   r"   r"   r#   Úget_sympy_Expr_dtypeQ  s     ÿþr™  c              	   o   s0   | r&t jj||Ž�}|V  W 5 Q R X nd V  d S rJ   )r,   ZprofilerZprofile)Zshould_profiler'   r(   r"  r"   r"   r#   Úmaybe_profile[  s    rš  c                 C   s6   t | j ¡ ƒ}| d| jf¡ | d| jf¡ t|ƒS )z~
    Convert triton config to a tuple that can uniquely identify it. We can use
    the return value as a dictionary key.
    Ú	num_warpsÚ
num_stages)r»   r(   r’   ru   r›  rœ  ry   )Úcfgr’   r"   r"   r#   Útriton_config_to_hashabled  s    rž  Tc                 C   s$   t s| S ttj| ¡ ƒ|  tjj S rJ   )ÚHAS_COLORAMAr4   rƒ  r„  rU  r…  )r}  Úcolorr"   r"   r#   Ú_color_textv  s    r¡  c                 C   s
   t | dƒS )NÚgreen©r¡  r|  r"   r"   r#   Ú
green_text}  s    r¤  c                 C   s
   t | dƒS )NÚyellowr£  r|  r"   r"   r#   Úyellow_text�  s    r¦  c                 C   s
   t | dƒS )NÚredr£  r|  r"   r"   r#   Úred_text…  s    r¨  c                 C   s
   t | dƒS )NÚbluer£  r|  r"   r"   r#   Ú	blue_text‰  s    rª  c               
   C   s.   ddl m}  tjdtjdtdtd| jdi}|S )Nr   rª   r[   ZDevicer*  r;  rr   )r­   r«   r,   r  r>   r*  r;  rÏ   )r«   ZPYTHON_TYPE_TO_SCHEMA_TYPEr"   r"   r#   Úpython_type_to_schema_type�  s         ûr«  c                 C   s   |rd| › d�S | S )Nz	Optional[rÀ   r"   )Úschema_typeÚis_optional_argr"   r"   r#   Úmay_get_optional_schema_type›  s    r®  c                 C   sh   t | tƒr6tdd„ | D ƒƒr2td|ƒ}|t|ƒkS dS | jtƒ krdtƒ | j }t||ƒ}|t|ƒkS dS )Nc                 s   s*   | ]"}t |tƒp t |tjƒo |jV  qd S rJ   )rA   r[   rE   rÛ   r˜  r6   r"   r"   r#   rM   ¡  s   ÿztype_match.<locals>.<genexpr>z	List[int]F)rA   r   rw   r®  rB   Ú	__class__r«  )rq   Zarg_typer­  Zmay_optional_schema_typer¬  r"   r"   r#   Ú
type_matchŸ  s$    
þ ÿ ÿr°  c                    sT  d}d}| j D ]"}| ¡ s"|d7 }|js|d7 }qt|ƒ}t|ƒ}d}dd„ }	dd„ ‰ ‡ fdd„}
t|ƒ|ks‚t|	t|ƒ||ƒƒ‚| j D ]¸}d }d	}||k r²|jr¨ d	S || }n|rÎ|j|krÎ||j }d
}|d krä|
|ƒsä d	S |d k	�r|j}t||ˆ |ƒƒ�s d	S |�s|d7 }qˆ|d k�r0ˆ |ƒ�s8|d k	rˆ|d8 }qˆ|dk�rPd	S d
S )Nr   r   c                 S   s6   ||kr d|› d|› d| › d�S d|› d| › d�S d S )Nztakes from z to z positional arguments but z were givenztakes r"   )ÚnargsÚmax_pos_argsÚmin_argsr"   r"   r#   Úargs_error_messageÆ  s    z(schema_match.<locals>.args_error_messagec                 S   s   dt | jƒkS )Nr	   )rB   rC   ©rq   r"   r"   r#   Úis_optionalÌ  s    z!schema_match.<locals>.is_optionalc                    s   ˆ | ƒp|   ¡ S rJ   )Úhas_default_valuerµ  ©r¶  r"   r#   Ú
allow_noneÏ  s    z schema_match.<locals>.allow_noneFT)Ú	argumentsr·  Z
kwarg_onlyrN   rO   rº   rC   r°  )Úschemar'   r(   r³  r²  Úargumentr±  Zremaining_kwargsZarg_posr´  r¹  r˜   Zis_kwdÚexpected_typer"   r¸  r#   Úschema_match¹  sT    

  ÿ







r¾  c                 C   s"   | D ]}t |||ƒr|  S qd S rJ   )r¾  )Zschemasr'   r(   r»  r"   r"   r#   Útry_find_schemaõ  s    
r¿  c                 C   sd   ddl m}m} | tjtjtjfks(t‚| tjtjfkr@|| ƒS tjj	j
jrV|tjƒS |tjƒS d S )Nr   )Úget_max_simd_tflopsÚget_max_tensorcore_tflops)r   rÀ  rÁ  r,   rQ  rR  rS  rO   Úbackendsr-   ÚmatmulZ
allow_tf32)r  rÀ  rÁ  r"   r"   r#   Úget_device_tflopsý  s    
rÄ  c                  C   s   ddl m}  | ƒ S )Nr   ©Úget_dram_gbps)r   rÆ  rÅ  r"   r"   r#   Úget_gpu_dram_gbps
  s    rÇ  c                 C   s
   |   d¡S )NZwelford)rì   ©Zreduction_typer"   r"   r#   Úis_welford_reduction  s    rÉ  c                 C   s   t | ƒrdS dS )Né   r   )rÉ  rÈ  r"   r"   r#   Úreduction_num_outputs  s    rË  )r   )r"   rŠ   rŠ   r‹   )N)N)N)r­   r­   )ŒrÃ   r7  r%   r   rÖ   Úloggingr>  r;   rú   r`  rŠ  rÿ   r@  r‚   ry  Úior   Útypingr   r   r   r   r   r   r	   r
   r   r   r   r   rE   r,   Ztorch.fx.immutable_collectionsr   r   Ztorch.utils._sympy.functionsr   r   r   r­   r   Zcuda_propertiesr   r   Ú	getLoggerr§   rL  r   r—  Z	VarRangesr   r&   r*  r0   r5   r=   r>   rB   rD   rI   rS   rW   r[   r\   rc   re   rk   rp   r~   r   r;  r‰   r�   Ú__hash__rœ   rž   rŸ   r¡   r©   r²   r¿   rÉ   rs   ÚNoderÎ   rØ   rÞ   rÛ   rã   ré   rñ   rõ   r÷   Ú
namedtuplery   rø   r8  r  r  r  r  r  r  rN  rV  rW  rX  rn  ro  rs  rz  r~  rr   r‚  rˆ  rŽ  r‘  r’  r–  r  r™  rš  rž  rŸ  rƒ  r   r¡  r¤  r¦  r¨  rª  r«  r®  r°  r¾  r¿  rÄ  rÇ  rÉ  rË  r"   r"   r"   r#   Ú<module>   sô   4
 

$þ


 ÿ

þ	 
ý
i 
	






<