
    Vh                    
   d dl mZ 	 d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dlm
Z
mZ d dlmZmZmZ d dlZd dlmc mZ d dlmZmZmZmZmZmZmZmZ d dlmZ erd dlmZ  ej@                  e!      Z"ej$                  jG                  e!d      Z$g d	Z%d d
l&m'Z( d Z) G d d      Z*i dejV                  dejX                  dejZ                  dej\                  dej\                  dej^                  dej`                  dejb                  dejd                  dejf                  dejh                  dejj                  dd dejl                  dejn                  dejp                  dejr                  i d ejt                  d!ejv                  d"ejx                  d#ejz                  d$ejz                  d%ej|                  d&ej|                  d'ej~                  d(ej                  d)ej                  d*ed+ed,ed-ed.ed/ej                  d0ej                  ZCh d1ZDd2 ZEd3ZFeFD ]J  ZGd4eG ZHd5eH ZI eJe*eH eEeG              eKeeI      eCeH<   eDj[                  eH       e%j                  eH       L dhZMeDeMz  ZNh d6ZOh d7ZPdhZQeOeQz  ZRh d8ZSdd#hZTdd#d9ZUh d:ZVeFD ]  ZGd4eG ZHeVj[                  eH        h d;ZWh d<ZXd= ZYd> ZZd? Z[d@ Z\dA Z]dB Z^dC Z_dD Z`dE ZadF ZbdG Zc	 dpdHZddI ZedJ Zfedej                  ejt                  e\e]e^e_eee`efeYeZe[eaebdKZgdL ZhdM ZidN ZjdO ZkdP ZldQ ZmdR ZndS ZodT ZpdU ZqdV ZrdW ZsdX Zte	j                  e!   ZvdY ZweFD ]'  ZGdZeG Zx eweG      Zyexxey_z        ey_!         eJevexey       ) [y[G[xd[ Z{dqd\Z|d] Z}d^ Z~i egi d.ej                  dejV                  deld!emdendeodepdeqdeidejd*e}dekd"ejx                  d-erd,esd+etde{e|e~d_ZeFD ]  ZGd4eG ZH eKevdZeG       eeH<    [G[H[F[vd` Zda Zdb Zdc Zdd Zde Zdf Zdg ZeeeeeedhZej                  ej                  diZdj Zdk Zdl Zdm Zdn Zej%                         D ]  \  ZZ eee        ej%                         D ]  \  ZZ eee        do Zej%                         D ]I  \  ZZeeOv r
 eee       eeSv r
 eee       "eeQv seePv r	 eee        eee       eeUvsA eee       K [[y)r    )annotationsN)	lru_cacheupdate_wrapper)OptionalTYPE_CHECKINGUnion)	sym_floatsym_itesym_maxsym_minsym_notSymBoolSymFloatSymInt)dtrace_structured)ShapeEnvsym_node)SymNodemethod_to_operatormagic_methods)py_sym_typesc                Z    | t         u rt        S | t        u rt        S | t        u rt
        S | S N)boolr   intr   floatr   )ts    N/home/dcms/DCMS/lib/python3.12/site-packages/torch/fx/experimental/sym_node.py_to_symtyper   :   s+    DyCxEzH    c                     e Zd ZU dZdZded<   	 	 	 dY	 dZdZd[dZd\dZd]d	Z	e
d
        Ze
d        Zd Zd^dZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd_dZd`dZd`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(Z)d`d)Z*d`d*Z+d`d+Z,d`d,Z-d`d-Z.d`d.Z/d`d/Z0d`d0Z1d`d1Z2d`d2Z3d`d3Z4d`d4Z5d`d5Z6d`d6Z7d`d7Z8d`d8Z9d`d9Z:d`d:Z;d`d;Z<d`d<Z=d`d=Z>d`d>Z?d`d?Z@d`d@ZAd`dAZBd`dBZCd`dCZDdD ZEdE ZFdF ZGdG ZHdH ZId`dIZJdJ ZKdK ZLdL ZMd`dMZNdadNZOdO ZPdP ZQdQ ZRdR ZSdS ZTdT ZUdU ZVdV ZWdW ZXdX ZYy)br   z
    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.
    Fr   _optimized_summationNc                    | _         | _        | _        | _         fd}|t	        |      |u s,t	        |      t        |      u sJ d| dt	        |               j                  rC j                  j                  r- |       }	||	k(  s!J | d|	 d j                   d        |       }| _        | _	         j                  xr  j                  j                  }
|
xr | _
        y )Nc                     ddl m}   | j                        ry j                  j	                  j                  d      }|#t        |t              sj                  |      n|}|S )Nr   )has_free_unbacked_symbolsT)compute_hint)%torch.fx.experimental.symbolic_shapesr%   expr	shape_env_maybe_evaluate_static
isinstanceSymTypespytype)r%   hintselfs     r   r&   z&SymNode.__init__.<locals>.compute_hint   sZ    W )3>>88QU8VD0:40Jt{{4(PTKr    zCannot create SymNode of type z  with incompatible hint of type z != z (for ))_exprr)   r-   r"   typer   _translation_validation_enabledr(   _hintconstantfx_node)r/   r(   r)   r-   r.   r5   r6   optimized_summationr&   computed_hinttx_validation_ens   `          r   __init__zSymNode.__init__V   s    
"$7!:	 :'4:V9L+L 0(:4:,HL ~~$.."P"P !-M)BV4fTYYKqAB)  >D
;C NNMt~~MM 	 (3Gr    c                    t        | j                  || j                  | j                  | j                  | j
                        S r   )r   r1   r-   r4   r5   r6   )r/   r)   s     r   with_shape_envzSymNode.with_shape_env   s0    JJ	4;;

DMM4<<
 	
r    c                   | j                   |j                   k(  xrj | j                  |j                  k(  xrO | j                  |j                  k(  xr4 | j                  |j                  k(  xr | j                  |j                  k(  S r   )r1   r-   r4   r5   r6   r/   others     r   	_value_eqzSymNode._value_eq   sq     JJ%++% .u||+.

ekk). /. -	
r    c                    t        | j                  | j                  | j                  | j                  | j
                  f      S r   )hashr1   r-   r4   r5   r6   r/   s    r   _value_hashzSymNode._value_hash   s,    TZZdjj$--VWWr    c                L    | j                   j                  | j                        S r   )r)   replacer1   rC   s    r   r(   zSymNode.expr   s    ~~%%djj11r    c                    | j                   S r   r4   rC   s    r   r.   zSymNode.hint   s    zzr    c                    | j                   d uS r   rH   rC   s    r   has_hintzSymNode.has_hint   s    zz%%r    c                r   ddl m} | j                  |n || j                        }| j                  j                  D ci c]"  }|||v rdn| j
                  j                  |   $ }}| j                  j                  |      S | j
                  j                  | j                        S | j                  S c c}w )Nr   free_unbacked_symbolsi   )	r'   rM   r4   r(   free_symbolsr)   
var_to_valxreplace	size_hint)r/   fallbackrM   unbacked_symbolssreplacementss         r   require_hintzSymNode.require_hint   s    O::# $9#C  "YY33  q$44t$..:S:STU:VV    yy)),77>>++DII66zz s   'B4c                Z    | j                   j                  rt        | j                         S y r   )r(   	is_numberr   rC   s    r   maybe_as_intzSymNode.maybe_as_int   s     99tyy>!r    c                v    dd l }t        | j                  |j                        rt	        | j                        S y Nr   )sympyr+   r(   Floatr   r/   r\   s     r   maybe_as_floatzSymNode.maybe_as_float   s)    dii-##r    c                p    dd l }| j                  |j                  u ry| j                  |j                  u ryy )Nr   TF)r\   r(   truefalser^   s     r   maybe_as_boolzSymNode.maybe_as_bool   s.    99

"YY%++%r    c                &    | j                   t        u S r   )r-   r   rC   s    r   is_intzSymNode.is_int   s    {{c!!r    c                &    | j                   t        u S r   )r-   r   rC   s    r   is_floatzSymNode.is_float   s    {{e##r    c                &    | j                   t        u S r   )r-   r   rC   s    r   is_boolzSymNode.is_bool   s    {{d""r    c                    | j                   d uxr@ t        | j                   t              xr$ | j                   j                  j	                         S r   )r4   r+   r   nodeis_nested_intrC   s    r   rl   zSymNode.is_nested_int   sA     JJd" 04::v.0

--/	
r    c                    t        |      t        u sJ dd l}t        |j	                  |      | j
                  t        |||      S Nr   )r5   r6   )r2   r   r\   r   Integerr)   r/   numr\   s      r   wrap_intzSymNode.wrap_int  s?    CyCMM#S3PS
 	
r    c                    t        |      t        u sJ dd l}t        |j	                  |      | j
                  t        |||      S rn   )r2   r   r\   r   r]   r)   rp   s      r   
wrap_floatzSymNode.wrap_float  s?    CyE!!!KKdnneS3PS
 	
r    c                    t        |      t        u sJ dd l}t        |r|j                  n|j
                  | j                  t        |||      S rn   )r2   r   r\   r   ra   rb   r)   rp   s      r   	wrap_boolzSymNode.wrap_bool  sF    CyD   EJJ5;;NN
 	
r    c                    | S r    rC   s    r   clonezSymNode.clone%  s    r    c                    | j                    S r   )r(   rC   s    r   strzSymNode.str(  s    ))r    c                "    | j                         S r   r{   rC   s    r   __str__zSymNode.__str__+  s    xxzr    c                z   d| j                    d| j                   d| j                   g}| j                  |j	                  d| j                          | j
                  |j	                  d| j
                          | j                  |j	                  d| j                          dj                  |      dz   S )	NzSymNode(z, shape_env=z	, pytype=zhint=z	constant=zfx_node=z, r0   )r1   r)   r-   r4   appendr5   r6   join)r/   reps     r   __repr__zSymNode.__repr__.  s    tzzl,t~~.>i}U
 ::!JJtzzl+,==$JJ4==/23<<#JJ$,,01yy~##r    c                "    | j                         S r   r}   rC   s    r   _graph_reprzSymNode._graph_repr:  s    xxzr    c                "    | j                         S r   )_absrC   s    r   abszSymNode.abs@      yy{r    c                "    | j                         S r   )_posrC   s    r   poszSymNode.posC  r   r    c                $    | j                  |      S r   )_round)r/   ndigitss     r   roundzSymNode.roundF  s    {{7##r    c                "    | j                         S r   )_truncrC   s    r   trunczSymNode.truncI      {{}r    c                $    | j                  |      S r   )_addr>   s     r   addzSymNode.addL      yyr    c                $    | j                  |      S r   )_subr>   s     r   subzSymNode.subO  r   r    c                $    | j                  |      S r   )_mulr>   s     r   mulzSymNode.mulR  r   r    c                $    | j                  |      S r   )_modr>   s     r   modzSymNode.modU  r   r    c                $    | j                  |      S r   )
_float_powr>   s     r   	float_powzSymNode.float_powX  s    u%%r    c                $    | j                  |      S r   )_pow_by_naturalr>   s     r   pow_by_naturalzSymNode.pow_by_natural[  s    ##E**r    c                $    | j                  |      S r   )_and_r>   s     r   and_zSymNode.and_^  s    zz%  r    c                $    | j                  |      S r   )_or_r>   s     r   or_zSymNode.or_a  r   r    c                $    | j                  |      S r   )_float_truedivr>   s     r   float_truedivzSymNode.float_truedivd  s    ""5))r    c                $    | j                  |      S r   )_int_truedivr>   s     r   int_truedivzSymNode.int_truedivg        ''r    c                $    | j                  |      S r   )_int_floordivr>   s     r   int_floordivzSymNode.int_floordivj      !!%((r    c                $    | j                  |      S r   )_lshiftr>   s     r   lshiftzSymNode.lshiftm      ||E""r    c                $    | j                  |      S r   )_rshiftr>   s     r   rshiftzSymNode.rshiftp  r   r    c                "    | j                         S r   )_sym_notrC   s    r   r   zSymNode.sym_nots      }}r    c                $    | j                  |      S r   )_eqr>   s     r   eqz
SymNode.eqv      xxr    c                $    | j                  |      S r   )_ner>   s     r   nez
SymNode.ney  r   r    c                $    | j                  |      S r   )_gtr>   s     r   gtz
SymNode.gt|  r   r    c                $    | j                  |      S r   )_ltr>   s     r   ltz
SymNode.lt  r   r    c                $    | j                  |      S r   )_ler>   s     r   lez
SymNode.le  r   r    c                $    | j                  |      S r   )_ger>   s     r   gez
SymNode.ge  r   r    c                "    | j                         S r   )_floorrC   s    r   floorzSymNode.floor  r   r    c                "    | j                         S r   )_is_integerrC   s    r   
is_integerzSymNode.is_integer  s    !!r    c                "    | j                         S r   )
_sym_floatrC   s    r   r	   zSymNode.sym_float  s      r    c                "    | j                         S r   )_sym_intrC   s    r   sym_intzSymNode.sym_int  r   r    c                "    | j                         S r   )_ceilrC   s    r   ceilzSymNode.ceil  s    zz|r    c                "    | j                         S r   )_negrC   s    r   negzSymNode.neg  r   r    c                $    | j                  |      S r   )_sym_minr>   s     r   r   zSymNode.sym_min      }}U##r    c                $    | j                  |      S r   )_sym_maxr>   s     r   r   zSymNode.sym_max  r   r    c                &    | j                  ||      S r   )_sym_ite)r/   then_valelse_vals      r   r
   zSymNode.sym_ite  s    }}Xx00r    c                &    | j                  ||      S r   )_is_contiguousr/   sizesstridess      r   is_contiguouszSymNode.is_contiguous  s    ""5'22r    c                &    | j                  ||      S r   )_is_channels_last_contiguous_2dr   s      r   is_channels_last_contiguous_2dz&SymNode.is_channels_last_contiguous_2d      33E7CCr    c                &    | j                  ||      S r   )_is_channels_last_contiguous_3dr   s      r   is_channels_last_contiguous_3dz&SymNode.is_channels_last_contiguous_3d  r   r    c                &    | j                  ||      S r   )_is_channels_last_strides_2dr   s      r   is_channels_last_strides_2dz#SymNode.is_channels_last_strides_2d      00@@r    c                &    | j                  ||      S r   )_is_channels_last_strides_3dr   s      r   is_channels_last_strides_3dz#SymNode.is_channels_last_strides_3d  r   r    c                &    | j                  ||      S r   )'_is_non_overlapping_and_dense_indicatorr   s      r   &is_non_overlapping_and_dense_indicatorz.SymNode.is_non_overlapping_and_dense_indicator  s    ;;E7KKr    c                $    | j                  |      S r   )r   r>   s     r   sym_orzSymNode.sym_or  r   r    c                $    | j                  |      S r   )r   r>   s     r   sym_andzSymNode.sym_and  r   r    c                $    | j                  |      S r   )_bitwise_andr>   s     r   bitwise_andzSymNode.bitwise_and  r   r    c                $    | j                  |      S r   )_bitwise_orr>   s     r   
bitwise_orzSymNode.bitwise_or  s    &&r    c                $    | j                  |      S r   )r   r>   s     r   truedivzSymNode.truediv  r   r    c                $    | j                  |      S r   )r   r>   s     r   floordivzSymNode.floordiv  r   r    c                $    | j                  |      S r   )r   r>   s     r   powzSymNode.pow  s    ~~e$$r    c                X    | j                  ||      j                  t        | d            S )N   )r  r   to_noder   s      r   is_non_overlapping_and_densez$SymNode.is_non_overlapping_and_dense  s)    ::5'JMMgVZ\]N^__r    c                &    | j                  dd      S N r   )	guard_intrC   s    r   int_zSymNode.int_  s    ~~b!$$r    c           
        dd l }ddlm}m}  |       r3t	        |  |t
        j                  t        d |D              fi             S |D cg c]  }|j                   }} |j                  | }g }d }	|D ]+  }|j                   n(|j                  |j                         - t        |      }	| j                  j                  t
        j                  t        d |D              f      \  }
}t        || j                  t         |	|
      S c c}w )Nr   get_proxy_modehandle_sym_dispatchc              3  2   K   | ]  }t        |        y wr   )	wrap_node.0as     r   	<genexpr>z"SymNode.sym_sum.<locals>.<genexpr>  s     6A9Q<6s   c              3  4   K   | ]  }|j                     y wr   r6   r&  s     r   r)  z"SymNode.sym_sum.<locals>.<genexpr>  s     !:!))!:s   r+  )r\   "torch.fx.experimental.proxy_tensorr"  r#  r  torchsym_sumtupler(   Addr.   r   sumr)   _create_fx_call_functionr   r   )r/   argsr\   r"  r#  r(  exprsout
size_hintsout_hintr6   _s               r   r.  zSymNode.sym_sum  s    	

 #MM6668  "&&A&&eii
 	'Avv~aff%	'
 :H^^<<MME!:T!::<


 sDNNC7KK# 's   D
c                :    | j                   j                  | |      S r   )r)   evaluate_sym_node)r/   size_obliviouss     r   evaluatezSymNode.evaluate  s    ~~//nEEr    c                    | j                         }	 t        |      S # t        $ r t        j	                  d|        w xY w)NzFailed to convert to int: %s)r<  r   	Exceptionlogwarningr/   fileliners       r   r  zSymNode.guard_int  s>     MMO	q6M 	KK6:	   
 !>c                    | j                         }	 t        |      S # t        $ r t        j	                  d|        w xY w)NzFailed to convert to float: %s)r<  r   r>  r?  r@  rA  s       r   guard_floatzSymNode.guard_float  s>     MMO	8O 	KK8!<	rE  c                    | j                         }	 t        |      S # t        $ r t        j	                  d|        w xY w)NFailed to convert to bool: %sr<  r   r>  r?  r@  rA  s       r   
guard_boolzSymNode.guard_bool  s>     MMO	7N 	KK7;	rE  c                   ddl m} | j                         r: || j                        s(| j                  j
                  s| j                  ||      S | j                  j                  | j                  | d| | j                        S )Nr   rL   :r+  )	r'   rM   rJ   r(   r)   +prefer_deferred_runtime_asserts_over_guardsrK  defer_runtime_assertr6   )r/   rB  rC  rM   s       r   expect_truezSymNode.expect_true  st    O MMO)$))4NNNN ??4..
 ~~22II$q' 3 
 	
r    c                    ddl m} | j                  | j                  d            }|j	                  ||      }|r!| j                         s |t        |              |S )Nr   )_advise_is_size)r'   rR  r   rr   rP  rJ   r   )r/   rB  rC  rR  brD  s         r   expect_sizezSymNode.expect_size1  sJ    IGGDMM!$%MM$%
 T]]_F4L)r    c                    | j                  d      }	 t        |      S # t        $ r t        j	                  d|        w xY w)aN  
        Like guard_bool, but if we encounter unbacked symbols, if those symbols
        are size-like, we will treat them as >= 2 for the purposes of the analysis.

        This CHANGES the runtime semantics, but all size-oblivious sites have been
        audited to ensure that the runtime semantics don't change in a material way.
        Acceptable runtime semantic changes are, e.g., squeeze() no longer dropping
        an unbacked one size, or a tensor reporting as non-contiguous even if it's
        contiguous if it would have been reported contiguous due to being empty.
        T)r;  rI  rJ  rA  s       r   guard_size_obliviouszSymNode.guard_size_oblivious?  sC     MMM.	7N 	KK7;	s	   
 !A c                &    | j                  dd      S r  )rK  rC   s    r   bool_zSymNode.bool_S  s    r1%%r    c                     y)NTrx   rC   s    r   is_symboliczSymNode.is_symbolicV      r    c                     y r   rx   rC   s    r   
nested_intzSymNode.nested_intY  r[  r    c                     y)NFrx   rC   s    r   is_constantzSymNode.is_constant\  s    r    )NNF)r.   z!Optional[Union[int, float, bool]])r)   r   returnr   )r?   r   r`  r   )r`  r   r   )r`  zbuiltins.str)r`  r   )F)Z__name__
__module____qualname____doc__r"   __annotations__r:   r<   r@   rD   propertyr(   r.   rJ   rV   rY   r_   rc   re   rg   ri   rl   rr   rt   rv   ry   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	   r   r   r   r   r   r
   r   r   r   r   r  r  r  r
  r  r  r  r  r  r  r  r.  r<  r  rG  rK  rP  rT  rV  rX  rZ  r]  r_  rx   r    r   r   r   G   s    "'$& !P4
 0P4d


X 2 2  &0"$#




$$    &+! *()##"!$$13DDAAL (')(%`%#LJF
$(&r    r   r   r   r   andr  r   r   r   r   r   r   r   r   c                "    | j                         S r   )r   xs    r   <lambda>rk  n  s    ALLN r    r   r   r   r   r   r   r   orr  r   r   r   r   r   r	   r
   r   r   r   r   r   >	   r   r   r   r   r   r   r   r   r	   c                      fd}|S )Nc                ,     t        | d              S )N_sym_)getattr)r/   names    r   fnz_get_sym_node_fn.<locals>.fn  s    ,wtuTF^,..r    rx   rq  rr  s   ` r   _get_sym_node_fnrt    s    / Ir    )sqrtcoscoshsinsinhtantanhasinacosatanlog2sym_r8  >   rl  rg  r
   r   >   r   r   r   >   r   r   sym_log2r   )r  r  >   r   r	   r   r   >   r   r   r   r   >   r   r   r   r   r   r   rl  rg  r   r   r  c                     ddl m}  || |      S )Nr   )FloatTrueDiv)torch.utils._sympy.functionsr  )r(  rS  r  s      r   _sympy_float_truedivr        91r    c                     ddl m}  || |      S )Nr   )
IntTrueDiv)r  r  )r(  rS  r  s      r   _sympy_int_truedivr    s    7ar    c                     ddl m}  || |      S )Nr   )FloorDiv)r  r  )r(  rS  r  s      r   _sympy_floordivr        5Aq>r    c                f    ddl m}m} | j                  r|j                  r	 || |      S  || |      S )Nr   Mod	PythonMod)r  r  r  is_nonnegative)r(  rS  r  r  s       r   
_sympy_modr    s.    ;A,,1ayAr    c                     ddl m}  || |      S )Nr   )PowByNatural)r  r  )r(  rS  r  s      r   _sympy_pow_by_naturalr    r  r    c                     ddl m}  || |      S )Nr   )FloatPow)r  r  )r(  rS  r  s      r   _sympy_float_powr    r  r    c                .    dd l }|j                  | |      S r[   )r\   Andr(  rS  r\   s      r   
_sympy_andr    s    99Q?r    c                .    dd l }|j                  | |      S r[   )r\   Orr  s      r   	_sympy_orr        88Aq>r    c                     ddl m}  || |      S )Nr   )LShift)r  r  )r(  rS  r  s      r   _sympy_lshiftr        3!Q<r    c                     ddl m}  || |      S )Nr   )RShift)r  r  )r(  rS  r  s      r   _sympy_rshiftr    r  r    c                `   t        |       dk(  r|gS ddlm}m}  || d          ||      k  r| |gz   S  || d          ||      kD  r|g| z   S dt        |       dz
  }}||k  r9||z   dz  }|j	                  | |   |      }|dk(  ry|dk  r|dz   }n|dz
  }||k  r9| j                  ||       | S )zs
    If new_arg is found in ordered_args None is returned, else the new
    ordered_args with new_arg inserted
    r   )_args_sortkeyBasicr     N)lensympy.core.basicr  r  compareinsert)ordered_argsnew_argsort_keyr  lowhighmidcompare_results           r   _binary_search_insert_argr  %  s    
 <AyA R !HW$55wi'' Q 8G#44y<''3|$q(C
+Tza|C'8'BQa'C7D + W%r    c                  	 ddl 	ddlm} 	fd}ddlm} | ||       z  }| ||      z  }|r|r || j
                  d          ||j
                  d         k  r || j
                  |j
                  z         S  || j
                  d          ||j
                  d         kD  r ||j
                  | j
                  z         S |r5|j                  r)t        t        | j
                        |      }| ||      S |r5| j                  r)t        t        |j
                        |       }| ||      S 	j                  | |      } ||      |fS )a  
    Custom optimization for Add used to optimize incremental binary summations of certain properties. The idea
    is when we know the expression is a summation of unique symbols all we need to know is the correct order of symbols,
    and no other optimizations are needed. We pass evaluate=false, with the correct order of args and save the following.
    1. Avoid running other optimizations when the Add is constructed.
    2. Manually figure out the order of the args for the new expression in log(n) comparisons instead of nLog(n)
    (comparing terms is expensive and shows in the profiles).
    The function returns a tuple of (1) a boolean that indicates whether the output is a summation of unique symbols,
    (2) the result sympy expression.
    r   N)r  c                0     j                   | ddi}d|fS )Nr<  FT)r0  )r  resultr\   s     r   make_optimizedz&_optimized_add.<locals>.make_optimizedW  s"    L959f~r    )_is_symbols_binary_summationr  )
r\   r  r  r  r  _args	is_symbolr  listr0  )
lhsrhslhs_is_optimized_summationrhs_is_optimized_summationsortkeyr  r  new_argsr  r\   s
            @r   _optimized_addr  G  s2    9 J">s"CC">s"CC!&@399R=!GCIIaL$99!#))cii"788399Q< 7399R=#99!#))cii"788 "cmm,T#))_cB!(++ "cmm,T#))_cB!(++YYsC F(0&99r    c                     ddl m}  || |      S )Nr   )BitwiseFn_bitwise_and)r  r  )r(  rS  r  s      r   r  r  x  s    B A&&r    c                     ddl m}  || |      S )Nr   )BitwiseFn_bitwise_or)r  r  )r(  rS  r  s      r   r  r  ~  s    A1%%r    )r   r   r   r   r   r   rg  r  rl  r  r   r   r   r   r   c                   dd l }t        | |j                        rf| j                  }t	        |      dk(  rLt        |d   |j
                        r3|d   j                  r$|j                  |d         }|d   |k(  r||d   z  S t        | |j
                        r| |j                  |       k(  st        | |j                        r|j                  |       S  ||       S )Nr   r  r  )r\   r+   Mulr3  r  r]   r   ro   )r(  rr  r\   aacoefs        r   _floor_ceil_helperr    s    !UYYVVr7a<Jr!uekk:r!u?O?O==A'D!u}be|#1ekk"q!!a'}}Qa5Lr    c                    ddl m}  ||       S )Nr   )
FloorToInt)r  r  )r(  r  s     r   _sympy_floorr        7a=r    c                    ddl m}  ||       S )Nr   )
TruncToInt)r  r  )r(  r  s     r   _sympy_truncr    r  r    c                    ddl m}  ||       S )Nr   )	CeilToInt)r  r  )r(  r  s     r   _sympy_ceilr    s    6Q<r    c                .    dd l }|j                  | |      S r[   )r\   Eqr  s      r   	_sympy_eqr    r  r    c                .    dd l }|j                  | |      S r[   )r\   Ner  s      r   	_sympy_ner    r  r    c                .    dd l }|j                  | |      S r[   )r\   Gtr  s      r   	_sympy_gtr    r  r    c                .    dd l }|j                  | |      S r[   )r\   Ltr  s      r   	_sympy_ltr    r  r    c                .    dd l }|j                  | |      S r[   )r\   Ler  s      r   	_sympy_ler    r  r    c                .    dd l }|j                  | |      S r[   )r\   Ger  s      r   	_sympy_ger    r  r    c                     ddl m}  || |      S )Nr   )Min)r  r  )r(  rS  r  s      r   
_sympy_minr        0q!9r    c                     ddl m}  || |      S )Nr   Max)r  r  )r(  rS  r  s      r   
_sympy_maxr    r  r    c                6    dd l }|j                  || f|df      S )Nr   T)r\   	Piecewise)r(  r   fr\   s       r   
_sympy_iter    s    ??Aq6At9--r    c                      fd}|S )Nc                r    dd l } t        |j                  j                  j                  d       |       S )Nr   OpaqueUnaryFn_)r  rp  utils_sympy	functions)r(  r-  rq  s     r   rr  z_get_sym_math_fn.<locals>.fn  s1    +Mwu{{))33~dV5LMaPPr    rx   rs  s   ` r   _get_sym_math_fnr     s    Q
 Ir    _sympy_c                ,    dd l }|j                  |       S r[   )r\   Abs)r(  r\   s     r   
_sympy_absr    s    99Q<r    c                8    ddl m}m} | ||       S  || |      S )Nr   )RoundDecimal
RoundToInt)r  r  r  )numberr   r  r  s       r   _sympy_roundr	    s"    E&!!FG,,r    c                    ddl m}  ||       S Nr   )ToFloat)r  r  )r(  r  s     r   _sympy_sym_floatr    s    4 1:r    c                d    dd l }ddlm} |j                   ||j	                  |             |       S r  )r\   r  r  r  r   )r(  r\   r  s      r   _sympy_is_integerr    s&    488GEKKN+Q//r    )r   r   c                `    t        |       }t        | |t        t        |dz
  dd                  S )Nr  r  )r  sympy_is_contiguous_genericr  range)r   r   dims      r   sympy_is_contiguousr  F  s,    
e*C&ugtE#'2r<R7STTr    c                   dd l }t        |       }t        |      |k7  r|j                  S |j                  }|j                  j
                  }|D ]L  }||j                  | |   |j                  j
                        |j                  ||   |      z  z  }|| |   z  }N t        |      D ].  }||j                  | |   |j                  j                        z  }0 |S r[   )	r\   r  rb   ra   SOner  r  Zero)r   r   	dim_orderr\   r  r   zds           r   r  r  K  s    
e*C
9~{{JJMA %(EGGKK8588GAJPQ;RRR	U1X 3Z :%(EGGLL99:r    c                     t        | |g d      S N)r     r  r   r  r   r   s     r   $sympy_is_channels_last_contiguous_2dr!  c  s    &ug|DDr    c                     t        | |g d      S N)r     r  r  r   r  r   s     r   $sympy_is_channels_last_contiguous_3dr%  g  s    &ugGGr    c                   dd l }ddlm} t        |       }|t        |      k7  r|j                  S |j
                  j                  }|j                  }||j                  |d   d      z  }|D ]R  }||j                  | |   d      ||   |k\  z  z  }|dk(  r||j                  ||d         z  }||    || |   d      z  }T |S )Nr   r  r  )	r\   r  r  r  rb   r  r  ra   r  )	r   r   r  r\   r  r  mrD  r  s	            r   &sympy_is_channels_last_strides_genericr(  k  s    0
e*C
c)n{{A

A '!*a	  A *	UXXeAh"gajAo66 6!WQZ((A AJU1Xq))'** Hr    c                     t        | |g d      S r  r(  r   s     r   !sympy_is_channels_last_strides_2dr+    s    1%,OOr    c                     t        | |g d      S r#  r*  r   s     r   !sympy_is_channels_last_strides_3dr-    s    1%/RRr    c                "    ddl m}  |g | | S )Nr   )!IsNonOverlappingAndDenseIndicator)r  r/  )r   r   r/  s      r   -_sympy_is_non_overlapping_and_dense_indicatorr0    s    N,>e>g>>r    )r   r   r   r   r  r  )r   r   c                   t        |t              r|j                  S t        |      t        u r| j                  |      S t        |      t        u r| j                  |      S t        |      t        u r| j                  |      S t        S r   )r+   r,   rk   r2   r   rv   r   rr   r   rt   NotImplemented)r/   rq   s     r   r  r    sn    #x xx	cd	~~c""	cc	}}S!!	ce	s## r    c                   t        | t              r| j                  | j                  S | j                         rt	        |       S | j                         rt        |       S | j                         rt        |       S t        d|        )Nzunrecognized return type )
r+   r   r5   re   r   rg   r   ri   r   AssertionErrorri  s    r   r%  r%    sk    !W!**"8zzxxzay	
{	
qz8<==r    c                    t         |    S r   )METHOD_TO_OPERATOR)methods    r   r   r     s    f%%r    c                l     t        d             t        v r  d}n }dd} fd}| fd       }| fd       } t        v rt        t        d| |       y  dk(  r fd}t        t        d| |       y  d	k(  rd fd
	}t        t        d| |       y t        t        d| |       y )N   r8  c                 L   dd l } | j                  j                  | j                  j                  | j                  j
                  j                  | g}dd l} |D ch c]  }t        j                  |       c}| j                  j                  j                         z  dhz  S c c}w )Nr   z<string>)r-  _dynamo
eval_framer  fxexperimentalr   torch._dynamo.guardsinspectgetfileguardsuninteresting_files)r-  modsr'  s      r   rC  z-_make_node_magic.<locals>.uninteresting_files  s     MM$$MMHH!!**	
 	$ *..AW__Q.mm""6689l	
.s   B!c                H     t        j                         d fd	       }|S )Nc                    |	 |       n	 | |      t         j                  j                  j                  r#|| |gn| gdfdt	        dfd       S )Nc                   dd l }| j                  y t        |       t              k(  ry t        | j                  |j
                  |j                  f      ry | j                  |j                  |j                  fv ry t        |       S r[   )	r\   r5   idr+   r(   ro   r]   ra   rb   )r   r\   r  s     r   get_idzM_make_node_magic.<locals>.capture_provenance.<locals>.wrapper.<locals>.get_id  sl     ((4#HF3##HMMEMM5;;3OP#!5::u{{*CC#h<'r    expression_createdc            
        t              t              D  cg c]  } t        |        c} D cg c]  } |       |       c}t        j                  d      t        j                  d      dS c c} w c c}w )Nr  )r7  r  	result_id	argumentsargument_ids
user_stackstack)r{   rH  
structuredget_user_stackget_framework_stack)r(  irM  rI  r7  r  s     r   rk  zO_make_node_magic.<locals>.capture_provenance.<locals>.wrapper.<locals>.<lambda>	  sv    "("%f+%'Z6?%@c!f%@/8)*+F1I<QF1I) '1&?&?&B!+!?!?!B
)  &A)s   A8
A=
A=)metadata_fn)r`  zOptional[int])r-  _logging	_internalGET_DTRACE_STRUCTUREDr   )r/   r?   rM  rI  r  rr  r7  s     @@@r   wrapperz=_make_node_magic.<locals>.capture_provenance.<locals>.wrapper  sc    }DD%~~''==$!%uI!%I( "(
! Mr    r   )	functoolswraps)rr  rY  r7  s   ` r   capture_provenancez,_make_node_magic.<locals>.capture_provenance  s&    		(	 
(	T r    c           
     D   ddl m}m} t              }d }| j                  )|j                   || j                  |j                        }t
        j                        }|r'|%t        |  |t        |       t        |                  S  |       r(t        |  ||t        |       t        |      fi             S t        |t              sJ d}	 dk(  rddlm}m}	 | j                  }
| j                  j                   s(|
j#                  | j                        j$                  dk\  r\|j                  j                   s(|
j#                  |j                        j$                  dk\  r || j                  |j                        }nw |	| j                  |j                        }nYdk(  r7 | j                  |j                  | j&                  |j&                        \  }}n | j                  |j                        }t.        j1                  d| j                  |j                  |       t2        v rt4        }nFt6        v rt8        }n7| j:                  t4        u s|j:                  t4        u rt4        }n| j:                  }||t        |t<              s ||      }| j                  j?                  || j@                  |j@                  f      \  }}t        || j                  ||||	      }|S # t(        $ r. t*        j-                  d| j                  |j                          w xY w)
Nr   r!  Fr   r  r   failed to eval %s(%s, %s)z%s %s %s -> %s)r6   r7   )!r,  r"  r#  r   r.    alternate_impl_if_hinted_methodsgetr  r%  r+   r   r  r  r  r)   r(   r  bound_sympylowerr"   r>  r?  r@  sym_node_logdebugalways_float_magic_methodsr   always_bool_magic_methodsr   r-   r,   r2  r6   )r/   r?   r"  r#  opr7  alternate_implr7   r  r  r)   r5  r-   r6   r8  r  funcr7  s                   r   binary_magic_implz+_make_node_magic.<locals>.binary_magic_impl  s   	

  '99 UZZ%;$))UZZ0H9==fEh24	$5AQ!RSS)"y	%@P.QSUV  %)))#	G !NN	II,, ,,TYY7==BJJ-- ,,UZZ8>>!Cdii4C#DIIuzz:C5-1IIJJ--..	.*$c 499ejj1 	+VTYY

CP //F00F[[E!U\\U%:F[[F $x2h'H ^^<<u}}-

 NN 3
 U  	KK3VTYY

S	s   D*K( (7Lc           	        ddl m}m} t              } |       rt	        |  ||t        |       fi             S | j                  }dk(  sdk(  r| j                  j                  |      }	  
|      }t        j                  d
||       d }| j                   || j                        }t        v rt         }n*t"        v rt$        }nt&        v rt(        }n| j*                  }| j                  j-                  || j.                  f      \  }}	t1        || j                  |||      S # t        $ r t        j                  d|        w xY w)Nr   r!  r   ceilingzfailed to eval %s(%s)z%s %s -> %sr+  )r,  r"  r#  r   r  r%  r(   r)   _simplify_floor_divr>  r?  r@  rc  rd  r.   always_int_magic_methodsr   rf  r   re  r   r-   r2  r6   r   )r/   r"  r#  rg  r(   r5  r7  r-   r6   r8  ri  r7  s             r   unary_magic_implz*_make_node_magic.<locals>.unary_magic_imply  s3   	

  '4!4R)D/9KR!PQQyyW) 3>>55d;D	t*C 	=$c:99 $))}H--F00F11F[[F^^<<R$,,Q
sDNNFHgNN%  	KK/>	s   ,D) )"Er
   c                   ddl m}m} | j                  r|j                  n|j                  } |       r6t	        |  |t
        t        |       t        |      t        |      fi             S 	  	| j                  |j                  |j                        }| j                  j                  t
        | j                  |j                  |j                  f      \  }}t        || j                  |j                  ||      S # t        $ r9 t        j                  d
| j                  |j                  |j                          w xY w)Nr   r!  zfailed to eval %s(%s, %s, %s)r+  )r,  r"  r#  r.   r  r
   r%  r(   r>  r?  r@  r)   r2  r6   r   r-   )	pred_node	then_node	else_noder"  r#  r7  r5  r6   r8  ri  r7  s            r   sym_ite_implz&_make_node_magic.<locals>.sym_ite_impl  s   
 *3y~~Y^^H'%i0%i0%i0
  
9>>9>>9>>J #,,EE)++Y->->	@Q@QRJGQ Y(()*:*:Hg   3NNNNNN s   ,(C< <AD>r   c           	     (   ddl m}m} t        j                  } |       rt        |  ||t        |       |fi             S | j                  }	  ||      }|t        }n| j                  }d }| j                   || j                  |      }| j                  g}	||	j                  |       | j                   j#                  |t%        |	            \  }
}t'        || j                   |||
      S # t        $ r t        j                  d||        w xY w)Nr   r!  z!failed to eval %s(%s, ndigits=%s)r+  )r,  r"  r#  builtinsr   r  r%  r(   r>  r?  r@  r   r-   r.   r6   r   r)   r2  r/  r   )r/   r   r"  r#  rg  r(   r5  r-   r7  r3  r6   r8  ri  r7  s               r   
round_implz$_make_node_magic.<locals>.round_impl  s	   
 B-b9T?G2LbQ  99D4)
 Hyy$dii1 LL>D"G$@@U4[QJGQ3'RR1  ?wWs   	C. .#D)r`  zset[str]r   )r   2magic_methods_on_operator_with_trailing_underscoreunary_methodssetattrr   )	r7  ri  method_attrrC  r\  rj  ro  rt  rw  s	   ``       r   _make_node_magicr|    s    9S>$DCCl
",\ \ \| "O "OH 1[M*,<=	9	&	P 	1[M*L9	7	'	SR 	1[M*J71[M*,=>r    c                      fd}t        t        d  |        fd}t        t        j                  t
                  s#t        t        j                  t
            |       y y )Nc                "   ddl m}m} t        t        j
                  t                 } |       rDt        |  |||D cg c]  }t        |       c}|D cg c]  }t        |       c}fi             S |D cg c]  }|j                   }}|D cg c]  }|j                   }}	  ||      }	g }
d }|D ]+  }|j                   nX|
j                  |j                         - g }|D ]+  }|j                   n&|j                  |j                         -  ||
|      }j                  d      rt         }nt"        }t%        |	| j&                  ||      S c c}w c c}w c c}w c c}w # t        $ r t        j                  d||        w xY w)Nr   r!  r^  
_indicator)r,  r"  r#  rp  sysmodulesra  r  r%  r(   r>  r?  r@  r.   r   endswithr   r   r   r)   )r/   r   r   r"  r#  rg  rT   
size_exprsstride_exprsr5  r6  r7  stride_hintsr-   ri  r7  s                 r   sizes_strides_implz4_make_node_sizes_strides.<locals>.sizes_strides_impl  s   	

 S[[*F3#,12qil274SaYq\4ST  ',,aff,
,(/0100	z<0C 
 	8Avv~aff%	8
 L 866>##AFF+8
 j,7 ??<(FFsDNNFH==E 34S -0  	KK3VZV	s#   EE:E!E&)	E+ +#Fr8  c                "   dd l }ddlm} t        j                  | |      D ]~  }t        |t              st         t        |j                        | D cg c]  }t        |j                  |       c}|D cg c]  }t        |j                  |       c}            c S  dk(  r	 || |      S t         | D cg c]  }|j                  |       c}|D cg c]  }|j                  |       c}            S c c}w c c}w c c}w c c}w )Nr   )!eval_is_non_overlapping_and_denser  )r\   r'   r  	itertoolschainr+   r   r%  rp  rk   r  r   sympify)r   r   r\   r  r(  rS  ri  r7  s         r   sizes_strides_userz4_make_node_sizes_strides.<locals>.sizes_strides_user3  s    	
 0 	A!V$ +GAFFF+5:;+;5<=+= 	 ==4UGDD /45!U]]1%5/67!U]]1%7  <= 67s   C=8D<DD)rz  r   hasattrr  r  ra  )r7  ri  r  r  s   ``  r   _make_node_sizes_stridesr    sS    .>` Gq\#56
6 3;;x(&1H%v/AB 2r    c                    	
  t         v rd  n dd	d 
 t        v rd nd  fd	
 fd}	
 fd}	
 fd	} t        v rt        |d
  d
|       y  t        v r$t        |       }t        | t        ||             y  dk(  r	fd}t        |d
  d
|       y  dk(  rd	
 fd	}t        |d
  d
|       y  } t        v r	t            }t        |d
| d
|        t        v rt        |d| d
|       y y )Nr  c                    t        | t        t        t        f      r| S t        | t              r| j
                  j                  dd      S t        d      )Nr  r   z*expect to be called with constant SymBools)r+   r   r   r   r   rk   rK  r4  ri  s    r   get_constantz&_make_user_magic.<locals>.get_constantb  sE    a#ud+,Ha!66$$R++IJJr    c                    t        | t        t        t        f      ryt        | t        t
        t        f      r| j                  j                         S y)NTF)	r+   r   r   r   r   r   r   rk   r_  ri  s    r   r_  z%_make_user_magic.<locals>.is_constanti  s=    a#ud+,a&(G4566%%''r    c                    t        | t              r-t        | j                  j	                  t        |                   S | S )z;Implements True+True=2, which works in python but not sympy)r+   r   r   rk   rr   r   ri  s    r   promotez!_make_user_magic.<locals>.promote  s-    !W%affooc!f566Hr    c                    | S r   rx   ri  s    r   r  z!_make_user_magic.<locals>.promote  s    Hr    c                    dvr| |fS t        | t        t        j                  f      }t        |t        t        j                  f      }|s|r.|st        j                  |       } |st        j                  |      }| |fS )N)r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   )r+   r   r-  r   r	   )r/   r?   f_selff_otherr7  s       r   promote2z"_make_user_magic.<locals>.promote2  sy      
 
$ ;D5%.."9:UUENN$;<Wt,.U{r    c                     |       }  |       r t               |             S t         t        | j                                     S r   )r   r%  rp  rk   )r/   r  r_  r7  r{  r  s    r   ro  z*_make_user_magic.<locals>.unary_magic_impl  sH    t}t.&v.T0BCC8K8:;;r    c           	        t        |t        t        t        t        t
        t        f      st        S t        j                  d| |        |       }  |      } 	| |      \  } } |       r t               |       |      S  |      r |      }t        | j                  |      }|t        u rt        S t         t        | j                        |            } |      r |      S |S )NzMAGIC %s %s %s)r+   r   r   r   r   r   r   r2  rc  rd  r   r  rk   r%  rp  
r/   r?   
other_noderetr  r_  r7  r{  r  r  s
       r   rj  z+_make_user_magic.<locals>.binary_magic_impl  s    %#udFHg!NO!!+VT5At}tU+et.&v.T0BEJJu 'ETYY.
'!!7		;7
CD$/$4|C =#=r    c           	        t        |t        t        t        t        t
        t        f      st        S  |       }  |      } 	| |      \  } } |       r t               |       |      S  |      r |      }t        | j                  |      }|t        u rt        S t         t        |      | j                              } |      r |      S |S r   )r+   r   r   r   r   r   r   r2  r   r  rk   r%  rp  r  s
       r   rbinary_magic_implz,_make_user_magic.<locals>.rbinary_magic_impl  s    %#udFHg!NO!!t}tU+et.&v.T0BEJJu 'ETYY.
'!!8
K8CD$/$4|C =#=r    __r
   c                   | j                   }t        ||      }t        ||      }|t        u s|t        u rt        S t        |t              r)t        |t              r|j
                  |j
                  k(  sJ t         t        | j                         ||            }|j                   j                         r |      S |S r   )	rk   r  r2  r+   r   r-   r%  rp  r_  )	predr   r   rq  rr  rs  r  r  r{  s	          r   sym_ite_magic_implz,_make_user_magic.<locals>.sym_ite_magic_impl  s    		I	84I	84IN*i>.I%%9g.y'2$$	(8(889 ;GDII{;IyQRC(+(<(<(><$GCGr    r   c                     |       rt        j                   |       |      S t         t        | j                        |            S r   )rv  r   r%  rp  rk   )r/   r   r  r_  r7  s     r   round_magic_implz*_make_user_magic.<locals>.round_magic_impl   s?    4 ~~l4&8'BB7WTYY7@AAr    __r)rj  z2Union[SymInt, int, SymFloat, float, SymBool, bool]r   )	rx  bool_becomes_int_magic_methodsunary_magic_methodsrz  unary_nonmagic_methodsrp  r   bitwise_opsreflectable_magic_methods)r7  	user_typero  rj  r  origr  r  method_namer  r_  r{  r  r  s   `        @@@@@r   _make_user_magicr  Y  sG    CCVHoKB //		!T< <> >"> >  $$	Rxr?,<=	)	)y&)	6>2BD#IJ	9		H 		Rxr?,>?	7		B 		Rxr?,<=[ %f-K	R}B/1BC..I[M46HI /r    )FFr   )
__future__r   rv  rZ  r@  r  loggingmathoperatorr  r   r   typingr   r   r   r-  torch._logging.structuredrV  rQ  r	   r
   r   r   r   r   r   r   torch._loggingr   r'   r   	getLoggerra  r?  getArtifactLoggerrc  __all__torch.typesr   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  r6  r  rt  math_op_namesrq  sym_namepriv_sym_namerz  rp  r   r  ry  only_bool_magic_methodsr  also_bool_magic_methodsbool_magic_methodsonly_float_magic_methodsrx  r  re  rn  rf  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  current_moduler   priv_sympy_namerr  rc  r  r	  r  r  invertr   r  r  r!  r%  r(  r+  r-  r0  sizes_strides_methodsminmaxr_  r  r%  r   r|  r  itemsr7  ri  r  rx   r    r   <module>r     s   #        
 / 1 1  . .	 	 	 - >g!~~//*E = 1V Vt#	8<<#	8<<# 
8<<# 
8==	#
 8==# DII# 	(++# TZZ# TZZ# H%%# 	(++# 	(++# *# 	(++# hoo#  	(++!#" 
8<<##$ 
8<<%#& 	(++'#( 
8<<)#* 	(,,+#, (,,-#. /#0 hll1#2 X^^3#4 hoo5#6 
8<<7#8 9#: w;#< w=#> w?#@ wA#B X%%C#D 8##E# J
   DdV}HzNMGX/56#*5-#@x H%NN8   $&<< > !6 & ,/FF  J  7<T] 2  X  -DdV}H""8,-
 H  "F LQ.:b'& <<<<+!
)%# &$. X&  1Dv&O	$	B$33BObkNOR0	1 o-0x 
8<< 	)	
 	) 	) 	) 	) 	) \ \ ! K 
8<< z  z!" z#$ 
:%& #)0  HDdV}H%nv6FGM(H 	(M>U
0EH%PPS? )&J&J#D#D.[	  ||||$  >&e?P	TCn "'') #LFDVT"# *//1 +LFDVT*+tJn "'') +LFD(()))*((F6T,T)VV$[ *+ r    