U
    9%e	k                    @   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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mZ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"m#  mZ$ d dl m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+ d d	l,m-Z-m.Z.m/Z/ d d
l0m1Z1m2Z2m3Z3m4Z4 d dl5m6Z6 d dl7m8Z8m9Z9m:Z:m;Z; d dl<m=Z=m>Z> d dl?m@Z@ eZAeZBe+e*e)fZCeDeEZFG dd deGZHd dlIZId dlJmKZK d dlLmMZM e jNjOjPZPdddddddddddddd d!gZQedd"d# ZRdaSG d$d% d%eGZTG d&d dZUd'd ZVd(d ZWd)d* ZXd+d ZYd,d- ZZee[e+f d.d/dZ\ee]e)f d.d0d!Z^d1d2 Z_ee+e j`f eeIja d3d4dZbeeIja d5d6d Zcd7d8 Zdd9d: Zed;d< Zfd=d> Zgd?d@ ZhdAd ZieIjae[e[e[e[dBdCdDZjdee[ ee[ dEdFdGZkddHee[ ee[ dEdIdJZldKdL Zmde[dMdNdOZndPdQ ZodRd ZpdSd ZqdTdU ZrdVdW ZsdXdY ZtdZd[ Zud\d]d^d_Zvd`da ZweIjxe:dbdcddZyG dedf dfeZzed\dgG dhdi diZ{ed\dgG djdk dke{Z|ed\dgG dldm dme{Z}ee|e}df Z~ed\dgG dndo doe{ZG dpdq dqZG drds dseIjZG dtdu dueIjZG dvdw dweIjZefZedxdydz Zd{d| d}d| d~d| dd| dd| dd| dd| dd| dd| dd| dd| dZdd Zdd Zdd Zdd Zedd| dd| dd| dd| dd| dd| dd| edd| edd| dd| dd| dd| dZdd| dd| dd| dd| dd| dd| dZe je jdZdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdddddUdhZdddhZddhZddUdddhZddhZdd ZejejejejejejeeejejejeejejdZdddUdhZddhZddddddddddh
Zdd Zdd̈́ Zddτ Ze D ]\ZZeee qe D ]\ZZeee qddф Ze D ]4\ZZeekreee) neee+ eee* q[[e]d5ddӄZdddՄZed\dgG ddׄ d׃ZG ddل deKZG ddۄ deZG dd݄ deKZG dd߄ d߃Ze
 ZG dd dZdd Zdd ZdS )    N)defaultdict)contextmanager)	dataclassfield)Enum)	lru_cache)
AnycastCallableDictListOptionalSetTupleTypeUnion)	sym_floatsym_maxsym_minsym_notSymBoolSymFloatSymInt)
ShapeGuardSourceTracingContext)FloorDivLShiftModRShift)	try_solve)bound_sympySymPyValueRangeAnalysisValueRangesValueRangeError)format_frameCapturedTraceback)signpost_eventc                   @   s   e Zd ZdS )GuardOnDataDependentSymNodeN__name__
__module____qualname__ r-   r-   d/var/www/html/Darija-Ai-API/env/lib/python3.8/site-packages/torch/fx/experimental/symbolic_shapes.pyr(   /   s   r(   )
StrPrinter)
precedencehas_symbolic_sizes_stridescreate_contiguousShapeEnvis_concrete_intSymDispatchMode	guard_intguard_floatguard_scalar	wrap_nodemethod_to_operatorhint_intSYMPY_INTERPfree_symbolsis_symbol_binding_fx_nodeis_concrete_boolc                  C   s*   dd l } tjt | | jjg}dd |D S )Nr   c                 S   s   h | ]}t |qS r-   )inspectgetfile).0mr-   r-   r.   	<setcomp>I   s     z&uninteresting_files.<locals>.<setcomp>)Ztorch._inductor.sizevarssysmodulesr*   Z	_inductorZsizevars)torchmodsr-   r-   r.   uninteresting_filesA   s    rI   c                   @   s   e Zd ZdS )ConstraintViolationErrorNr)   r-   r-   r-   r.   rJ   S   s   rJ   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )r5   c                 C   s
   t  d S N)NotImplementedError)selffunctypesargskwargsr-   r-   r.   __sym_dispatch__f   s    z SymDispatchMode.__sym_dispatch__c                 C   s,   t }t| drt|  dn|| _| a | S )Ninnerz< has already been used as a mode. Please use a fresh version)SYM_FUNCTION_MODEhasattrRuntimeErrorrS   )rM   oldr-   r-   r.   	__enter__i   s    
zSymDispatchMode.__enter__c                 C   s
   | j ad S rK   )rS   rT   )rM   exc_typeexc_valexc_tbr-   r-   r.   __exit__s   s    zSymDispatchMode.__exit__N)r*   r+   r,   rR   rX   r\   r-   r-   r-   r.   r5   e   s   
c                 C   s   | j S rK   )Z_has_symbolic_sizes_strides)elemr-   r-   r.   r1   w   s    c                 C   s:   dg}t | d d D ]}|||d   qtt |S N   )reversedappendlist)shapestridesdimr-   r-   r.   r2   z   s    c                 C   s6   t }|st|ja zg }|| |||W S |a X d S rK   )rT   AssertionErrorrS   rR   )rN   rP   rQ   moderO   r-   r-   r.   _handle_sym_dispatch   s    ri   c                 C   s.   t | tjr| j S t| tks*t| | S rK   )
isinstancerG   r   noderequire_hinttypeintrg   ar-   r-   r.   r;      s    
c                 C   s   t | tr| j S dS NT)rj   SymTypesrk   has_hintro   r-   r-   r.   rs      s    

rs   ro   c                 C   s<   t | ttfstt | tr dS t | jjtjjj	r8dS dS )z Utility to check if underlying object
    in SymInt is concrete value. Also returns
    true if integer is passed in.

    Args:
        a (SymInt or int): Object to test if it int
    TF)
rj   r   rn   rg   rk   exprsympycorenumbersIntegerro   r-   r-   r.   r4      s    
c                 C   sF   t | ttfstt | tr dS t | jjtjjj	tjjj
frBdS dS )z Utility to check if underlying object
    in SymBool is concrete value. Also returns
    true if integer is passed in.
    Args:
        a (SymBool or bool): Object to test if it bool
    TF)rj   r   boolrg   rk   rt   ru   ZlogicZboolalgZBooleanTrueZBooleanFalsero   r-   r-   r.   r?      s    
c                 C   s   t dd |  D S )Nc                 s   s   | ]}t |V  qd S rK   )rs   rB   sr-   r-   r.   	<genexpr>   s     z#tensor_has_hints.<locals>.<genexpr>)allsizetr-   r-   r.   tensor_has_hints   s    r   )valreturnc                 C   s   t | ttfr| jjjS t | tjr*| jS t | tt	t
fr@t S t | tjrpt|  t|  B t|  B S t | ttfrt }| D ]}|t|O }q|S td|  dt|  d S )Nzcannot compute free_symbols of  )rj   r   r   rk   rt   r=   ru   Exprrn   floatry   setrG   Tensorr~   stridestorage_offsettuplerc   rg   rm   )r   rr{   r-   r-   r.   r=      s&    



r   c                 C   sN   | j dkrJd| jkrJt| jd tjrJt| jd jjtjrJ| jd jjS d S )Nplaceholderr   )	opmetarj   rG   r   rk   rt   ru   Symbol)rk   r-   r-   r.   r>      s    c                 C   s   dd | j D S )Nc                 S   s$   i | ]}t |r|jd  jj|qS )r   )r>   r   rk   rt   )rB   rk   r-   r-   r.   
<dictcomp>   s    z0find_symbol_binding_fx_nodes.<locals>.<dictcomp>)nodes)graphr-   r-   r.   find_symbol_binding_fx_nodes   s    r   c                 C   s(   t | tr | j rt| S dS t| S )a+  
    Returns True only if we can tell that a is True, possibly introducing
    a guard in the process.  If a depends on some unbacked SymInt, we may
    return False even though there may exist a possible value of the SymInt
    that would cause the expression to return True.

    When is it appropriate to use definitely_true?  First, if you can use
    a higher level combinator like parallel_or/parallel_and, prefer using
    those instead, they are definitely safe (modulo short-circuiting).
    Second, it can be used if the program would behave equivalently if
    definitely_true always returned False (parallel_or/parallel_and are
    examples of this pattern, modulo short-circuiting).  Finally, it even
    be OK if the program wouldn't behave equivalently, so long as the
    change is semantics preserving.  It can be semantics preserving if
    the program errors in more cases than it did previously (but otherwise
    behaves identically), or if it changes some quantity in a way that
    doesn't matter (e.g., strides often fall in this bucket.)
    Frj   r   rk   rs   
guard_boolry   ro   r-   r-   r.   definitely_true   s
    

r   c                 C   s,   t | tr"| j rt|  S dS t|  S )aK  
    Returns True only if we can tell that a is False, possibly introducing
    a guard in the process.  If a depends on some unbacked SymInt, we may
    return False even though there may exist a possible value of the SymInt
    that would cause the expression a to be False.  See definitely_true
    for more usage guidance.
    Fr   ro   r-   r-   r.   definitely_false  s
    


r   c                  G   s   t dd | D rdS t | S )z
    Evaluate the logical OR of several arguments, avoiding guarding on
    unbacked SymInts if another argument is definitely True.
    c                 s   s   | ]}t |V  qd S rK   )r   rB   rp   r-   r-   r.   r|     s     zparallel_or.<locals>.<genexpr>T)anyrP   r-   r-   r.   parallel_or  s    r   c                  G   s   t dd | D rdS t| S )z
    Evaluate the logical FALSE of several arguments, avoiding guarding on
    unbacked SymInts if another argument is definitely False.
    c                 s   s   | ]}t |V  qd S rK   )r   r   r-   r-   r.   r|   $  s     zparallel_and.<locals>.<genexpr>F)r   r}   r   r-   r-   r.   parallel_and  s    r   c                 C   sT   t | ttfrt| S t | ttfr,t| S t | ttfrBt	| S t
d|  d S )Nzunrecognized scalar )rj   r   ry   r   r   rn   r6   r   r   r7   rg   ro   r-   r-   r.   r8   (  s    )r{   compiler_mincompiler_maxruntime_minruntime_maxc                 C   s   | j |d  }r8tt|j|t|j|| j |< nt||| j |< | j|d  }rtt|j|t|j|| j|< nt||| j|< d S rK   )	var_to_rangegetr#   builtinsmaxlowerminupperruntime_var_to_range)	shape_envr{   r   r   r   r   r   r-   r-   r.   _constrain_symbol_range2  s      r   )r   r   c                 C   s   t | ttfrtdt | ts$tt | jjtj	s<td|dkrHd}|dkrVtj
}|dkrltd| ||k r|td|dk rdn|}t| jj| jj||||d dS )	z=
    This function is NOT INTENDED to be used by itself.
    z$Constraining SymFloat/SymBool is nyiconstraining non-Symbols NYINr      zCMaximum value to constrain_as_size must be greater than 2, but was oMaximum value to constrain_as_size can't be less than the specified min value, received min={min} and max={max}r   r   r   r   )rj   r   r   
ValueErrorr   rg   rk   rt   ru   r   oor   r   )rp   r   r   r   r-   r-   r.   _constrain_range_for_sizeA  s.    r   )r   c                C   s   |dkrt j }|dkrt j}||k r.tdt| trn||   krL|ksjn td|  d| d| ddS t| jjt jr|t| jj  kr|ksn tdt| jj d| d| ddS t| jjt j	st
dt| jj| jj||||d dS )	a  
    Applies a constraint that the passed in SymInt must lie between min-max
    inclusive-inclusive, WITHOUT introducing a guard on the SymInt (meaning
    that it can be used on unbacked SymInts).  If min/max are None, we assume
    that the dimension is unbounded in that direction.  Repeated application
    of constrain_range intersects the ranges.  This is a fairly low level API
    that doesn't have a lot of safety guarantees (TODO: provide higher level
    APIs).

    Currently, we use this API in the following circumstance: when we allocate
    an unbacked SymInt, denoting an integer quantity which is data dependent,
    we ordinarily do not know anything about what values it may take.  This
    means that any sort of guard on it will immediately fail.  However, in
    many cases, we know something about the unbacked SymInt: for example, we
    know that nonzero(x).size(0) must be >= 0.  We use constrain_range to
    narrow the possible range, declaring that negative symbols are impossible.
    This permits to definitely answer True to queries like 'nnz >= 0', even if
    we don't know what the actual (hinted) value of 'nnz' is.  In fact, we
    actually use constrain_range to unsoundly discharge common guards: for an
    unbacked SymInt produced by nonzero, we will also assume that it is not
    equal to 0/1 (even though these are perfectly possible values at runtime),
    because we generally expect graphs that are valid for N=2 to also be valid
    for N=1.

    .. warning::
        If you use constrain_range in the context of tracing, we do NOT check
        that the constraint was actually valid at runtime!  In fact, we
        cannot (easily) do so, as we currently unsoundly assume that unbacked
        SymInt can never be zero/one, even if it may actually take on these
        values at runtime (we assume that a graph that is valid for N=2 will
        also be valid for N=1).
    Nr   zInvalid value z for range [:]r   r   )ru   r   r   rj   rn   rk   rt   rx   r$   r   rg   r   r   )rp   r   r   r-   r-   r.   constrain_rangeg  s2    !
$r   c                 C   s   t | tsXt |ts"| |ksVtqt |jjtjs:td|jj}t| |j	|jj< nt | jjtjsptd| jj}t |tst||j	| jj< nH| jj|jjkstt |jjtjstd|
| jj}||j	|jj< dS )z
    Given two SymInts, constrain them so that they must be equal.  NB:
    this will not work with SymInts that represent nontrivial expressions
    (yet!)
    r   N)rj   r   rg   rk   rt   ru   r   r   rx   replacements_find)rp   br   new_varr-   r-   r.   constrain_unify  s    


r   skipc                 C   sV   t | tr>t }t|d D ]
}|j}q| j|jj	|j
S t| tksRt| | S Nr_   )rj   r   r@   currentframerangef_backrk   expect_truef_codeco_filenamef_linenorm   ry   rg   )rp   r   frame_r-   r-   r.   r     s    
r   c                 C   s0   t | tr| jddS t| tks,t| | S N r   )rj   r   rk   r   rm   ry   rg   ro   r-   r-   r.   r     s    
r   c                 C   s0   t | tr| jddS t| tks,t| | S r   )rj   r   rk   r6   rm   rn   rg   ro   r-   r-   r.   r6     s    
c                 C   s.   t | tr| jddS t | ts*t| | S r   )rj   r   rk   r7   r   rg   ro   r-   r-   r.   r7     s    
c                 C   s   t | dr|  S t| S )N__sym_sqrt__)rU   r   mathsqrtro   r-   r-   r.   sym_sqrt  s    
r   c                 C   sZ   t |tr|jS t|tkr&| |S t|tkr<| |S t|tkrR| 	|S t
S d S rK   )rj   rr   rk   rm   ry   	wrap_boolrn   wrap_intr   
wrap_floatNotImplementedrM   numr-   r-   r.   to_node
  s    



r   c                 C   s   dd | j jD S )Nc                 S   s    g | ]}|j d kr|jd qS )r   r   )r   r   rB   nr-   r-   r.   
<listcomp>  s     
 z'fx_placeholder_vals.<locals>.<listcomp>r   r   gmr-   r-   r.   fx_placeholder_vals  s    r   c                 C   s   dd | j jD S )Nc                 S   s   g | ]}|j d kr|jqS )r   )r   targetr   r-   r-   r.   r     s     
 z*fx_placeholder_targets.<locals>.<listcomp>r   r   r-   r-   r.   fx_placeholder_targets  s    r   Tignore_staticc                G   s   | j jt| ||dS )Nr   )r   evaluate_guards_for_argsr   )r   r   rP   r-   r-   r.   eval_guards"  s    r   c                 G   s   | j t| |S rK   )r   bind_symbolsr   )r   rP   r-   r-   r.   r   %  s    r   rt   boundc                 C   sd   |j js0|j js0|j jr0| tjs0t|| f|jjs`|jjs`|jjr`| tjs`t|| fdS )a8  
    We assert that the bounds are either Boolean, or not finite, or can be computed
    in exact prevision via rational arithmetic.
    The only exception to this is the rare case when the user calls `sqrt(s0)`
    sqrt is turned into sympy.Pow so we just match for that (it matches more things, but still)
    N)	r   Zis_rationalZ
is_Boolean	is_finitehasru   Powrg   r   r   r-   r-   r.   _assert_bound_is_rational(  s    0r   c                   @   s   e Zd ZdZdZdZdZdS )
DimDynamican  
    Controls how to perform symbol allocation for a dimension.  It is always
    sound to default this to DYNAMIC, but the policies DUCK and STATIC can
    result in better trace-time and compile-time performance, as they reduce
    the number of allocated symbols and generally make your graph more static.

    NB: If we notice you've applied a constraint to the dimension, we will
    force it to DYNAMIC for simplicity.

    DimDynamic is controlled by a variety of higher level UX features.
    Currently:

    - In eager mode, the default policy is DUCK.
        - The default is changed to STATIC with assume_static_by_default.
        - An individual dim is marked DYNAMIC if you mark_dynamic_dim.
    - In export mode, the default policy is STATIC.
        - An individual dim is marked DYNAMIC if you mention it as dynamic_dim
          in the constraints kwarg.
    r   r_   r   N)r*   r+   r,   __doc__DYNAMICDUCKSTATICr-   r-   r-   r.   r   2  s   r   frozenc                   @   s   e Zd ZU eed< dS )
Constraint	warn_onlyN)r*   r+   r,   ry   __annotations__r-   r-   r-   r.   r   ^  s   
r   c                   @   s(   e Zd ZU dZeed< edddZdS )StrictMinMaxConstrainta-  
    For clients: the size at this dimension must be within 'vr' (which
    specifies a lower and upper bound, inclusive-inclusive) AND it
    must be non-negative and should not be 0 or 1 (but see NB below).

    For backends: there must not be any guards on this dimension which
    are not implied by the given lower and upper bound.  Regardless of
    the lower bound, the backend can assume the size is non-negative
    and that it is not 0 or 1.

    An unbounded StrictMinMaxConstraint can be thought of as a strict version
    of "RelaxedUnspecConstraint".

    NB: Export will often unsoundly assume that a graph works for 0/1, even
    though at trace time we assumed size is not 0 or 1.  The idea is that
    if we produce a graph that works for a range of values, it will be OK
    for N=0/1 too.
    vrsourcec                 C   s    | j j d|  d| j j S )N <= )r   r   namer   rM   r   r-   r-   r.   renderx  s    zStrictMinMaxConstraint.renderN)r*   r+   r,   r   r#   r   r   r   r-   r-   r-   r.   r   b  s   
r   c                   @   s   e Zd ZdZedddZdS )RelaxedUnspecConstrainta  
    For clients: no explicit constraint; constraint is whatever is implicitly
    inferred by guards from tracing.

    For backends: there must exist at least TWO possible values for the
    size at this dimension which satisfy the guards for this dimension.

    In other words, this constraint helps us distinguish between "we don't
    care if this dimension specializes or not" versus "this dimension must be
    unspecialized."  However, this constraint doesn't say very much about what
    specialization is permitted; for example, if we guard on a size being
    even, this would still be acceptable under an unspec constraint.  This
    makes RelaxedUnspecConstraint useful for eager mode, where your backend compiler
    may add constraints to otherwise dynamic dimensions; we can't assert that
    there are NO guards as this is brittle because compilers should be able to
    add extra constraints.  If you want to assert that there are no guards,
    use StrictMinMaxConstraint with an unbounded ValueRanges.
    r   c                 C   s   d|   dS )NzRelaxedUnspecConstraint()r   r   r-   r-   r.   r     s    zRelaxedUnspecConstraint.renderN)r*   r+   r,   r   r   r   r-   r-   r-   r.   r   |  s   r   c                   @   sN   e Zd ZU dZeeeef  ed< dd Zdd Z	dd Z
d	d
 Zdd ZdS )EqualityConstraintz
    Given pairs of sources corresponding to pairs of dynamic dimensions that
    are specified equal, represent them in a union-find data structure so that
    we can efficiently check whether two such sources are transitively equal.
    source_pairsc                 C   s:   t | di  | jD ] \}}| | || | qd S )N_parents)object__setattr__r   _unionr   rM   source1source2r-   r-   r.   __post_init__  s    z EqualityConstraint.__post_init__c                 C   s"   || j kr| | j | S |S d S rK   )r   r   r   r-   r-   r.   r     s    
zEqualityConstraint._findc                 C   s   ||kr|| j |< d S rK   )r   )rM   Zroot1root2r-   r-   r.   r    s    zEqualityConstraint._unionc                 C   s"   d dd | jD }d| d S )N, c                 s   s(   | ] \}}|   d |   V  qdS ) == Nr   )rB   r  r  r-   r-   r.   r|     s   z,EqualityConstraint.render.<locals>.<genexpr>{})joinr   )rM   bufr-   r-   r.   r     s    
zEqualityConstraint.renderc                 C   s   |  ||  |kS rK   r   r  r-   r-   r.   is_equal  s    zEqualityConstraint.is_equalN)r*   r+   r,   r   r   r   r   r   r  r   r  r   r  r-   r-   r-   r.   r     s   
r   c                   @   s  e Zd ZdZdyeeeef  dddZe	dd Z
dd	 Ze	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 Zdd Zd d! Zd"d# Zd$d% Zd d&d'd(Zd d&d)d*Zd d&d+d,Zd d&d-d.Zd d&d/d0Zd d&d1d2Zd d&d3d4Z d d&d5d6Z!d d&d7d8Z"d d&d9d:Z#d d&d;d<Z$d d&d=d>Z%d d&d?d@Z&d d&dAdBZ'd d&dCdDZ(d d&dEdFZ)d d&dGdHZ*d d&dIdJZ+d d&dKdLZ,d d&dMdNZ-d d&dOdPZ.d d&dQdRZ/d d&dSdTZ0d d&dUdVZ1d d&dWdXZ2d d&dYdZZ3d d&d[d\Z4d d&d]d^Z5d d&d_d`Z6d d&dadbZ7d d&dcddZ8d d&dedfZ9dgdh Z:didj Z;dkdl Z<dmdn Z=dodp Z>dqdr Z?dsdt Z@dudv ZAdwdx ZBdS )zSymNodez
    This is a type erased SymInt/SymFloat which we use to do actual operations.
    End users don't touch this.  Magic methods are NOT defined on this object.
    Nhintc                 C   s`   || _ || _|| _|d kr:| j|j| _d | _|   nd | _|| _|| _	t
 rV|nd | _d S rK   )_exprr   pytypert   xreplace
var_to_val
_hint_expr_hint_update_hintconstant_translation_validation_enabledfx_node)rM   rt   r   r  r  r  r  r-   r-   r.   __init__  s    
zSymNode.__init__c                 C   s   | j | jS rK   )r   replacer  rM   r-   r-   r.   rt     s    zSymNode.exprc                 C   sH   | j j| jj krD| j| j }|jr2|| _ d S | || _d | _ d S rK   )r  r=   r   r   keysr  r  r  )rM   Znew_hintr-   r-   r.   r    s    zSymNode._update_hintc                 C   s   | j d kr|   | j S rK   )r  r  r   r-   r-   r.   r    s    
zSymNode.hintc                 C   s
   | j d k	S rK   )r  r   r-   r-   r.   rs     s    zSymNode.has_hintc                 C   sB   | j d kr8|   | j d kr0| j| j| jq>| j S n| j S d S rK   )r  r  r   _make_data_dependent_errorr  rt   r   r-   r-   r.   rl     s    

zSymNode.require_hintc                 C   s   | j jrd S t| j S d S rK   )rt   r=   rn   r   r-   r-   r.   maybe_as_int  s    zSymNode.maybe_as_intc                 C   s
   | j tkS rK   )r  rn   r   r-   r-   r.   is_int  s    zSymNode.is_intc                 C   s
   | j tkS rK   )r  r   r   r-   r-   r.   is_float  s    zSymNode.is_floatc                 C   s
   | j tkS rK   )r  ry   r   r-   r-   r.   is_bool  s    zSymNode.is_boolc                 C   s,   t |tksttt|| jt|||dS N)r  r  )rm   rn   rg   r  ru   rx   r   r   r-   r-   r.   r     s    zSymNode.wrap_intc                 C   s,   t |tksttt|| jt|||dS r'  )rm   r   rg   r  ru   Floatr   r   r-   r-   r.   r     s    zSymNode.wrap_floatc                 C   s2   t |tkstt|rtjntj| jt|||dS r'  )rm   ry   rg   r  ru   truefalser   r   r-   r-   r.   r   #  s    zSymNode.wrap_boolc                 C   s   | S rK   r-   r   r-   r-   r.   clone'  s    zSymNode.clonec                 C   s   | j  S rK   rt   r   r-   r-   r.   str*  s    zSymNode.strc                 C   s   |   S rK   r-  r   r-   r-   r.   __str__-  s    zSymNode.__str__c                 C   s   |   S rK   r.  r   r-   r-   r.   __repr__0  s    zSymNode.__repr__r   c                 C   s
   |  |S rK   )_addrM   otherr-   r-   r.   add5  s    zSymNode.addc                 C   s
   |  |S rK   )_subr2  r-   r-   r.   sub8  s    zSymNode.subc                 C   s
   |  |S rK   )_mulr2  r-   r-   r.   mul;  s    zSymNode.mulc                 C   s
   |  |S rK   )_modr2  r-   r-   r.   mod>  s    zSymNode.modc                 C   s
   |  |S rK   )Z_powr2  r-   r-   r.   powA  s    zSymNode.powc                 C   s
   |  |S rK   )Z_and_r2  r-   r-   r.   and_D  s    zSymNode.and_c                 C   s
   |  |S rK   )Z_or_r2  r-   r-   r.   or_G  s    zSymNode.or_c                 C   s
   |  |S rK   )Z_truedivr2  r-   r-   r.   truedivJ  s    zSymNode.truedivc                 C   s
   |  |S rK   )	_floordivr2  r-   r-   r.   floordivM  s    zSymNode.floordivc                 C   s
   |  |S rK   )Z_lshiftr2  r-   r-   r.   lshiftP  s    zSymNode.lshiftc                 C   s
   |  |S rK   )Z_rshiftr2  r-   r-   r.   rshiftS  s    zSymNode.rshiftc                 C   s   |   S rK   )Z_sym_notr   r-   r-   r.   r   V  s    zSymNode.sym_notc                 C   s
   |  |S rK   )_eqr2  r-   r-   r.   eqY  s    z
SymNode.eqc                 C   s
   |  |S rK   )Z_ner2  r-   r-   r.   ne\  s    z
SymNode.nec                 C   s
   |  |S rK   )Z_gtr2  r-   r-   r.   gt_  s    z
SymNode.gtc                 C   s
   |  |S rK   )Z_ltr2  r-   r-   r.   ltb  s    z
SymNode.ltc                 C   s
   |  |S rK   )Z_ler2  r-   r-   r.   lee  s    z
SymNode.lec                 C   s
   |  |S rK   )Z_ger2  r-   r-   r.   geh  s    z
SymNode.gec                 C   s   |   S rK   )Z_floorr   r-   r-   r.   floork  s    zSymNode.floorc                 C   s   |   S rK   )Z
_sym_floatr   r-   r-   r.   r   n  s    zSymNode.sym_floatc                 C   s   |   S rK   )Z_sym_intr   r-   r-   r.   sym_intq  s    zSymNode.sym_intc                 C   s   |   S rK   )_ceilr   r-   r-   r.   ceilt  s    zSymNode.ceilc                 C   s   |   S rK   )Z_negr   r-   r-   r.   negw  s    zSymNode.negc                 C   s
   |  |S rK   )Z_sym_minr2  r-   r-   r.   r   z  s    zSymNode.sym_minc                 C   s
   |  |S rK   )Z_sym_maxr2  r-   r-   r.   r   }  s    zSymNode.sym_maxc                 C   s   |   S rK   )Z	_sym_sqrtr   r-   r-   r.   r     s    zSymNode.sym_sqrtc                 C   s   |  ||S rK   )Z_is_contiguousrM   sizesre   r-   r-   r.   is_contiguous  s    zSymNode.is_contiguousc                 C   s   |  ||S rK   )Z_is_channels_last_contiguous_2drO  r-   r-   r.   is_channels_last_contiguous_2d  s    z&SymNode.is_channels_last_contiguous_2dc                 C   s   |  ||S rK   )Z_is_channels_last_contiguous_3drO  r-   r-   r.   is_channels_last_contiguous_3d  s    z&SymNode.is_channels_last_contiguous_3dc                 C   s   |  ||S rK   )Z_is_channels_last_strides_2drO  r-   r-   r.   is_channels_last_strides_2d  s    z#SymNode.is_channels_last_strides_2dc                 C   s   |  ||S rK   )Z_is_channels_last_strides_3drO  r-   r-   r.   is_channels_last_strides_3d  s    z#SymNode.is_channels_last_strides_3dc                 C   s   |  ||S rK   )Z'_is_non_overlapping_and_dense_indicatorrO  r-   r-   r.   &is_non_overlapping_and_dense_indicator  s    z.SymNode.is_non_overlapping_and_dense_indicatorc                 C   s
   |  |S rK   )r=  r2  r-   r-   r.   sym_or  s    zSymNode.sym_orc                 C   s
   |  |S rK   )r<  r2  r-   r-   r.   sym_and  s    zSymNode.sym_andc                 C   s   |  ||t| dS r   )rV  rD  r   rO  r-   r-   r.   is_non_overlapping_and_dense  s    z$SymNode.is_non_overlapping_and_densec                 C   s   |  ddS r   )r6   r   r-   r-   r.   int_  s    zSymNode.int_c                 C   sJ   | j j| j| j| jd}z
t|W S  tk
rD   td|  Y nX d S )Nr  zFailed to convert to int: %s)	r   evaluate_exprrt   r  r  rn   	ExceptionlogwarningrM   fileliner   r-   r-   r.   r6     s    
zSymNode.guard_intc                 C   sJ   | j j| j| j| jd}z
t|W S  tk
rD   td|  Y nX d S )Nr[  zFailed to convert to float: %s)	r   r\  rt   r  r  r   r]  r^  r_  r`  r-   r-   r.   r7     s    
zSymNode.guard_floatc                 C   sJ   | j j| j| j| jd}z
t|W S  tk
rD   td|  Y nX d S )Nr[  zFailed to convert to bool: %s)	r   r\  rt   r  r  ry   r]  r^  r_  r`  r-   r-   r.   r     s    
zSymNode.guard_boolc                 C   s4   |   r| ||S | jj| j| d| | jdS )Nr   r[  )rs   r   r   defer_runtime_assertrt   r  )rM   ra  rb  r-   r-   r.   r     s    zSymNode.expect_truec                 C   s   |  ddS r   )r   r   r-   r-   r.   bool_  s    zSymNode.bool_)NN)Cr*   r+   r,   r   r   r   rn   r   r  propertyrt   r  r  rs   rl   r#  r$  r%  r&  r   r   r   r+  r-  r/  r0  r4  r6  r8  r:  r;  r<  r=  r>  r@  rA  rB  r   rD  rE  rF  rG  rH  rI  rJ  r   rK  rM  rN  r   r   r   rQ  rR  rS  rT  rU  rV  rW  rX  rY  rZ  r6   r7   r   r   rd  r-   r-   r-   r.   r    sz   %






r  c                   @   s   e Zd Zedd ZdS )r   c                 C   s:   |j rtdS |j r.|dk r.t| dn|| S d S )Nr_   r   z% cannot be raised to a negative power)is_zeroru   rx   ZeroDivisionError)clsbaseexpr-   r-   r.   eval  s
    
zPow.evalNr*   r+   r,   classmethodrk  r-   r-   r-   r.   r     s   r   c                   @   s   e Zd Zedd ZdS )TrueDivc                 C   s   |j rtdn|| S d S )Nzdivision by zero)rf  rg  )rh  ri  divisorr-   r-   r.   rk    s    
zTrueDiv.evalNrl  r-   r-   r-   r.   rn    s   rn  c                   @   s   e Zd ZdZedd ZdS )!IsNonOverlappingAndDenseIndicatorTc                 G   sl   t |d dkstt |d }tdd |D rh|d| }||d  }tdd |D dd |D S d S )Nr   r   c                 s   s   | ]}t |tjV  qd S rK   )rj   ru   rx   r   r-   r-   r.   r|     s     z9IsNonOverlappingAndDenseIndicator.eval.<locals>.<genexpr>c                 S   s   g | ]}t |qS r-   rn   r   r-   r-   r.   r     s     z:IsNonOverlappingAndDenseIndicator.eval.<locals>.<listcomp>c                 S   s   g | ]}t |qS r-   rq  r   r-   r-   r.   r     s     )lenrg   r}   !eval_is_non_overlapping_and_dense)rh  rP   rf   Z	size_argsZstride_argsr-   r-   r.   rk    s    z&IsNonOverlappingAndDenseIndicator.evalN)r*   r+   r,   
is_integerrm  rk  r-   r-   r-   r.   rp    s   rp     c                 C   sF   t | dr>zt| W S  tk
r:   td|  |  Y S X n| S d S )Nexpandz"RecursionError in sympy.expand(%s))rU   ru   rv  RecursionErrorr^  r_  )r   r-   r-   r.   safe_expand  s    
rx  c                 C   s   | | S rK   r-   rp   r   r-   r-   r.   <lambda>      rz  c                 C   s   | | S rK   r-   ry  r-   r-   r.   rz    r{  c                 C   s   | | S rK   r-   ry  r-   r-   r.   rz    r{  c                 C   s
   t | |S rK   )r   ry  r-   r-   r.   rz    r{  c                 C   s
   t | |S rK   )r   ry  r-   r-   r.   rz    r{  c                 C   s   t | |S rK   )ru   Andry  r-   r-   r.   rz    r{  c                 C   s   t | |S rK   )ru   Orry  r-   r-   r.   rz    r{  c                 C   s
   t | |S rK   )rn  ry  r-   r-   r.   rz    r{  c                 C   s
   t | |S rK   )r   ry  r-   r-   r.   rz    r{  c                 C   s
   t | |S rK   )r   ry  r-   r-   r.   rz    r{  c                 C   s
   t | |S rK   )r   ry  r-   r-   r.   rz    r{  )r4  r6  r8  r:  r;  andorr>  r@  rA  rB  c                   C   s   t dd S )Nzshouldn't be hit)rg   r-   r-   r-   r.   error  s    r  c                 C   s   t | tjr^| j}t|dkr^t |d tjr^|d jr^t|d }|d |kr^||d  S t | tjrx| t| kst | tjrt| S || S Nr   r   r_   )rj   ru   ZMulrP   rr  r(  rt  rx   )rp   fnZaaZcoefr-   r-   r.   floor_ceil_helper!  s    &&
r  c                 C   s   t | tjS rK   )r  ru   rJ  ro   r-   r-   r.   
floor_impl,  s    r  c                 C   s   t | tjS rK   )r  ru   ceilingro   r-   r-   r.   	ceil_impl/  s    r  c                 C   s   |  S rK   r-   ro   r-   r-   r.   rz  5  r{  c                 C   s   t | |S rK   )ru   Eqry  r-   r-   r.   rz  6  r{  c                 C   s   t | |S rK   )ru   Nery  r-   r-   r.   rz  7  r{  c                 C   s   t | |S rK   )ru   Gtry  r-   r-   r.   rz  8  r{  c                 C   s   t | |S rK   )ru   Ltry  r-   r-   r.   rz  9  r{  c                 C   s   t | |S rK   )ru   Lery  r-   r-   r.   rz  :  r{  c                 C   s   t | |S rK   )ru   Gery  r-   r-   r.   rz  ;  r{  c                 C   s   | S rK   r-   ro   r-   r-   r.   rz  =  r{  c                 C   s   |  S rK   r-   ro   r-   r-   r.   rz  ?  r{  c                 C   s   t | |S rK   )ru   Minry  r-   r-   r.   rz  @  r{  c                 C   s   t | |S rK   )ru   Maxry  r-   r-   r.   rz  A  r{  c                 C   s
   t | S rK   )ru   r   ro   r-   r-   r.   rz  B  r{  )r   rD  rE  rF  rG  rH  rI  rJ  r   rM  rN  r   r   r   c                 C   s
   t | |S rK   )sympy_is_contiguousrP  re   r-   r-   r.   rz  H  r{  c                 C   s
   t | |S rK   )$sympy_is_channels_last_contiguous_2dr  r-   r-   r.   rz  I  r{  c                 C   s
   t | |S rK   )$sympy_is_channels_last_contiguous_3dr  r-   r-   r.   rz  J  r{  c                 C   s
   t | |S rK   )!sympy_is_channels_last_strides_2dr  r-   r-   r.   rz  K  r{  c                 C   s
   t | |S rK   )!sympy_is_channels_last_strides_3dr  r-   r-   r.   rz  L  r{  c                 C   s   t | | S rK   )rp  r  r-   r-   r.   rz  M  r{  )rQ  rR  rS  rT  rU  rV  )r   r   c                 C   s   t | }t ||krtjS tj}td}|D ]:}|t| | tdt|| |B M }|| | 9 }q.t|D ]}|t| | tdO }qr|S )Nr_   r   )rr  ru   r*  r)  rx   r  r   )rP  re   	dim_orderrf   rQ  zdr-   r-   r.   sympy_is_contiguous_genericU  s    
*r  c                 C   s$   t | }t| |tt|d ddS r^   )rr  r  rc   r   )rP  re   rf   r-   r-   r.   r  f  s    r  c                 C   s   t | |ddddgS Nr_      r   r   r  r  r-   r-   r.   r  m  s    r  c                 C   s   t | |dddddgS Nr_      r  r   r   r  r  r-   r-   r.   r  p  s    r  c                 C   s   t | }|t |krtjS td}tj}|t|d dM }|D ]X}|t| | d|| |k@ M }|dkr|t||d M }|| t| | d }qB|S )Nr   r_   )rr  ru   r*  rx   r)  r  r  )rP  re   r  rf   rC   r   r  r-   r-   r.   &sympy_is_channels_last_strides_generics  s    
 	r  c                 C   s   t | |ddddgS r  r  r  r-   r-   r.   r    s    r  c                 C   s   t | |dddddgS r  r  r  r-   r-   r.   r    s    r  c                 C   s   t tt| |S rK   )rn   r   "_eval_is_non_overlapping_and_denser  r-   r-   r.   rs    s    rs  c                 C   sv   t | }|dkr(|d dkp&| d dk S tt| |tdd}d}|D ](\}}|dkrZqH||krh dS ||9 }qHdS )Nr_   r   r   keyFT)rr  sortedzipoperator
itemgetter)rP  re   rf   Zlengths_and_stridesZexpected_stridelengthr   r-   r-   r.   r    s     
r  r   rM  rJ  rN  r   r~  r  r   r   c                 C   sT   | t kr|  d}n| }| tkr2ttjjj|}n| tkrFtt|}n
tt	|}|S )Nr   )
2magic_methods_on_operator_with_trailing_underscoremagic_methods_on_submodulegetattrrG   fxZexperimentalZsymbolic_shapesmagic_methods_on_mathr   r  )methodmethod_attrr   r-   r-   r.   r:     s    
)r  r  r  r  r  r  r  r  r   r   rn  rp  rJ  r  r>  r;  rD  rE  rF  rG  rH  rI  rY  c                 C   s\   t | tr| jd k	r| jS |  r*t| S |  r:t| S |  rJt| S t	d|  d S )Nzunrecognized return type )
rj   r  r  r$  r   r%  r   r&  r   rg   xr-   r-   r.   r9     s    c                    sr   t d  tkr  d}n} fdd} fdd}tkr\ttd| | nttd| | d S )Nru  r   c           	   	      s@  t }d }| jd k	r.|jd k	r.|| j|j}t}|r\|d k	r\t| |t| t|S tr~t| t|t| t|fi S t|t	st
z | j|j}W n* tk
r   td| j|j  Y nX t|}tkrt}n2tkrt}n$| jtks|jtkrt}n| j}| j|| j|jf\}}t	|| j|||dS )Nfailed to eval %s(%s, %s)r[  )r:   r   alternate_impl_if_hinted_methodsr   r   r9   rT   ri   rj   r  rg   rt   r]  r^  r_  rx  always_float_magic_methodsr   always_bool_magic_methodsry   r  r   create_fx_call_functionr  )	rM   r3  r   out_hintZalternate_imploutr  r  r   rN   r  r-   r.   binary_magic_impl  s2    
	z+_make_node_magic.<locals>.binary_magic_implc                    s   t }tr$t| t|t| fi S | j}dks:dkrF| j|}z |}W n$ tk
rv   t	
d|  Y nX d }| jd k	r|| j}t|}tkrt}ntkrt}n| j}| j|| jf\}}t|| j|||dS )NrJ  r  zfailed to eval %s(%s)r[  )r:   rT   r   ri   r9   rt   r   _simplify_floor_divr]  r^  r_  r  rx  always_int_magic_methodsrn   r  r   r  r  r  r  )rM   r   rt   r  r  r  r  r   r  r-   r.   unary_magic_impl/  s,    

z*_make_node_magic.<locals>.unary_magic_impl)r   r  unary_magic_methodssetattrr  )r  rN   r  r  r  r-   r  r.   _make_node_magic  s    +r  c                    sT    fdd}t td |  fdd}ttjt sPt tjt | d S )Nc              	      s  t tjt }tr>t| t|dd |D dd |D fi S dd |D }dd |D }z ||}W n& tk
r   t	d||  Y nX g }d }|D ]}	|	j
d kr q||	j
 qg }
|D ]}	|	j
d kr q|
|	j
 q|||
}drt}nt}t|| j||S )Nc                 S   s   g | ]}t |qS r-   )r9   rz   r-   r-   r.   r   \  s     zH_make_node_sizes_strides.<locals>.sizes_strides_impl.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r-   r,  rz   r-   r-   r.   r   `  s     c                 S   s   g | ]
}|j qS r-   r,  rz   r-   r-   r.   r   a  s     r  Z
_indicator)r  rE   rF   r*   rT   r   ri   r]  r^  r_  r  rb   endswithrn   ry   r  r   )rM   rP  re   r   Z
size_exprsZstride_exprsr  Z
size_hintsr  r{   Zstride_hintsr  r  r-   r.   sizes_strides_implU  sB    



z4_make_node_sizes_strides.<locals>.sizes_strides_implr   c                    s   t | |D ]D t trtt j fdd| D  fdd|D   S qdkrdt| |S tdd | D dd |D S d S )Nc                    s   g | ]}t  j|qS r-   r   rk   rB   r   ro   r-   r.   r     s     zH_make_node_sizes_strides.<locals>.sizes_strides_user.<locals>.<listcomp>c                    s   g | ]}t  j|qS r-   r  r  ro   r-   r.   r     s     rV  c                 S   s   g | ]}t |qS r-   ru   sympifyr   r-   r-   r.   r     s     c                 S   s   g | ]}t |qS r-   r  r   r-   r-   r.   r     s     )		itertoolschainrj   r   r9   r  rk   rs  ry   r  r  ro   r.   sizes_strides_user  s    

z4_make_node_sizes_strides.<locals>.sizes_strides_user)r  r  rU   rE   rF   r*   )r  rN   r  r  r-   r  r.   _make_node_sizes_stridesR  s
    +r  c                    s   | t kr|  d n|   fdd} fdd} fdd}| tkrZt|d|  d| n0t|d|  d| | tkrt|d	|  d| d S )
Nr   c                    s   t t| j  S rK   )r9   r  rk   r   r  r-   r.   r    s    z*_make_user_magic.<locals>.unary_magic_implc                    s,   t | j|}|tkrtS tt| j |S rK   r   rk   r   r9   r  rM   r3  Z
other_noder  r-   r.   r    s    z+_make_user_magic.<locals>.binary_magic_implc                    s,   t | j|}|tkrtS tt| | jS rK   r  r  r  r-   r.   rbinary_magic_impl  s    z,_make_user_magic.<locals>.rbinary_magic_impl____r)r  r  r  reflectable_magic_methods)r  Z	user_typer  r  r  r-   r  r.   _make_user_magic  s    r  c                  C   s   ddl m}  |  S )Nr   translation_validation_enabled)torch.fx.experimental.validatorr  r  r-   r-   r.   r    s    r  c                    s<   t ||  dt|  fdd} j|_ j|_|S )z
    Wrapper around lru_cache that clears when new info about shapes has been
    updated.

    Use lru_cache if the output is always the same, regardless of the
    constraints we know now (i.e. evaluate_expr)

    Use _lru_cache otherwise.
    Nc                    s,   |   kr|       | f||S rK   )_get_keycache_clear)rM   rP   rQ   Zfn_cacheZ	prior_keyr-   r.   wrapper  s    z_lru_cache.<locals>.wrapper)r   	functoolswrapsr  
cache_info)r  maxsizer  r-   r  r.   
_lru_cache  s    
r  c                   @   s<   e Zd ZU ejed< eddZeed< eddZ	eed< dS )RuntimeAssertrt   F)reprmsgstackN)
r*   r+   r,   ru   r   r   r   r  r-  r  r-   r-   r-   r.   r    s   

r  c                       s*   e Zd Z fddZedddZ  ZS )ShapeGuardPrinterc                    s    t    || _|| _|| _d S rK   )superr  symbol_to_source
source_refvar_to_sources)rM   r  r  r  	__class__r-   r.   r    s    
zShapeGuardPrinter.__init__r   c                    st   t |tjsttt| fdd} j|s`t| ddd  j| D  d|  d 	 j| d S )	Nc                      s   t dd  j D S )Nc                 S   s    i | ]\}}|d d |D qS )c                 S   s   g | ]}|  qS r-   r   rz   r-   r-   r.   r     s     z]ShapeGuardPrinter._print_Symbol.<locals>.repr_symbol_to_source.<locals>.<dictcomp>.<listcomp>r-   )rB   symbolsourcesr-   r-   r.   r     s    zRShapeGuardPrinter._print_Symbol.<locals>.repr_symbol_to_source.<locals>.<dictcomp>)r  r  itemsr-   r   r-   r.   repr_symbol_to_source  s    z>ShapeGuardPrinter._print_Symbol.<locals>.repr_symbol_to_sourcez (could be from c                 S   s   g | ]}|  qS r-   r   rz   r-   r-   r.   r   	  s     z3ShapeGuardPrinter._print_Symbol.<locals>.<listcomp>z	) not in zu.  If this assert is failing, it could be due to the issue described in https://github.com/pytorch/pytorch/pull/90665r   )
rj   ru   r   rg   r-  rm   r  r   r  r  )rM   rt   r  r-   r   r.   _print_Symbol  s    &zShapeGuardPrinter._print_Symbol)r*   r+   r,   r  r-  r  __classcell__r-   r-   r  r.   r    s   r  c                       s   e Zd Z fddZ  ZS )LoggingShapeGuardPrinterc                    s   t  |dd | d S )Nc                 S   s   |   S rK   r   r   r-   r-   r.   rz    r{  z3LoggingShapeGuardPrinter.__init__.<locals>.<lambda>)r  r  )rM   r  r  r-   r.   r    s    z!LoggingShapeGuardPrinter.__init__)r*   r+   r,   r  r  r-   r-   r  r.   r    s   r  c                       sD   e Zd ZdZ fddZedddZedddZd	d
 Z  Z	S )DynamicDimConstraintPrinterz
    Printer for dynamic dim constraints.
    - Instead of t.size()[d] it prints dynamic_dim(t, d)
    - Instead of Eq(_, _), Mod(_, _), etc. it prints _ == _, _ % _, etc.

    We use this to suggest code for specifying dynamic dim constraints.
    c                    s   t    || _d S rK   )r  r  r  )rM   r  r  r-   r.   r    s    
z$DynamicDimConstraintPrinter.__init__r   c                 C   s   d|j   d|j dS )Nzdynamic_dim(r	  r   )ri  r   idxr   r-   r-   r.   print_source!  s    z(DynamicDimConstraintPrinter.print_sourcec                 C   s0   t |tjsttt|| | j| d S Nr   )rj   ru   r   rg   r-  rm   r  r  rM   rt   r-   r-   r.   r  $  s    z)DynamicDimConstraintPrinter._print_Symbolc              	   C   s,   d | |jt||j| |jt|S )Nz{} {} {})formatZparenthesizelhsr0   Zrel_oprhsr  r-   r-   r.   _print_Relational)  s
    z-DynamicDimConstraintPrinter._print_Relational)
r*   r+   r,   r   r  r-  r  r  r  r  r-   r-   r  r.   r    s
   r  c                   @   s   e Zd ZdZdd Zdd ZedddZd	d
 Zdd Z	dd Z
dd Zdd ZdddZdd Zdd ZejdddZdS )DimConstraintsz
    Custom solver for a system of constraints on symbolic dimensions.
    Solutions are "static" values or simplified "dynamic" constraints.
    c                 C   s`   t t| _t | _i | _|| _t t| _t | _g | _t | _	t | _
t|| _g | _|| _d S rK   )r   r   _univariate_inequalities_symbols_with_equalities_substitutions_var_to_val_congruences_multivariate_inequalities_symbolic_equivalences_static_results_dynamic_resultsr  _dcp_inconsistencies_marked_dynamic)rM   r  r  Zmarked_dynamicr-   r-   r.   r  7  s    


zDimConstraints.__init__c                    sL    fdd} fdd}| tr2|t|}| trH|t|}|S )aA  
        Eliminate expressions of the form b // d and b % d while adding congruences of the form b % d == k.
        This leaves rational operators (in particular of the form b / d) that our inequality solver can handle.
        We solve the added congruences separately (using our congruence solver, see below).
        c                     sb   | \}}  |  | }}|j|j }|| | }|dkr^j  | |S r  rewrite_with_congruencessubsr  r  r4  rP   ri  ro  Zmod_reduced
congruencer{   rM   r-   r.   mod_handlerg  s    z<DimConstraints.rewrite_with_congruences.<locals>.mod_handlerc                     sj   | \}}  |  | }}|j|j }|| | }|dkr^j  | || | S r  r  r
  r  r-   r.   floor_div_handler  s    zBDimConstraints.rewrite_with_congruences.<locals>.floor_div_handler)r   r   r  r   )rM   r{   rt   r  r  r-   r  r.   r  a  s     

z'DimConstraints.rewrite_with_congruencesr   c                 C   s   |t jkrdS |}|| j}|t jkr:| j| d |j}|sRtd| t	|dkrl| j
| n|tt|}| ||}|t jkrdS || j}|t jkr| j| d| d t|t jr| j| | j| | dS )NTz is inconsistent!z2Did not expect constraint with no free variables: r_   z, obtained by rewriting z# with congruences, is inconsistent!F)ru   r)  r	  r  r*  r  rb   r=   rg   rr  r   r4  nextiterr  rj   r  r  r  )rM   rt   	orig_exprZorig_reducedr=   r{   Zreducedr-   r-   r.   r4    s.    



zDimConstraints.addc                 C   s6   |j r| j||f n| j|  d|  d S )Nr
  )r=   r  rb   r  r4  r   )rM   r   rt   r-   r-   r.   add_equality  s    zDimConstraints.add_equalityc                    s&  i }| j  D ]\}}g }t }|D ]}|j\}}tjddd}	tj|||	  |gd\}
}||
krtjj	||	\}}t
|tjrt
|tjr|| }|||f q&|| q&|rtjjj| \}}|| | h||< ||tjddd | i ||  fdd|D  q|||< q|S )NtmpTinteger)symbolsc                 3   s   | ]}t | s|V  qd S rK   )ru   checksol)rB   r  Zsubstitutionr-   r.   r|     s   z4DimConstraints.reduce_congruences.<locals>.<genexpr>)r  r  r   rP   ru   r   Zsolve_linearZpolysZ	polytoolsdivrj   rx   rb   r4  ZntheoryZmodularZsolve_congruenceupdate)rM   reduced_congruencesr{   congruencesZremainder_modulus_pairsZcongruences_to_checkr  ri  ro  r  r  solutionmodulus	remainderr-   r  r.   reduce_congruences  s0    


z!DimConstraints.reduce_congruencesc                 C   s.   | j r*d| j }| j   td| d S )N
z*The following inconsistencies were found:
)r  r  clearr   )rM   r  r-   r-   r.   raise_inconsistencies  s    
z$DimConstraints.raise_inconsistenciesc                 C   s>   | j | }| j| jj| d   d|  || j|< d S )Nr   r
  )r  r  r4  r  r  r   r  )rM   r{   r   r-   r-   r.   _force_specialization  s    
&z$DimConstraints._force_specializationc                    s    j D ]6}|ttD ]$}|j\}}|jD ]} | q*qq j }t  _ |D ]} |	 j
 qP    fdd j D  _ fdd j D  _d S )Nc                    s    i | ]\}}| j kr||qS r-   r  )rB   r{   exprsr   r-   r.   r   
  s   
 z=DimConstraints.specialize_divisor_symbols.<locals>.<dictcomp>c                    s    i | ]\}}| j kr||qS r-   r%  )rB   r{   r  r   r-   r.   r     s   
 )r   atomsr   r   rP   r=   r$  r   r4  r	  r  r#  r  r  r  )rM   rt   atomr   ro  r{   multivariate_inequalitiesr-   r   r.   specialize_divisor_symbols  s     




z)DimConstraints.specialize_divisor_symbolsTc                    s  |    | jr| j }| j|}tjj||}t|tj	rXt
dd |jD |}t|tjsxtd| d| |j\}}||kstd| d| | j| jj| d   d|  || j|< | j}t | _|D ]}	| |	|| j|  q|    q|   |  }
|
 D ]v\}}|D ]f}|| jksTt||| j| is,|rt| | | j|d  n| j| jt|d q,q | j D ]\}}zZtjj||}t|tj	r|jD ]}| j| j| qn| j| j| W nP tk
rT } z0t d	| |D ]}	| j| j|	 q(W 5 d }~X Y nX q| j!}g | _!|D ]l\}}	|rt|	tj"s|	j#D ]2}| | | j$|  fd
d| jD | _q| %||	| j qj| j!D ]0\}}	| j| j&| d| j|	  qd S )Nc                 s   s   | ]}t |tjr|V  qd S rK   )rj   ru   r  )rB   argr-   r-   r.   r|     s      z'DimConstraints.solve.<locals>.<genexpr>z$Expected an equality constraint for z, got zExpected a constraint on z instead of on r   r
  z!Failed to reduce inequalities: %sc                    s   h | ]} |kr|qS r-   r-   rB   r   sexprr-   r.   rD   T  s      z'DimConstraints.solve.<locals>.<setcomp>)'r#  r  popr  ru   ZsolversZinequalitiesZreduce_inequalitiesrj   r|  r  rP   r  rg   r  r4  r  r  r   r  r   r   r	  r*  r   r  r  r$  r  doprintrL   r^  r_  r  r   r=   r  r  r  )rM   Zdisable_congruencesZdisable_equivalencesr{   r&  r  r  r   r)  rt   r  r  r  r+  eZsymbolic_equivalencesr   r-   r-  r.   solve  s`    
 
&

$
$
.

zDimConstraints.solvec                    s   d  fdd j D S )Nr!  c                    s<   g | ]4\}}| j krd  jj| d   d| dqS )	r   z3, which was marked dynamic, must be specialized to .)r  r  r  r   )rB   r{   r   r   r-   r.   r   ]  s   
z9DimConstraints.forced_specializations.<locals>.<listcomp>)r  r  r  r   r-   r   r.   forced_specializations\  s    z%DimConstraints.forced_specializationsc                 C   s~   g }t  }| jD ]0}tdd|}||kr6|| q|| q|D ],}d}|D ]}||krRd}qR|sF|| qF|| _d S )Nz2 <= dynamic_dim(.+)zdynamic_dim\1FT)r   r  rer6  rb   r4  )rM   Zcandidates_for_removalZdynamic_resultsdcZdc_foundZother_dcr-   r-   r.    remove_redundant_dynamic_resultsf  s    
z/DimConstraints.remove_redundant_dynamic_results)original_signaturec                    s  dd fdd}|j tjjd}i }t|j D ]\}}||f||< q6 fdd}d d	}| jr|| j|}	 d
7   dt| d7  ||	|dd   d7  | j	r|| j	|}
 d7   d7   dt| d7   d| d7  ||
|d dd   d| d7   S )Nc                 S   s8   t d| }|d krd S |d}t dd| } || fS )NzL\['(.+?)'\]z\1)r6  searchrv  r6  )r7  matchr+  r-   r-   r.   extract_and_rewrite_local  s    
zBDimConstraints.prettify_results.<locals>.extract_and_rewrite_localc           
         s   t t}| D ]<} |}|d kr"q|\}}||kr|||  | qqqg }t| D ]"\}}|\}	}||t|f qZ|S rK   )r   rc   rb   r  r  )
results
args_indexgroupsr7  localr+  Zsorted_groupsr  Zdcsr   )r=  r-   r.   group  s    z.DimConstraints.prettify_results.<locals>.group)return_annotationc                    s^   d}| D ]P\}}|r d7  nd} d| d| d7  |D ]} d| || 7  q<qd S )NFr!  Tz# r   r-   )groupedindentZ	result_fnspacer+  r>  result)r  r-   r.   print_results  s    
z6DimConstraints.prettify_results.<locals>.print_resultsr   z    zF
The following dimensions have been specialized and CANNOT be dynamic.z
```
def specializationsr   c                 S   s
   d|  S )Nzassert r-   rG  r-   r-   r.   rz    r{  z1DimConstraints.prettify_results.<locals>.<lambda>z
```
z)
The following dimensions CAN be dynamic.zL
Please use the following code to specify the constraints they must satisfy:z
```
def specify_constraintsr!  zreturn [r   c                 S   s
   |  dS )N,r-   rI  r-   r-   r.   rz    r{  z]
```
)
r  r@   	Signatureempty	enumerate
parametersr!  r  r-  r  )rM   r:  rB  	signaturer?  ir+  rH  rE  Zgrouped_static_resultsZgrouped_dynamic_resultsr-   )r  r=  r.   prettify_results|  s@    zDimConstraints.prettify_resultsN)TT)r*   r+   r,   r   r  r  ry   r4  r  r   r#  r$  r*  r2  r5  r9  r@   rK  rQ  r-   r-   r-   r.   r  1  s   *;&)
G
r  c                	   @   s  e Zd ZdddddddddZdd Zeeej d	d
dZ	eje
ddddZddddZddddZddddZeeeeejj ef dddZeje
eejj dddZeejj ddddZdd Zed d! Zd"d# Zejeee ee e ej! d$d%d&Z"ee# eee e e e ej! d'd(d)Z$ddd*ejeeee  eee  d+d,d-Z%dd.d/ee# ee d0d1d2Z&d3d4 Z'd/d5d6d7Z(d8d9 Z)d:d; Z*d<d= Z+ej,dfe#eeed/d>d?d@Z-ej,ddfe#eeeee d/dAdBdCZ.dDdE Z/dFdG fdddddHee0e1eeee  f   ee2eeef   e e3 dIdJdKZ4ddLdMdNZ5dOdP Z6dQdR Z7ddSdTZ8dUdV Z9e:dddWd/eedXdYdZd[Z;e:d/d/d\d]d^Z<e:d_d` Z=e:d/d/d\dadbZ>e?dcd/dddedfZ@e?dcd/dddgdhZAdidj ZBdkd/ddldmdnZCe:dkd/dodpdqZDe?dce1dr eddsdtduZEeFddvdwZGeFddxdyZHe:dzd{ ZId|d} ZJe3d~ddZKe?dcdd/dddZLdd ZMdd/dddZNeOddddZPdS )r3   TFN)allow_scalar_outputsallow_dynamic_output_shape_opsassume_static_by_defaultspecialize_zero_one
duck_shape	co_fieldsc                C   s   || _ || _g | _i | _i | _i | _i | _i | _i | _i | _	t
 | _i | _|rftdtdd| _t | _t | _tt| _d| _|| _|| _|| _t| _| jd d| _d | _t | _ |r|ni | _!i | _"i | _#t$ rddl%m&} | | _'t(j)* | _+| j+,| j+-d  d S )Nr   r_   r   r_   Z
create_envF)TranslationValidator).rR  rS  guardsr  r   r   r  var_to_stackvar_to_guardsr   r   	divisible
val_to_varru   rx   r  countunbacked_symfloat_counterunbacked_symint_countercollectionsr   rc   deferred_runtime_assertsnum_deferred_runtime_assertsrT  rU  rV  r^  infor   dim_constraintsCountercounterrW  fx_node_cachesource_to_symbolr  r  rY  	validatorrG   r  ZGraphr   Zinserting_beforeoutput)rM   rR  rS  rT  rU  rV  rW  rY  r-   r-   r.   r    sD    


zShapeEnv.__init__c                 C   s
   d| _ d S rq   r   r   r-   r-   r.   freezeM  s    zShapeEnv.freeze)r   r   c                 C   s:   t  s
d S | }|| jkr0tj|dd| j|< | j| S )NTr  )r  r   rj  ru   r   )rM   r   srcnamer-   r-   r.   _create_symbol_for_sourceP  s    
z"ShapeEnv._create_symbol_for_source)r  rm   r   c                 C   s   t  r| j|| d S rK   )r  rk  Zadd_var)rM   r  rm   r-   r-   r.   
_add_z3varX  s    zShapeEnv._add_z3varr   c                 C   s   t  r| j| d S rK   )r  rk  Zadd_target_exprr  r-   r-   r.   _add_target_expr\  s    zShapeEnv._add_target_exprc                 C   s   t  r| j| d S rK   )r  rk  Zadd_assertionr  r-   r-   r.   _add_assertion`  s    zShapeEnv._add_assertionc                 C   s   t  r| j  d S rK   )r  rk  validater   r-   r-   r.   _check_translation_validated  s    z$ShapeEnv._check_translation_validate)r   rP   r   c                 C   s   ||f}d}t  r|| jkrddlm} tdd |D rXtdd |D sPtd |fS d}tdd |D std	|j d
| ||| j}| j	
||| j|< | j|d |fS )NFr   )z3opc                 s   s   | ]}|d kV  qd S rK   r-   r   r-   r-   r.   r|   v  s     z3ShapeEnv.create_fx_call_function.<locals>.<genexpr>c                 s   s   | ]}t |tjj V  qd S rK   )rj   rG   r  Noder   r-   r-   r.   r|   y  s     Tc                 s   s   | ]}|d k	V  qd S rK   r-   r   r-   r-   r.   r|     s     zmissing arg in FX graph (z): )r  ri  r  ru  r   r}   rg   r*   rk  r   Zcall_functionr   )rM   r   rP   node_keyfreshru  Z	lifted_opr-   r-   r.   r  h  s    (z ShapeEnv.create_fx_call_functionc              	   C   sr   t  s
d S | jj|ff}|| jkrh| || tddtdd|j}| j|}||jd< || j|< | j| S )Nz[^a-zA-Z0-9]r   z[()]r   r  )	r  r   r   ri  rp  r6  r6  r   r   )rM   r  rm   rw  Zmangled_namerk   r-   r-   r.   create_fx_placeholder_and_z3var  s    


z(ShapeEnv.create_fx_placeholder_and_z3var)rk   r   c                 C   s   t  r|d k	r| j| d S rK   )r  r   Z
erase_node)rM   rk   r-   r-   r.   remove_fx_node  s    zShapeEnv.remove_fx_nodec                 C   s   t tddS )Nsuppress_guardsF)r  TLSr   r-   r-   r.   _suppress_guards_tls  s    zShapeEnv._suppress_guards_tlsc                 c   s   dt _z
d V  W 5 dt _X d S )NTF)r|  r{  r   r-   r-   r.   r{    s    
zShapeEnv.suppress_guardsc                 C   s   t | jt | j| jfS )z
        Defines the current "state" of the guards we've accumulated in this ShapeEnv.
        Determines when we need to invalidate our cache
        )rr  r   r]  rd  r   r-   r-   r.   r    s    zShapeEnv._get_key)exr   dynamic_dimsconstraint_dimsr   c                 C   s   |  t| |||S rK   )!_produce_dyn_sizes_from_int_tupler   r~   )rM   r~  r   r  r  r-   r-   r.   _produce_dyn_sizes  s    zShapeEnv._produce_dyn_sizes)tensor_sizer   r  r  r   c           
   
   C   sr   t dd |D s td| ddlm}m} g }t|D ]0\}}	|| |	|||j||| ||  q<|S )Nc                 s   s   | ]}t |tV  qd S rK   )rj   rn   )rB   r   r-   r-   r.   r|     s     z=ShapeEnv._produce_dyn_sizes_from_int_tuple.<locals>.<genexpr>z0Expect size to be a plain tuple of ints but got r   TensorPropertySourceTensorProperty)	r}   rg   torch._dynamo.sourcer  r  rM  rb   create_symbolSIZE)
rM   r  r   r  r  r  r  r~   rP  r   r-   r-   r.   r    s        z*ShapeEnv._produce_dyn_sizes_from_int_tuple)r  r  )r~  r   r  r  c             
      s$  t dfddtfdd| D tfdd| D | }| }|dkrldg| }|dkrg }t|D ]4}t||rtj	}nj
rtj}ntj}|| qtjg| }tdd |D rtjntj}	t||kstt||kstd	d
lmm  ||dgt tD ]"\}}
|
dkr8t|
|< q8tdd D rhfddttD }tfddttD }|D ]V\}}| dkr| |kr||  |< | |  || |  < qtdd D r\tfddttD \}
}j|
 j||	dd|< q\tdd D st fddttD }g }tD ]<\}}|dk	st|j||  j|d qjj| j|	dd| jd}|||fS )z
        Returns a list of symbolic sizes and strides for the given tensor.
        We try our best to express stride in terms of the sizes, so as to not
        introduce new symbolic variables.
        r   c                    s@   t | ttjfstt | tr<| jj k	s2td| j S | S )NzFexpect the symbol is created from an shape env other than current one.)rj   rn   rG   r   rg   rk   r   rl   )Z	maybe_symr   r-   r.   "maybe_specialize_sym_int_with_hint  s    

zaShapeEnv.create_symbolic_sizes_strides_storage_offset.<locals>.maybe_specialize_sym_int_with_hintc                 3   s   | ]} |V  qd S rK   r-   )rB   szr  r-   r.   r|   	  s     zHShapeEnv.create_symbolic_sizes_strides_storage_offset.<locals>.<genexpr>c                 3   s   | ]} |V  qd S rK   r-   )rB   sdr  r-   r.   r|   	  s     Nc                 s   s   | ]}|t jkV  qd S rK   )r   r   r,  r-   r-   r.   r|   "	  s     r   r  rX  c                 s   s   | ]}|d kV  qd S rK   r-   rB   r  r-   r-   r.   r|   -	  s     c                    sB   i | ]:}| d k	r| dkr | |  | |  qS r  r-   rB   rP  )ex_size	ex_strider~   r   r-   r.   r   .	  s
     zIShapeEnv.create_symbolic_sizes_strides_storage_offset.<locals>.<dictcomp>c                    s$   g | ]}| d kr | |fqS rK   r-   r  r  r   r-   r.   r   5	  s      zIShapeEnv.create_symbolic_sizes_strides_storage_offset.<locals>.<listcomp>c                 s   s   | ]}|d kV  qd S rK   r-   r  r-   r-   r.   r|   <	  s     c                    s$   g | ]}| d kr | |fqS rK   r-   r  r  r-   r.   r   ?	  s   )dynamic_dimconstraint_dimc                 s   s   | ]}|d k	V  qd S rK   r-   r  r-   r-   r.   r|   K	  s     c              	      s.   g | ]&\}\}}j || j|d qS )r  r   )create_symintnoder  )rB   rP  symr  )r  r  rM   r   r-   r.   r   M	  s   
r  ) rn   r   r~   r   r   rf   r   _is_dim_dynamicr   r   rT  r   r   rb   r}   rr  rg   r  r  r  r  rM  ru   rx   r   r  r   r  STRIDEr  r  STORAGE_OFFSET)rM   r~  r   r  r  Zex_storage_offsetrf   rP  r   Zdynamic_strides_offsetr   
candidatesZval_listr   Z	sym_sizesZ
sym_strideZstride_exprZsym_storage_offsetr-   )	r  r  r  r  r  rM   r~   r   r   r.   ,create_symbolic_sizes_strides_storage_offset  s    1



$
  
 
z5ShapeEnv.create_symbolic_sizes_strides_storage_offsetr   z
sympy.Expr)r  r  r   c                C   s   t  rD|d k	rD| |}|d k	s$t| |t}| t|| nd }t|tj	rt|d k	rlt||ksltt|S t
t|| t||dS )Nr[  )r  ro  rg   ry  rn   rr  ru   r  rj   rx   r   r  )rM   r  r  r   r  r  r-   r-   r.   r  d	  s    
zShapeEnv.create_symintnodec                 C   s   | j | j|||d||dS )N)r   r  r  )r  create_unspecified_symbol)rM   valuer   r  r-   r-   r.   $create_unspecified_symint_and_symbol~	  s    z-ShapeEnv.create_unspecified_symint_and_symbol)r  c                 C   s   t t|| td S rK   )r   r  ry   )rM   r  r-   r-   r.   create_symboolnode	  s    zShapeEnv.create_symboolnodec                 C   sj   t dt| j }| jd  d7  < tjdd| j|< t	 | j
|< | |t}tt|| td |dS )Nfcreate_unbacked_symbolr_   r   r[  )ru   r   r  r`  rh  r&   extractr[  r#   unknownr   ry  r   r   r  rM   r  r  r-   r-   r.   create_unbacked_symfloat	  s    z!ShapeEnv.create_unbacked_symfloatc                 C   sn   t jdt| j dd}| jd  d7  < tjdd| j|< |  | j	|< | 
|t}tt|| td |dS )NrP  Tr  r  r_   r   r[  )ru   r   r  ra  rh  r&   r  r[   _default_unspecified_value_ranger   ry  rn   r   r  r  r-   r-   r.   create_unbacked_symint	  s    zShapeEnv.create_unbacked_symintc                 C   sx   t jdt| j dd}| jd  d7  < tjdd| j|< tdd| j	|< | 
|t}ttt |d| td |dS )	NrP  Tr  r  r_   r   r   r[  )ru   r   r  ra  rh  r&   r  r[  r#   r   ry  ry   r   r  r  r  r-   r-   r.   create_unbacked_symbool	  s    z ShapeEnv.create_unbacked_symbool)r   r   r  r  r   c                 C   s   | j ||||d dS )N)positive)r  )rM   r   r   r  r  r-   r-   r.   r  	  s    	z"ShapeEnv.create_unspecified_symbol)r   r   r  r  r  r   c           
      C   s  t |ts tt| d| |r:|dk r:td| |d k	rHtj}|tjkr\t|S |tj	krn| j
}n|tjkr~d}ntd| |dkr| jr| j| }n<|r|| jkrtjdt| j |dd	}| jd
|||  | jd  d7  < t|| j|< g | j|< | |t |r2|| j|< |rV| |dk |  | j|< n|  | j|< t |tr|rzt| j|  |jM  < | j| }	||	krt| d|	j d|	j d|}n| j| }| j d||  t |tjr| j| !| |S )Nr   r   z!positive set for negative value: Fzunhandled dynamic_dim rX  r{   Tr  r  zcreate_symbol %s = %s for %sr  r_   z not in range [r	  r   zcreate_symbol %s duck sized %s)"rj   r   rg   rm   r   r   r   ru   rx   r   rV  rU  r^  r   rr  r  r^  re  r   rh  r  rp  rn   rr  _default_value_ranger   r  r   r   rJ   r   r   debugrb   )
rM   r   r   r  r  r  duckr   Z
sympy_exprr   r-   r-   r.   r  	  sL     









zShapeEnv.create_symbolc                 C   s   t |tr|jj|jj }}|  }||jkr2d }||jkr@d }|  d}|d k	r~|d k	r~|d| d|  d| 7 }nR|d kr|d k	r|d|  d| 7 }n(|d k	r|d kr|d| d|  7 }|S ||S )Nz in the specified ranger   r   )rj   r   r   r   r   r  r   r   )rM   r   cr   r   defaultZc_renderr-   r-   r.   %render_range_for_constraint_violation
  s     


 z.ShapeEnv.render_range_for_constraint_violationc                 C   s   |   S rK   r   r  r-   r-   r.   rz  -
  r{  zShapeEnv.<lambda>)constraint_inputsequalities_inputs_simplifiedr   )r  r  r   c          %   
      sd  	j d t|t|ks t|d kr8dd |D }nt|t|ksLttt||D ]j\}\}	}
t|	tjr|
d krd g|		  ||< qt|
|		 kstqZt|	t
tfstt|
trZtqZddlmmm  g ttttg d$fdd	fdd	d% 	
fd
d	}t|||D ]\}	}}
t|trbddlm} ||}t|tsrt|	d krq8t|	t
tfr|||	 q8t|	tjstt|	 D ](\}}|j|}||||
|  qt|	 D ]\}}||j|| q||j|	  q8g t	jt 	_ |sĈD ]n\}}t! r|" }|	j#kr	$t%&	j#| | t|t%j'r(|r|| d krqR|rt|rt|j)dkr	j *d
| d|  qR|r	j +|| t,
	j-.|}/
| d|  t|t%j'rR|krRt|rR|j0jkrR|rR|1|| d sRd|2  d
| d| d}|j3| qRt t4d d	
fdd}	j5D ]$}	6|j7d k	rq|| q	j89 D ]6\}}|kr8q"|D ]}|d k	r<|| q<q"|s9 D ]F\}}	j:(|}|d kr	j;| }|st|j<st	j8(|d\}}g }|j=t%j> kr|d krt?fdd|D r	j @t%A||j= |/t|j= |/
|d  |jBt%j>kr|jBtCjDd k r|d krt?fdd|D r	j @t%E||jB |/t|jB t|dkrh/dF| qhrfg }g }D ]Z\}}|rdt|d  d|  }|/| n$dt|d  d|  }|/| qt|dkrHdF|}tGd| nt|dkrft *dt| tHd d	jI	jJttKd!d L D d" t! rXdd#lMmN}  	jOL D ]}!|!D ]}"	$|"j7 qq	j;9 D ]P\}#}$|$j=t%j> kr	$t%E|$j=|# |$jBt%j>kr	$t%E|#|$jB qtPQ  | 	jR	jST  W 5 Q R X 	U  S )&Nproduce_guardsc                 S   s*   g | ]"}t |tjr"d g|  nd qS rK   )rj   rG   r   rf   rB   r   r-   r-   r.   r   ?
  s    z+ShapeEnv.produce_guards.<locals>.<listcomp>r   )r  r  NegateSourcec                    s    |  fddf d S )Nc                      s    r    S S rK   r-   r-   r  r  r-   r.   rz  
  r{  zNShapeEnv.produce_guards.<locals>.record_constraint_violation.<locals>.<lambda>)rb   )r   r  r  )constraint_violationsr  r.   record_constraint_violation
  s    z<ShapeEnv.produce_guards.<locals>.record_constraint_violationc                    s   t | o| j jkS rK   )rj   propr  )src)r  r  r-   r.   is_dim
  s    z'ShapeEnv.produce_guards.<locals>.is_dimc           	         s  t |tr"|j d k	r"|j }t |tr*|jj}t |tjrh| |  |d k	rf| | nt | tjr|   |  nd}t |trd}n*t |t	r|j
rd}nt|}|dkrd}|rfdd}| |}d| d|   d}|j|t||d	 | |f nt|}| |f d}t |trXd}nt |t	rr|dkrrd}|r| |}d| d|   d
| d}|j| d S )NFTrX  c                    s   t  j| }| dS )NzI. For more information about this inference, run with TORCH_LOGS=dynamic.)r  r  r0  )r{   r.  )rM   r  r  r-   r.   r  
  s    z;ShapeEnv.produce_guards.<locals>.track_symint.<locals>.hintNot all values of z are valid because z was inferred to be equal to r  z  was inferred to be a constant (zN). For more information about why it is constant, run with TORCH_LOGS=dynamic.)rj   r   rk   r#  rt   ru   r   rb   r   r   r=   rn   r  r   r   r  partialrx   )	r   r   
constraintr{   Zconstraint_violatedrP  r  var_with_ranger  )r  input_guardsr  rM   r  symbol_to_constraintsr  r-   r.   track_symint
  sV    





z-ShapeEnv.produce_guards.<locals>.track_symintLocalSourcezSkipping guard %sr
  z The specified set of equalities z( is not sufficient; please also specify r4  guardr   c           
   
      sD   | j}| jkrd S | zd}tfdd|jD rPj|}tj|} 	| 
| t|jdkr
|s
t|jd }| d }| }|D ]T}t|tr||}d| d| d}	|j|	 qt|trqtd	| qW n2 tk
r>   jd
d| j   Y nX d S )NFc                 3   s$   | ]}| D ]} |V  qqd S rK   r-   )rB   r{   r   )r  r  r-   r.   r|   F  s     
  z?ShapeEnv.produce_guards.<locals>.issue_guard.<locals>.<genexpr>r_   r   r  z satisfy the generated guard zW. For more information about why this guard was generated, run with TORCH_LOGS=dynamic.zunrecognized constraint zFailing guard allocated at: 
%sr   )simplifyrt   r4  r   r=   rf  r  r  r0  rb   rq  rr  rc   rj   r   r  r   r   rg   r]  r^  r_  r  r  r  )
r  rt   Z
is_trivialZ
guard_exprr  r   constraintsr  r  r  )r&  r  issuedr  rM   r  r  r  r-   r.   issue_guard;  s6    





z,ShapeEnv.produce_guards.<locals>.issue_guardNNc                 3   s   | ]} |V  qd S rK   r-   rB   r   r  r-   r.   r|     s     z*ShapeEnv.produce_guards.<locals>.<genexpr>r_   c                 3   s   | ]} |V  qd S rK   r-   r  r  r-   r.   r|     s     r   z  z. r!  zConstraints violated!
z$%s Warning only constraints violateddynamicc                 s   s   | ]}|rd V  qdS r_   Nr-   )rB   vr-   r-   r.   r|     s      )Z
num_guardsr=   )PopulateValidator)N)N)Vr^  re  rr  rg   rM  r  rj   rG   r   rf   r   rn   rc   r  r  r  r  rb  r   r-  r  r   r~   r  r   r  r  r   r  r  r   r!  rf  r  r   rj  rq  ru   r  r   r   r=   r  r  r  r  r0  rb   r  r  r   r   r   rZ  _maybe_evaluate_staticrt   r\  r  r   r   rt  r   r   r   r4  r  r   rE   r  r  r  rJ   r'   rW  rh  sumvaluesr  r  rc  fx_tracebackZpreserve_node_metar   rk  runrt  )%rM   placeholdersr  r  r  r  r  r   rP  r   r  r  r   r  ssZproperty_sourcert   rn  r.  r  r  r  r  rZ  r   Zg_lowerZg_upperZboundsZ	warn_msgsZ
error_msgsr   errr  rasrar  r   r-   )r  r  r  r  r&  r  r  r  r  rM   r  r  r  r.   r  )
  s,   =

D






		"-





*

zShapeEnv.produce_guardsr   c                   sl   ddl m  dd tt|D }| j| fdd|D |d}|rhd|}t|tdtt	||iS d	S )
Nr   r  c                 S   s   g | ]}d | qS r   r-   r  r-   r-   r.   r     s     z5ShapeEnv.evaluate_guards_for_args.<locals>.<listcomp>c                    s   g | ]} |qS r-   r-   r   r  r-   r.   r     s     r   z and LT)
r  r  r   rr  r  r  rk  r<   dictr  )rM   r  rP   r   	arg_namesrZ  coder-   r  r.   r     s    
z!ShapeEnv.evaluate_guards_for_argsc                    s   i   fdd}t ||D ]\}}|d kr,qt|trB||| qt|tjsRtt| D ]\}}|||| q^t| D ]\}}|||| q||	 |	  q S )Nc                    s   t |tr|jj}t |tjrT| krJ | | ksRt |  d|  q|  |< nPt | tjr|  kr |  |  kst |   d|   n|   | < d S )N != )rj   r   rk   rt   ru   r   rg   )r+  r   r{   Zbindingsr-   r.   bind_symint  s    
$

,z*ShapeEnv.bind_symbols.<locals>.bind_symint)
r  rj   r   rG   r   rg   rM  r~   r   r   )rM   r  rP   r  r   r+  rP  r{   r-   r  r.   r     s    

zShapeEnv.bind_symbolsc                    s    fdd j D S )Nc                    s(   g | ] }  |jd kr |jqS rK   )r  rt   r  rB   r  r   r-   r.   r     s      z2ShapeEnv.get_nontrivial_guards.<locals>.<listcomp>)rZ  r   r-   r   r.   get_nontrivial_guards
  s    zShapeEnv.get_nontrivial_guardsc                    s&   fdd d  fdd| jD S )Nc                    s&    sdS dd dd |  D  S )Nr   z
   Guarded at:
c                 s   s   | ]}d | V  qdS )z   Nr-   )rB   lr-   r-   r.   r|     s     z<ShapeEnv.format_guards.<locals>.format_tb.<locals>.<genexpr>)r  r  )tb)verboser-   r.   	format_tb  s    z)ShapeEnv.format_guards.<locals>.format_tbr!  c                 3   s$   | ]}d |j   |j V  qdS )z - N)rt   r  r  )r  r-   r.   r|     s     z)ShapeEnv.format_guards.<locals>.<genexpr>)r  rZ  )rM   r  r-   )r  r  r.   format_guards  s    zShapeEnv.format_guardsc                 C   s0   t t}| j D ]\}}|| | q|S rK   )rb  r   rc   r   r  rb   )rM   Zshape_groupskr  r-   r-   r.   get_shape_groups  s    
zShapeEnv.get_shape_groups)unbacked_onlycompute_hintzOptional[sympy.Expr])rt   r  r  r   c                C   s  |  |}t|j}|D ]b}|| jkr(qi }| j| D ]8}|rN|j| j}n|j}tj||< tj	|t
|< q6||}qi }	i }
t|D ]~\}}| j| }|jtj d d k s|r|| jkr||
|< qtjd| ddd}|jd }|| |	|< t|| |
|< qdd }z|||	}W n8 tk
rZ   td||	 | jd	  d7  < Y d
S X i }|tD ]$}t|jd |jd  ||< qjt||}tt|jdkr|S t||
}t|| |  r|jS |r|S d
S )z
        Tries to evaluate expr without introducing guards

        If unbacked_only == True, then we only do substitutions on
        unbacked SymInts (leaving regular hinted integers alone).
        r_   r   Zshape_Tr  c                 S   s
   |  |S rK   )r  )rt   replr-   r-   r.   r  V  s    z0ShapeEnv._maybe_evaluate_static.<locals>.replacez(RecursionError in sympy.xreplace(%s, %s)sympy_recursion_errorNr   )!r  rc   r=   r  rc  rt   r  ru   r)  r*  Notr	  rM  r   r   rE   r  r   r"   r4  rw  r^  r_  rh  r'  r   rJ  rP   rx  rr  r!   r   Zis_singleton)rM   rt   r  r  r  r{   Zsubstr  r1  Znew_shape_envZnew_range_envr  r  r   offsetr  new_exprZfloor_div_replacer(  r  r-   r-   r.   r    s^    






"


zShapeEnv._maybe_evaluate_static)rt   r   c                    s"    fdd|j D }t||S )Nc                    s    i | ]}|  ttj|qS r-   )r   r	   ru   r   rz   r   r-   r.   r   t  s      z$ShapeEnv.replace.<locals>.<dictcomp>)r=   rx  r  )rM   rt   r   r-   r   r.   r  r  s    zShapeEnv.replacec                 C   s>   t  }| jD ]&}| |}t|jdkr|| q|| _d S r  )r   r]  r  rr  r=   r4  )rM   Znew_divisibler  resr-   r-   r.   _update_divisiblew  s    

zShapeEnv._update_divisiblec                 C   sf  |  |}|tr|   i }|tD ]^}|j\}}t|tr*|j\}}|  t||| jkr*||kr*|  t||| jkr*|||< q*|	|}t
|}|trbi }|tj}|tj|tj}	|tD ]0}
|
j\}}|  t||| jkr|| ||
< q|	|}t
|}|tj}|tj|tj}||rb||	rb|}|S rK   )r  r   r   r  r'  rP   rj   r   r]  r  rx  ru   r   Rational
differencerx   issubset)rM   rt   Zdiv_replacementsr(  ri  ro  Zbase1Zdivisor1ZpowsZ	rationalsfdr  Znew_powsZnew_rationalsr-   r-   r.   r    s>    








zShapeEnv.simplifyru  r,  c                 C   sH   t || j}t|jdkrD| j|dd}|dk	r8|S | |||S )a  
        Gets a size hint for a given expression from the underlying shapes we had.
        Does not introduce a guard, so only use this when you can guarantee that
        your code is still valid for arbitrary shapes (such as optimization decisions)
        r   T)r  N)rx  r  r  rr  r=   r  r"  )rM   rt   result_exprr   r-   r-   r.   	size_hint  s    zShapeEnv.size_hintc                 C   s,   t || j}t|jdkp*| |d k	S r  )rx  r  r  rr  r=   r  )rM   rt   r  r-   r-   r.   rs     s    zShapeEnv.has_hintc                 C   sF   |j D ](}d| j|  }| jd|| qtd| d| dS )Nr   z-Data dependent variable '%s' allocated at:
%szIt appears that you're trying to get a value out of symbolic int/float whose value is data-dependent (and thus we do not know the true value.)  The expression we were trying to evaluate is z (unhinted: zU).  Scroll up to see where each of these data-dependent accesses originally occurred.)r=   r  r[  r  r^  r  r(   )rM   rt   Zunhinted_exprr{   Z
stacktracer-   r-   r.   r"    s    
z#ShapeEnv._make_data_dependent_errorzsympy.Symbol)rp   rt   r   c                 C   s   t jjjrbt|tjtjfrb|| jks4|| j| krb| j	
d| j| d  | | j	jddd || j|< | t|| dS )zx
        Adds or updates a replacement for a symbol.
        Use this instead of `self.replacements[a] = expr`.
        zSpecializing %s to %sr   ZSPECIALIZATIONT
stack_infoN)rG   _dynamoconfigZprint_specializationsrj   ru   rx   r(  r   r^  r_  r  r   r  rq  r  )rM   rp   rt   r-   r-   r.   _set_replacement  s    
zShapeEnv._set_replacement)rp   r   c                    sN   | j kr|S  j | } fdd|jD } | j | |  j | S )z
        Implements a DSU-like algorithm to find the variable that represents a
        Also handles transitive non-identity replacements.

        a: b + c
        c: d
        c                    s   i | ]}|  |qS r-   r  rz   r   r-   r.   r     s      z"ShapeEnv._find.<locals>.<dictcomp>)r   r=   r  r  )rM   rp   r  Zcur_replacer-   r   r.   r     s    	

zShapeEnv._find)zsympy.Eqzsympy.Ne)rt   concrete_boolr   c           
   
      s  t |tkstt|tjr&|s:dS nt|tjr:|r:dS t|j}t	|dks^td| t	|dkrndS t
| fdddd}|j}|j}|tsz|t|t}t	|dkrtd	d
 |D rtt||d dd}|dk	r6tdd
 t|d D r6 |d } ttj|d | W nR tk
rN   Y n> tk
r    jd  d7  <  jd|||d  Y nX |trt|td }	z6t||	dd}|dk	r|d dkrވ j !|	 W n tk
r   Y nX dS )z
        Evaluates the result of an eq call. If true, uses information to
        simplify shapes (i.e. a == b or a % 5 == 0)
        Nr   z3The expression should not be static by this point:    c                    s     | | jfS rK   )r  r   r  r   r-   r.   rz    r{  z*ShapeEnv._maybe_guard_eq.<locals>.<lambda>T)r  reversec                 s   s   | ]}|j d kV  qdS r  )ro  r   r-   r-   r.   r|     s     z+ShapeEnv._maybe_guard_eq.<locals>.<genexpr>F)Zfloordiv_inequalityc                 s   s   | ]}|j V  qd S rK   )rt  r  r-   r-   r.   r|     s     r_   r  z*RecursionError in sympy.solve(%s - %s, %s))"rm   ry   rg   rj   ru   r  r  rc   r=   rr  r  r  r  r   r   r'  r   unionr   rL   r    r}   Zpreorder_traversalr   r  r	   r   rw  rh  r^  r_  r   r]  r4  )
rM   rt   r  freer  r  Zfloor_div_atomsr   r   mod_exprr-   r   r.   _maybe_guard_eq  sJ    
(zShapeEnv._maybe_guard_eqc                 C   s   | j r
dnd}t|tjd S r  )rU  r#   rE   r  )rM   r   r-   r-   r.   r  &  s    zShapeEnv._default_value_rangec                 C   s   t tj d tjS r   )r#   rE   r  r   r-   r-   r.   r  *  s    z)ShapeEnv._default_unspecified_value_rangec                 C   sP   t |t}t|D ].}|j\}}t||}t|d}| | q| 	|S r  )
r   r'  r   ra   rP   r   ru   r  r\  r  )rM   rt   Z
floor_divsr  ri  ro  r  Zeq_exprr-   r-   r.   r  -  s    

zShapeEnv._simplify_floor_divc                 C   sL   | j rH| jd  d7  < tdd| j| d| dd td|| d S )	NZignored_backward_guardr_   r  Zevaluate_expr_frozenr
  r   )Zignored_guardversionz>Ignored guard %s == %s, this could result in accuracy problems)r   rh  r'   rW  r^  r_  )rM   rt   concrete_valr-   r-   r.   _check_frozen=  s    zShapeEnv._check_frozen)prefixc           	      C   s   | j tjrd }t }z<|d k	rT|jjt krLt	
|jj|j|jj}qT|j}qW 5 ~X d}t }|r|dt|d  }| j tj}d}|r|rddt	| }| j jd||t|||d d S )Nr   z at r`   zM
User Stack (most recent call last):
  (snipped, see stack below for prefix)
zeval %s [guard added]%s (%s)%sr  )r^  isEnabledForloggingINFOr@   r   r   r   rI   	tracebackFrameSummaryr   co_namer   r   extract_stackr%   DEBUGr  format_listre  )	rM   r  gZfsummaryr   Zmaybe_user_locZuser_tbZis_debugZmaybe_extra_debugr-   r-   r.   
_log_guardN  sB    zShapeEnv._log_guard)r  c                 C   s  |dkr|  |}n
t|}d}d}t r|dk	r|  s|tjkr\| tj|f\}}n^|tj	kr| t
j|f\}}| tj|f\}}n*| t
j||f\}	}| tj|	f\}}d}
d}zt|jdkr| jd| t|ttfr||kst| d| |W S |}| |}|dk	rp| jd|| t|ttfrj||ksjt| d| |W S |j| j ks| j|dd}|j| j ks| || j||}| || tjjjrt|trt|tjtjfrt |}t|tjtjfr"| !|t| n"t|tj"rD| !t||d |tjkrV|}n$|tj	krnt |}nt||}|  st#j$d	d
}t%||}
| j&'|
 W n( t(k
r   |r| )|  Y n@X |  s|
dk	st| *|
 | +d| n| jd| |S )zO
        Given an expression, evaluates it, adding guards if necessary
        NFr   zeval %s [trivial]r  z eval %s == %s [statically known]Tr  r_   r   rk  zeval %s [guard suppressed]),r  ru   r  r  r}  r)  r  rG   _assertr*  r  not_rD  rr  r=   r^  r  rj   rn   ry   rg   r  r  r!  r"  r  r  r  r   Z/inject_EVALUATE_EXPR_flip_equality_TESTING_ONLYr  r  r  r  rx   r&   r  r   rZ  rb   r]  rz  refine_rangesr  )rM   r  r  r  r
  rk   rx  rN  r   Zeqlr  r  rt   static_exprr  r  r  r-   r-   r.   r\  w  s    
	

	







zShapeEnv.evaluate_exprc                 C   sV   | j D ]}|j  q| j D ]}|  q | j D ]}|D ]}|j  q@q8d S rK   )rZ  r  cleanupr[  r  rc  )rM   r  r{   r  r  r-   r-   r.   r    s    

zShapeEnv.cleanupc           
      C   s  |}|  |}|d k	r*| jd|| |S | j |dd}|j| j krV| j||dS t r||d k	r||  s|| 	t
j|f | |tj |  stjdd}t|||}tdd |jD d	d
 d}	| j|	d  | |  jd7  _| d| n| jd| dS )Nz*runtime_assert %s == %s [statically known]Tr  r[  r_   r   c                 S   s   g | ]}|j d r|qS )rP  )r   
startswithrz   r-   r-   r.   r     s      z1ShapeEnv.defer_runtime_assert.<locals>.<listcomp>c                 S   s   t | jdd  S r   )rn   r   )r{   r-   r-   r.   rz    r{  z/ShapeEnv.defer_runtime_assert.<locals>.<lambda>r  r`   Zruntime_assertz$runtime_assert %s [guard suppressed])r  r^  r  r=   r  r!  r\  r  r}  r  rG   r  r  ru   r)  r&   r  r  r  rc  rb   rd  r  )
rM   r  r  r  rt   r  r  r  r  candsr-   r-   r.   rc    s2    
zShapeEnv.defer_runtime_assertr  c                 C   sL  |  |j}|jD ]2}t|tjs(tt||}|d ks|jr|d jsLq|\}}| j	| }|j
|j }}	t|| j	}
t||
 | j|d\}}||
j
k rt|tjtjtjfr|
j
tt|tj }|}|	|
jkrt|tjtjtjfr|
jtt|tj }	|}|t||	krqt||	| j	|< ||f| j|< | j  qd S )Nr_   r  )r  rt   r=   rj   ru   r   rg   r    rt  r   r   r   r!   r   r\  r   r  r  r  rn   r  r  r#   r  r  )rM   r  rt   r  r   Zr_exprr  r   r   r   Zrhs_vrZlower_guardZupper_guardr-   r-   r.   r  4  s.    


 $zShapeEnv.refine_ranges)F)NN)N)Qr*   r+   r,   r  rm  r   r   ru   r   ro  r   rp  rq  rr  rt  r
   r   rG   r  rv  ry   r  ry  rz  r}  r   r{  r  r   DimListr   DimConstraintr   r   r  rn   r  r  r  r  r  r  r  r  r   r  r  r  	InputListr   r   r-  r  r   r   r  r  r  r  r  r  r  r  r   r  rs   r"  r  r   r  r#   r  r  r  r  r  r\  r  rc  r   r  r-   r-   r-   r.   r3     s  { 

 

 N%

   ,	/
   V
	%5
)u;c                 C   s(   t | tsdS t| jjjdkr$dS dS )NFr   T)rj   r   rr  rk   rt   r=   r,  r-   r-   r.   _is_intf  s
    
r#  c                 C   s   t | do|| jkS )N_dynamo_dynamic_indices)rU   r$  )r   r  r-   r-   r.   r  n  s    r  )NN)r   )N)r   rb  r  r@   r  r  r   r  r6  rE   	threadingr  r   
contextlibr   dataclassesr   r   enumr   r   typingr   r	   r
   r   r   r   r   r   r   r   rG   Ztorch.fxZtorch.fx.tracebackr  r  r   r   r   r   r   r   r   Ztorch._guardsr   r   r   Ztorch.utils._sympy.functionsr   r   r   r   Ztorch.utils._sympy.solver    Ztorch.utils._sympy.value_rangesr!   r"   r#   r$   Ztorch.utils._tracebackr%   r&   Ztorch._utils_internalr'   r"  r   rr   	getLoggerr*   r^  rV   r(   ru   Zsympy.printing.strr/   Zsympy.printing.precedencer0   Z_opsZopsZaten__all__rI   rT   rJ   r5   r1   r2   ri   r;   rs   rn   r4   ry   r?   r   r   r   r=   r>   r   r   r   r   r   r8   r   r   r   r   r   r   r6   r7   r   r   r   r   r   r   r   r   r   r   r   r   r!  r   r  Functionr   rn  rp  ZIndicatorTypesrx  r  r  r  r  r  Zmagic_methodsZsizes_strides_methodsr   r   r  r  r  r  r  r  r  r  rs  r  r  Zbool_magic_methodsr  r  r  r:   rD  rE  rF  rG  rH  rI  r:  r@  r>  rJ  rM  r<   r  r  r  r9   r  r  r  r  rN   r  r  r  r  r  r  r  r  rA  r|  r3   r#  r  r-   r-   r-   r.   <module>   s  0$	


           	
	 
		
&E<

,%  
#	
VG


                 "