
    Phc              	          U 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mZmZmZmZmZmZmZmZ d dlZd dlmZ d dlZd dlZd dlmZ ddlmZmZ dd	lm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' dd
l(m)Z)m*Z*m+Z+ ejX                  j[                  e.d      Z/d Z0 edg d      Z1 edddg      Z2 edddg      Z3i Z4ee5e3f   e6d<   de5de7de7fdZ8de5fdZ9de5fdZ:deejv                     fdZ< ejz                  d      d        Z>ej~                  ej                  ej                  ej                  iej                  ej                  ej                  ej                  ej                  ej                  ej                  ej                  fD  ci c]  } | |  c} ZJ G d d       ZK G d! d"e      ZL G d# d$eL      ZM G d% d&      ZN G d' d(e       ZO G d) d*e#      ZP G d+ d,e      ZQ G d- d.      ZR G d/ d0      ZS G d1 d2eR      ZT G d3 d4      ZU G d5 d6e       ZV G d7 d8      ZW G d9 d:eW      ZXej                   G d; d<             ZZ ejz                  d      d=        Z[ G d> d?      Z\ G d@ dA      Z]yc c} w )B    N)
namedtuple)chain)
AnyCallableClassVarDictList
NamedTupleOptionalSetTupleUnion)Printer)ValueRanges   )configmetrics)DeferredLineBasedo_benchfree_symbol_startswithIndentedBuffer	sympy_dot
sympy_subssympy_symbolunique)opsOpsValueVschedulec                 x    t         j                  t        j                        rt         j	                  d|        y y )NzData type propagation: %s)schedule_logisEnabledForloggingDEBUGdebug)msgs    iC:\Users\daisl\Desktop\realtime-object-detection\venv\Lib\site-packages\torch/_inductor/codegen/common.pydata_type_loggerr(   .   s*      /6< 0    	TensorArg)namebufferdtypecheck_alignmentSizeArgr+   exprDeviceCodegen
schedulingwrapper_codegendevice_codegensdevicedevice_schedulingdevice_wrapper_codegenc                 *    t        ||      t        | <   y N)r1   r4   )r5   r6   r7   s      r'   register_backend_for_devicer:   O   s     ,,=?UVOFr)   c                 <    | t         v rt         |    j                  S d S r9   )r4   r2   r5   s    r'   get_scheduling_for_devicer=   U   s     17?1J?6"--TPTTr)   c                 <    | t         v rt         |    j                  S d S r9   )r4   r3   r<   s    r'   get_wrapper_codegen_for_devicer?   Y   s$    39_3L//RVr)   indexc                 L    ddl m} g | t        ||j                  |            S )Nr   )FlexibleLayout)irrB   r   contiguous_strides)r@   
index_varssizesrB   s       r'   index_prevent_reorderingrG   _   s*    # UUTIj.*K*KE*RSTTr)   c                       y)N)is_infis_nanbitwise_xorlogical_notsignbitleltgegteqne rT   r)   r'   boolean_opsrU   f   s    r)   c                   
   e Zd ZddZdej
                  j                  fdZdej
                  j                  fdZdej
                  j                  fdZ	dej
                  j                  fdZd	 Zed
        Zed        Zy)DataTypePropagationNc                     || _         d|j                  j                  i| _        |j                  j                         D ]  \  }}|j                  | j                  |<     y Nroot)body
root_blockgraphgraphs	subblocksitems)selfr[   kvs       r'   __init__zDataTypePropagation.__init__   sP    	DOO))B
 NN((*DAqWWDKKN +r)   nodec                    |j                   }|D cg c]9  }t        |t        j                  j                        s(|j
                  dk7  s8|; }}t        |      dk(  ry t        d |D              }|sy t        j                  t        j                  |D cg c])  }|j                  t        j                     j                  + c}      S c c}w c c}w )Nplaceholderr   c              3      K   | ]K  }t         j                  |j                  v xr) |j                  t         j                     j                  d u M y wr9   )OptimizationContextkeymetar-   ).0ns     r'   	<genexpr>zBDataTypePropagation.deduce_node_dtype_by_inputs.<locals>.<genexpr>   sS      )
 !  ##qvv- B*../55TAB s   AA)all_input_nodes
isinstancetorchfxNodeoplenall	functoolsreducepromote_typesrk   ri   rj   r-   )ra   re   inputsrm   input_nodesall_input_nodes_propogateds         r'   deduce_node_dtype_by_inputsz/DataTypePropagation.deduce_node_dtype_by_inputs   s    %%
!Auxx}}!=!$$-BWAv 	 
 {q %( )
 !)
 &
"
 *<GHKqQVV'++,22KH
 	

  Is   )CCC.C
c                 b    | j                   |j                     }| j                  |      }|sJ |S r9   )r^   targetpropagate_graph)ra   re   	sub_graphr-   s       r'   deduce_node_dtype_by_subgraphz1DataTypePropagation.deduce_node_dtype_by_subgraph   s0    KK,	$$Y/ur)   c                    |j                   t               v rt        j                  S |j                  dk(  ry |j                   dk(  rt        |j                        dk7  ry |j                   dv r|j                  d   S |j                   dv rt        j                  S |j                   dv rt        j                  S |j                   dv r.|j                  d   }t        j                  j                  |      S |j                   t        j                  k(  r| j                  |j                  d	         S t        |j                   t               sJ |j                   d
k(  r|j                  d   S |j                   dk(  rt"        |j                  d      S |j                   j%                  d      r| j'                  |      S | j)                  |      S )Nrg   output   )to_dtype
index_expr)randrandn)	get_indexr   )loadstorestore_reductionr   	reductionconstantmasked_subblock)r   rU   rq   boolrt   ru   argsfloatint64r   r]   	get_dtypeoperatorgetitemdeduce_node_dtyperp   strDTYPE_TO_COMPUTATION_DTYPE
startswithr   r}   )ra   re   buf_names      r'   r   z%DataTypePropagation.deduce_node_dtype   s   ;;+-'::77m#;;("499~";; 
 
 99R= ;; 
 
 ;;;; 
 
 ;;;; 
 

 yy|H77$$X..;;(***))$))A,77$++s+++;;+%99Q<;;*$-diim<<;;!!"3455d;;//55r)   r]   c                 n   |j                   sJ d }|j                   D ]  }t        j                  |j                  v r|j                  t        j                     }n
t               }| j	                  |      |_        ||j                  t        j                  <   |j                  dk(  s|j
                  } |S )Nr   )nodesri   rj   rk   r   r-   r   )ra   r]   graph_dtypere   opt_ctxs        r'   r   z#DataTypePropagation.propagate_graph   s    {{{ KKD"&&$))3))$7$;$;<-/ 2248GM18DII)--.{{h&%mm   r)   c                 @    | j                  | j                  d          y rY   )r   r^   ra   s    r'   	propagatezDataTypePropagation.propagate   s    T[[01r)   c                 .     | |      j                         S r9   )r   )clsr[   s     r'   propagate_loopbodyz&DataTypePropagation.propagate_loopbody   s    4y""$$r)   c                     ddl m} ddlm} t	        ||      sJ t	        |j
                  |      sJ t        j                  |j
                         y )Nr   )LoopBody)SchedulerNode)rC   r   	schedulerr   rp   _bodyrW   r   )r   re   r   r   s       r'   propagate_scheduler_nodez,DataTypePropagation.propagate_scheduler_node   s>    !-$...$**h///..tzz:r)   )returnN)__name__
__module____qualname__rd   rq   rr   rs   r}   r   r   Graphr   r   classmethodr   r   rT   r)   r'   rW   rW      s    %
 
*%((-- 46ehhmm 46lUXX^^ $2 % % ; ;r)   rW   c                   X    e Zd Zed        Zd Zd Zd Zd Zd Z	d Z
d Zd	 Zd
 Zd Zy)ExprPrinterc                     d }t        | t              sOt        j                  d| t        j                        s*t        j                  d| t        j                        s| dk(  r| S  ||       r| S d|  dS )Nc                     | d   dk7  st        |       dk  ryd}t        | dd        D ]3  \  }}|dk(  r|dz  }n
|dk(  r|dz  }|dk(  s!|t        |       dz
  k7  s3 y |dk(  sJ y)Nr   (r   Fr   )T)ru   	enumerate)stringcountichars       r'   all_in_parensz(ExprPrinter.paren.<locals>.all_in_parens
  s    ayC3v;?E$VABZ043;QJES[QJEA:!s6{Q"6  1 A::r)   z^[a-z0-9_.]+$z^\([^)]*\)$ r   r   )rp   CSEVariablerematchI)r   r   s     r'   parenzExprPrinter.paren  sc    	 v{+xx(&"$$7xx5|M M6(!}r)   c                      y)Nzmath.infrT   ra   r0   s     r'   _print_InfinityzExprPrinter._print_Infinity$  s    r)   c                      y)Nz	-math.infrT   r   s     r'   _print_NegativeInfinityz#ExprPrinter._print_NegativeInfinity'  s    r)   c           	          d|j                    dj                  t        | j                  t        | j                  |j
                                    S )N )rel_opjoinmapr   _printr   r   s     r'   _print_RelationalzExprPrinter._print_Relational*  s:    4;;-q!&&s4::s4;;		7R'STTr)   c           	          dj                  t        | j                  t        | j                  |j                                    S )N*r   r   r   r   r   r   s     r'   
_print_MulzExprPrinter._print_Mul-  s+    xxDJJDKK(CDEEr)   c           	          dj                  t        | j                  t        | j                  |j                                    S )Nz + r   r   s     r'   
_print_AddzExprPrinter._print_Add0  +    zz#djj#dkk499*EFGGr)   c           	          dj                  t        | j                  t        | j                  |j                                    S )N % r   r   s     r'   
_print_ModzExprPrinter._print_Mod3  r   r)   c                 0    t        dt        |              )Nz$_print_FloorDiv not implemented for )NotImplementedErrortyper   s     r'   _print_FloorDivzExprPrinter._print_FloorDiv6  s    !$Hd"UVVr)   c                 $    | j                  |      S r9   )r   r   s     r'   _print_CleanDivzExprPrinter._print_CleanDiv9  s    ##D))r)   c           	          dj                  t        | j                  t        | j                  |j                                    S )Nz >= r   r   s     r'   _print_GreaterThanzExprPrinter._print_GreaterThan<  s-     {{3tzz3t{{DII+FGHHr)   c                 z    t        |j                        dk(  sJ d| j                  |j                  d          dS )Nr   zalign(r   r   ru   r   r   r   s     r'   _print_alignzExprPrinter._print_alignB  s9    499~"""DIIaL12!44r)   N)r   r   r   staticmethodr   r   r   r   r   r   r   r   r   r   r   rT   r)   r'   r   r     sL     6UFHHW*I5r)   r   c                   B    e Zd Zd Zd Zd Zd Zd Zd Zd Z	d Z
d	 Zy
)PythonPrinterc                    |j                   \  }}}| j                  | j                  |            }| j                  | j                  |            }| j                  | j                  |            }|dk7  r	d| d| d}| d| S )N1r    // r   r   r   r   doprint)ra   r0   xdivmods        r'   _print_ModularIndexingz$PythonPrinter._print_ModularIndexingH  s    ii3JJt||A'jjc*+jjc*+#:A3d3%q!ACu~r)   c                     |j                   \  }}| j                  | j                  |            }| j                  | j                  |            }d| d| dS )Nr   r   r   r   )ra   r0   r   r   s       r'   r   zPythonPrinter._print_FloorDivQ  sQ    3JJt||A'jjc*+1#T#a  r)   c                 ,    d| j                  |       dS )Nz
math.sqrt(r   )r   r   s     r'   _helper_sqrtzPythonPrinter._helper_sqrtW  s    DKK-.a00r)   c           	         |j                   \  }}|dk(  r| j                  |      S |dk(  rd| j                  |      z   S | j                  |      }|t        |      k(  sJ |       t        |      }|dkD  r$dj	                  | j                  |      g|z        S |dk  r?d| j                  dj	                  | j                  |      gt        |      z              z   S y)Ng      ?g      z1/r   r   r   )r   r   r   intr   r   abs)ra   r0   baseexps       r'   
_print_PowzPythonPrinter._print_PowZ  s    II	c #:$$T**D[$++D111{{4 c#h###h788TZZ-.4551W$**SXXtzz$/?.@3s8.K%LMMMr)   c                 z    t        |j                        dk(  sJ d| j                  |j                  d          dS )Nr   zmath.floor(r   r   r   r   s     r'   _print_floorzPythonPrinter._print_floorp  s9    499~"""T[[167q99r)   c                 z    t        |j                        dk(  sJ d| j                  |j                  d          dS )Nr   z
math.ceil(r   r   r   r   s     r'   _print_ceilingzPythonPrinter._print_ceilingt  s9    499~"""DKK		!56a88r)   c                 z    t        |j                        dk(  sJ d| j                  |j                  d          dS )Nr   zabs(r   r   r   r   s     r'   
_print_AbszPythonPrinter._print_Absx  s9    499~"""dkk$))A,/022r)   c                     t        |j                        dk\  sJ ddj                  t        | j                  |j                               dS )Nr   zmax(, r   ru   r   r   r   r   r   s     r'   
_print_MaxzPythonPrinter._print_Max|  @    499~"""diiDKK ;<=Q??r)   c                     t        |j                        dk\  sJ ddj                  t        | j                  |j                               dS )Nr   zmin(r  r   r  r   s     r'   
_print_MinzPythonPrinter._print_Min  r  r)   N)r   r   r   r   r   r   r   r   r   r  r  r  rT   r)   r'   r   r   G  s1    !1,:93@@r)   r   c                        e Zd Z fdZd Zed        Zed        Zed        Zed        Z	ed        Z
ed        Zed	        Zed
        Zed        Zed        Zed        Zed        Zed        Z xZS )OpOverridesc                 0    t         |           || _        y r9   )superrd   _parent)ra   parent	__class__s     r'   rd   zOpOverrides.__init__  s    r)   c                 .    t        | j                  |      S r9   )getattrr  )ra   items     r'   __getattr__zOpOverrides.__getattr__  s    t||T**r)   c                     | S r9   rT   )values    r'   identityzOpOverrides.identity  s	     r)   c                     t        |       S r9   )repr)r  r-   s     r'   r   zOpOverrides.constant  s    E{r)   c                 .    t        j                  d|       S )Nr   )r   truedivr   s    r'   
reciprocalzOpOverrides.reciprocal  s    {{3""r)   c                 .    t        j                  | |       S r9   )r   mulr  s    r'   squarezOpOverrides.square  s    wwq!}r)   c                 2    dt         j                  |        S )N~r   r   r  s    r'   bitwise_notzOpOverrides.bitwise_not  s    ;$$Q'())r)   c                 2    t         j                  |        dS )Nz == 0r"  )as    r'   rL   zOpOverrides.logical_not  s    ##A&'u--r)   c                 \    t         j                  |        dt         j                  |       S )Nz & r"  r   ys     r'   bitwise_andzOpOverrides.bitwise_and  +    ##A&'s;+<+<Q+?*@AAr)   c                 \    t         j                  |        dt         j                  |       S )Nz | r"  r'  s     r'   
bitwise_orzOpOverrides.bitwise_or  r*  r)   c                 \    t         j                  |        dt         j                  |       S )Nz ^ r"  r'  s     r'   rK   zOpOverrides.bitwise_xor  r*  r)   c                 \    t         j                  |        dt         j                  |       S )Nz << r"  r'  s     r'   bitwise_left_shiftzOpOverrides.bitwise_left_shift  +    ##A&'tK,=,=a,@+ABBr)   c                 \    t         j                  |        dt         j                  |       S )Nz >> r"  r'  s     r'   bitwise_right_shiftzOpOverrides.bitwise_right_shift  r0  r)   c           	          t        j                  | |      }t        j                  d| d| d| dt        j                  ||      |      S )Nz((z != 0) & ((z
 < 0) != (z < 0))))r   r   whereadd)r%  brs      r'   	remainderzOpOverrides.remainder  sE    GGAqMyy2aSA3j7CSWWQPQ]TUVVr)   c                 T    t        j                  | t        j                  |            S r9   )r   r   sympyInteger)r+   offsets     r'   	load_seedzOpOverrides.load_seed  s    xxemmF344r)   )r   r   r   rd   r  r   r  r   r  r  r#  rL   r)  r,  rK   r/  r2  r8  r=  __classcell__r  s   @r'   r
  r
    s   +     # #   * * . . B B B B B B C C
 C C W W 5 5r)   r
  c                   .     e Zd ZdZ fdZd Zd Z xZS )DeferredLinezHA line that can be 'unwritten' by adding name to V.graph.removed_buffersc                 2    t         |   |       || _        y r9   )r  rd   r+   )ra   r+   liner  s      r'   rd   zDeferredLine.__init__  s    	r)   c                     t         fdt        j                  j                  t        j                  j                  t        j                  j
                  t        j                  j
                  fD              r j                  S y )Nc              3   :   K   | ]  }j                   |v  y wr9   r+   )rl   r   ra   s     r'   rn   z(DeferredLine.__call__.<locals>.<genexpr>  s&      
 IIQs   )rv   r   r]   removed_bufferskernelinplaced_to_removerC  r   s   `r'   __call__zDeferredLine.__call__  s_     
 ''((**++	
 
 99r)   c                 .    t        | j                  |      S r9   )rA  r+   ra   rC  s     r'   	_new_linezDeferredLine._new_line  s    DIIt,,r)   )r   r   r   __doc__rd   rJ  rM  r>  r?  s   @r'   rA  rA    s    R-r)   rA  c                       e Zd ZddZy)BracesBufferc                 F     t         j                   fd       } |       S )Nc               3     K   t              D ](  } j                  d       xj                  dz  c_        * t               D ](  } xj                  dz  c_        j                  d       * d  t               D ](  } j                  d       xj                  dz  c_        * t              D ](  } xj                  dz  c_        j                  d       * y w)N{r   })range	writeline_indent)_r<  ra   s    r'   ctxz BracesBuffer.indent.<locals>.ctx  s     6]s#! # F7^!s# $ F7^s#! $ 6]!s# #s   C C#)
contextlibcontextmanager)ra   r<  rY  s   `` r'   indentzBracesBuffer.indent  s$    		"	"	$ 
#	$ ur)   N)r   )r   r   r   r\  rT   r)   r'   rP  rP    s    r)   rP  c                   (    e Zd ZU eed<   ee   ed<   y)InplacedBuffer
inner_nameother_namesN)r   r   r   r   __annotations__r	   rT   r)   r'   r^  r^    s    Ocr)   r^  c                   ~    e Zd Ze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 Zy)
KernelArgsc                 |    t        |t        t        j                  f      sJ ||vr|  t	        |       ||<   ||   S r9   )rp   r   r:  Symbolru   )prefixodictr+   s      r'   _lookupzKernelArgs._lookup  sC    $ell 3444u#HSZL1E$KT{r)   Nc                     t               | _        t               | _        t               | _        |xs
 t               | _        y r9   )dictinput_buffersoutput_buffersinplace_bufferssizevars)ra   rn  s     r'   rd   zKernelArgs.__init__   s.    !V"f#v *DFr)   c                     dj                  dj                  t        t        | j                  | j
                  | j                  | j                  g                  S )NzKernelArgs({})r  )formatr   r   r  rk  rl  rm  rn  r   s    r'   __repr__zKernelArgs.__repr__  sS    &&II**++,,	

 	
r)   c                 H    t        |t              xr |j                  d      S )NREMOVED)rp   r   r   ra   r+   s     r'   _buffer_is_marked_removedz$KernelArgs._buffer_is_marked_removed  s    $$C)CCr)   c                    t         j                  j                  r4t         j                  j                  j                  j	                  ||      }|t         j                  j
                  vsJ |       || j                  v r| j                  |   S || j                  v r| j                  |   j                  S |j                  d      r| j                  d| j                  |      S | j                  d| j                  |      S )Nseedin_ptr)r   r]   r   mutation_real_namegetrG  rl  rm  r_  r   rh  rk  rt  s     r'   inputzKernelArgs.input  s    7777$$77;;D$GD1772228D824&&&&&t,,4'''''-888??6"<<(:(:DAA||Hd&8&8$??r)   c                 l   t         j                  j                  r4t         j                  j                  j                  j	                  ||      }|t         j                  j
                  vsJ |       || j                  v r| j                  |   j                  S | j                  d| j                  |      S )Nout_ptr)
r   r]   r   ry  rz  rG  rm  r_  rh  rl  rt  s     r'   r   zKernelArgs.output$  s    7777$$77;;D$GD1772228D824'''''-888||It':':DAAr)   c           	      f   || j                   vsJ || j                   v r:| j                   |   }|j                  j                  |       || j                   |<   y t        dt	        t        | j                   j                                      ||g      }|| j                   |<   || j                   |<   y )N
in_out_ptr)rm  r`  appendr^  ru   r   values)ra   
input_nameoutput_namebufs       r'   make_inplacezKernelArgs.make_inplace,  s    $"6"6666---&&z2COO"";/03D  - S(<(<(C(C(E!FGHI[)C 03D  ,03D  -r)   c                     || j                   v r| j                   |   S | j                   j                         v r0 t        fd| j                   j                         D               | j                   |<   S )Nc              3   F   K   | ]  }|j                        sd   yw)r   N)r   )rl   rc   r+   s     r'   rn   z)KernelArgs.seed_offset.<locals>.<genexpr>?  s     U(>1!,,tBTQ(>s   !!)rn  r  sum)ra   r+   r  s    ` r'   seed_offsetzKernelArgs.seed_offset:  sr    DMM!==''4==''))&U(<(<(>UUVW   $er)   c                 x    t        |      dk(  rd| j                  d<   y| j                  d| j                  |      S )Nrw  ks)r   rn  rh  rt  s     r'   sizezKernelArgs.sizeD  s6    t9$*DMM&!||D$--66r)   c                     t        | j                  j                         | j                  j                         | j                  j                               S r9   )r   rk  keysrl  rn  r   s    r'   
call_nameszKernelArgs.call_namesJ  sA    ##%t':':'?'?'A4==CUCUCW
 	
r)   c                     d| dS )Nz	c_void_p(.data_ptr())rT   )ra   r  r-   s      r'   wrap_ptr_argzKernelArgs.wrap_ptr_argO  s    3%|,,r)   c                     d| dS )Nzc_long(r   rT   ra   r  s     r'   wrap_size_argzKernelArgs.wrap_size_argR  s    a  r)   c                 0   ddl m}m} g }g }g }t        | j                  j                               D ]  }| j                  |      r|j                  d   }|j                  }t        j                  j                  |      }	||	   }
|j                  |
 d|        |j                  | j                  ||	             |j                  |
 d        | j                  j                         D ]  \  }}|| j                  v rt        j                  j                  |      }	||	   }
|j                  d|
 d|        |j                  | j                  ||	             |j                  d|
 d        | j                   j                         D ]  \  }}|| j                  v s| j                  |      r&t        j                  j                  |      }	||	   }
|j                  |
 d|        |j                  | j                  ||	             |j                  |
 d        | j"                  j                         D ]P  \  }}|j                  d| d|        |j                  | j%                  |             |j                  d|        R |||fS )Nr   )DTYPE_TO_CPP
INDEX_TYPEr   z* r   zconst r   )cppr  r  r   rm  r  ru  r`  r_  r   r]   r   r  r  rk  r`   rl  rn  r  )ra   r  r  	call_argsarg_defs	arg_typesinplacedouterinnerr-   	cpp_dtypes              r'   cpp_argdefszKernelArgs.cpp_argdefsU  so   1		t33::<=H--h7((,E''EGG%%e,E$U+IOOykE734T..ue<=	{!_- > !..446LE5,,,GG%%e,E$U+IOOfYKr%9:T..ue<=vi[23 7 !//557LE5,,,0N0Nu0UGG%%e,E$U+IOOykE734T..ue<=	{!_- 8 !MM//1LE5OOfZL%9:T//67vj\23 2 I--r)   c                    g }g }g }t        | j                  j                               D ]  }| j                  |      r|j	                  |j
                         |j	                  |j                  d          |j	                  t        |j
                  |j                  d   t        j                  j                  |j                  d         d              t        | j                  j                         | j                  j                               D ]  \  }}|| j                  v s| j                  |      r&|j	                  |       |j	                  |       |j	                  t        ||t        j                  j                  |      d              | j                  j                         D ]B  \  }}|j	                  |       |j	                  |       |j	                  t!        ||             D |||fS )Nr   T)r   rm  r  ru  r  r_  r`  r*   r   r]   r   r   rk  r`   rl  rn  r/   )ra   r  r  precompile_argsr  r  r  s          r'   python_argdefszKernelArgs.python_argdefs{  s   	;=t33::<=H--h7OOH//0X11"56""''((,GG%%h&:&:2&>?	 > "$$&(;(;(A(A(C
LE5 ,,,0N0Nu0UOOE"U#""%(9(9%(@$G
 !MM//1LE5OOE"U#""75%#89 2
 O33r)   c              #     K   t        | j                  j                               D ]  }| j                  |      r|j                  D ]  }|t
        j                  j                  v s|t
        j                  j                  v r<|| j                  v r| j                  |   |j                  f || j                  v sv| j                  |   |j                  f   y wr9   )r   rm  r  ru  r`  r   r]   rI  rH  rk  r_  rl  )ra   r  others      r'   aliaseszKernelArgs.aliases  s     t33::<=H--h7!--QWW777 ; ;;D...,,U3X5H5HHHD///--e4h6I6III . >s   B:C="Cc                 ^      fd} || j                         xr  || j                        S )Nc                 8    | |vxs j                  ||          S r9   )ru  )r+   buffersra   s     r'   _is_removedz*KernelArgs.is_removed.<locals>._is_removed  s#    w&W$*H*HQU*WWr)   )rl  rm  )ra   r+   r  s   `  r'   
is_removedzKernelArgs.is_removed  s7    	X 4!4!45 
+$&&;
 	
r)   c                 p   t               }t        | j                  j                               D ]2  }| j	                  |      r|j                  |j                  d          4 | j                  j                         D ]6  \  }}|| j                  v s| j	                  |      r&|j                  |       8 |S )Nr   )	setr   rm  r  ru  r5  r`  rl  r`   )ra   	live_outsr  r  r  s        r'   live_output_bufferszKernelArgs.live_output_buffers  s    E	t33::<=H--h7MM(..r23 > !//557LE5,,,0N0Nu0UMM%  8 r)   r9   )r   r   r   r   rh  rd   rq  ru  r{  r   r  r  r  r  r  r  r  r  r  r  r  rT   r)   r'   rc  rc    sj     +
D
@B47

-!$.L 4DJ

r)   rc  c                   @    e Zd ZdZdefdZd ZdefdZde	fdZ
d Zy	)
r   aD  A CSEVariable is just a name for an expression but it is useful to be able to annotate them on a backend dependent basis.
    To do so, the backends can simply overload `Kernel.create_cse_var`
    The "CSEVariable.update_on_args" method gives you a hook for annotations
    See example of TritonCSEVariable in triton.py
    boundsc                 D    t        |t              sJ || _        || _        y r9   )rp   r   r+   r  )ra   r+   r  s      r'   rd   zCSEVariable.__init__  s     &+...	r)   c                     | j                   S r9   rF  r   s    r'   __str__zCSEVariable.__str__  s    yyr)   r   c                 ,    t        | j                        S r9   )hashr+   r   s    r'   __hash__zCSEVariable.__hash__  s    DIIr)   c                 f    t        |      t        |       k(  xr |j                  | j                  k(  S r9   )r   r+   )ra   r  s     r'   __eq__zCSEVariable.__eq__  s'    E{d4j(DUZZ499-DDr)   c                      y r9   rT   )ra   r+   r   kwargss       r'   update_on_argszCSEVariable.update_on_args  s    r)   N)r   r   r   rN  r   rd   r  r   r  r   r  r  rT   r)   r'   r   r     s7    [ 
# Et Er)   r   c                       e Zd Zd Zd Zy)CppWrapperKernelArgsc                 ^    ddl m} t        j                  j                  r|S d||    d| dS )Nr   )r  r   z*)(r  )r  r  r   aot_inductorabi_compatible)ra   r  r-   r  s       r'   r  z!CppWrapperKernelArgs.wrap_ptr_arg  s6    %-- J|E*+3se<@@r)   c                     | S r9   rT   r  s     r'   r  z"CppWrapperKernelArgs.wrap_size_arg  s
    r)   N)r   r   r   r  r  rT   r)   r'   r  r    s    Ar)   r  c            	           e Zd ZdZ	 	 	 	 	 	 	 ddZdee   fdZd Z e	j                         dddd	ed
eeeef   de	defdZ e	j                         fde	defdZy)CSEz Common subexpression eliminationNc                     || _         || _        i | _        || _        |xs i | _        |xs i | _        |xs t        j                         | _        t               | _
        |xs i | _        y r9   )rf  suffixcachename_prefixstore_cachereduction_cache	itertoolsr   iter_buffer_idsr  invalidated_storesvarname_map)ra   rf  r  r  iter_buffersr  r  r  s           r'   rd   zCSE.__init__  sf     
&&,".4"+@y/@"%%&,"r)   	keep_varsc                 0   t        | j                  j                               D ]2  \  }}||vs| j                  |= | j                  j	                  |       4 | j
                  j                         D ci c]  \  }}||v s|| c}}| _        y c c}}w r9   )listr  r`   r  r5  r  )ra   r  r+   tmprb   rc   s         r'   
invalidatezCSE.invalidate  s    d..4467ID#)#$$T*''++D1 8 (,zz'7'7'9L'9tq!Q)^ad'9L
Ls   6BBc                     t        | j                  | j                  | j                  | j                  | j
                  | j                        S )N)rf  r  r  r  r  r  )r  rf  r  r  r  r  r  r   s    r'   clonez	CSE.clone
  sA    ;;;;((--((((
 	
r)   T)r  write
assignmentr,   r0   r  r   c                   t        |t              r|j                  }t        |t        t        f      sJ t        |             |s|sJ t        |t              r"|j                  j                  |      |_        |S |}| j                  j                  |d       }|s|r| j                  |      nd }|| j                  |<   |rt        j                  j                  r+t        j                  j                  j                  |d       |r | j                   | d| | j                    }n| | j                    }|j#                  |       |S |j                  j                  |      |_        |S )NT)	only_oncez = )rp   r   r  r   r   r   r  tightenr  rz  newvarr   rH  current_nodecodegen_originating_inforf  r  rV  )	ra   r,   r0   r  r  r  	cache_keyvarrC  s	            r'   generatezCSE.generate  s?    dH%::D$k 23?T$Z?3
""dK( ++--f5DKK	jjnnY-)3$++f%C$'DJJy!88((HH))BB$ C  "kk]3%s4&FD"VDKK=1D  & 
 ++F3CJ
r)   c                     | j                    t        | j                         }t        j                  j                  ||      }|| j                  |<   |S r9   )r  nextr  r   rH  create_cse_varr  )ra   r  var_namer  s       r'   r  z
CSE.newvar=  sN    &&'T-A-A(B'CDhh%%h7%("
r)   )r   r   r  NNNN)r   r   r   rN  rd   r   r   r  r  r   unknownr   r   r   r   r  r  rT   r)   r'   r  r    s    * -(MCH M	
  2k113&& Ch./&
 & 
&P ,?;+>+>+@ [ [ r)   r  c                       e Zd Zd Zd Zd Zy)IndirectAssertLinec                 J    || _         || _        || _        || _        || _        y r9   )r  maskrC  	assert_fnsize_map)ra   rC  r  r  r  r  s         r'   rd   zIndirectAssertLine.__init__E  s%    		" r)   c                 |   | j                   | j                  | j                  f   \  }}| j                  j                  j                  dk\  t
        j                  k7  }| j                  j                  j                  |k  t
        j                  k7  }|s|sy |r5|r3d| j                   d| j                   d| d}d| j                   d| }n+|rd| j                   }|}n|sJ | j                   d| }|}| j                  rd| d| j                   }| j                  j                  | j                  ||	      S )
Nr   z(0 <= z) & (z < r   z0 <= r   z) | ~)r  cond
cond_print)r  r  r  r  lowerr:  trueupperrC  rp  r  )ra   r  size_str
assert_min
assert_maxr  r  s          r'   rJ  zIndirectAssertLine.__call__L  s+   $))'<=h hhoo++q0UZZ?
hhoo++d2uzzA
 jJ DHH:U488*CzCD 
#hZ8J488*%DJ:hhZs8*-DJ99tfE$))-Dyynn4J   
 	
r)   c                 p    t        || j                  | j                  | j                  | j                        S r9   )r  r  r  r  r  rL  s     r'   rM  zIndirectAssertLine._new_linei  s*    !$..$((DIIt}}
 	
r)   N)r   r   r   rd   rJ  rM  rT   r)   r'   r  r  D  s    !
:
r)   r  c                   *     e Zd Z fdZd Zd Z xZS )CodeGenc                 T    t         |           t        j                         | _        y r9   )r  rd   rZ  	ExitStack
exit_stack)ra   r  s    r'   rd   zCodeGen.__init__p  s    $..0r)   c                 :    | j                   j                          | S r9   )r  	__enter__r   s    r'   r  zCodeGen.__enter__t  s    !!#r)   c                 >    | j                   j                  |||       y r9   )r  __exit__)ra   exc_typeexc_valexc_tbs       r'   r   zCodeGen.__exit__x  s      7F;r)   )r   r   r   rd   r  r   r>  r?  s   @r'   r  r  o  s    1<r)   r  c                       e Zd ZdZdZdZdZdZd fd	Ze	j                  d        Ze	j                  dd       Zdedej                  fdZdedej                  fd	Zd
 ZddZd Zdedej                  dej,                  defdZedefd       Zdej                  defdZ fdZ fdZd Zd Zdej                  fdZ d Z! xZ"S )Kernelr   Nc                    t         |           |rt        xj                  dz  c_        |xs
 t	               | _        t               | _        t               | _        t               | _	        t        | j                  | j                        | _        t               | _        t               | _        d | _        d | _        d | _        i | _        t               | _        t               | _        t/               | _        d| _        y )Nr   )r  rd   r   generated_kernel_countrc  r   r   loadscomputestoresr  newvar_prefixr  cser  must_keep_buffersstore_buffer_names
_load_maskr  node_to_boundsindirect_max_sizesrG  rI  rj  inplace_update_buffersmin_elem_per_thread)ra   r   increase_kernel_countr  s      r'   rd   zKernel.__init__  s     **a/*(JL	#%
%'$&D..<!$"%% JNQS"u"%%
 '+f##$ r)   c              #      K   | j                   }|| _         |j                  j                         j                         | _        	 d  || _         y # || _         w xY wwr9   )r  r   r  
get_boundsr  )ra   re   priors      r'   set_current_nodezKernel.set_current_node  sO     !! "jj//1<<>	& %DDs   AAA A	AAc              #   L  K   ||}| j                   }| j                  }| j                  }| j                  }|| _         || _        || _        |j	                         | _        	 d  || _         || _        || _        || _        y # || _         || _        || _        || _        w xY wwr9   )r  r	  r
  r  r  )ra   lbcbsbr  r	  r
  r  s           r'   swap_bufferszKernel.swap_buffers  s     :B

,,hh
99;	DJ"DL DKDH DJ"DL DKDHs   AB$"B &B$B!!B$r+   r@   c                     t               r9   r   )ra   r+   r@   s      r'   r   zKernel.load      !##r)   c                     | j                   }	 | j                  | _         | j                  ||      || _         S # || _         w xY w)z+A load the depends on an index we have read)r  r	  r   )ra   r+   r@   r  s       r'   indirect_loadzKernel.indirect_load  s8    

	DJ99T5)DJDJs	   "8 	Ac                     t               r9   r  )ra   r+   r@   r  s       r'   r   zKernel.store_reduction  r   r)   c                     t               r9   r  )ra   r+   r@   r  modes        r'   r   zKernel.store  r   r)   c                     t               r9   r  )ra   r-   	src_dtypereduction_typer  s        r'   r   zKernel.reduction  r   r)   offsets_nameoffsets_sizeindexing_dtyperightc                     t               )z3
        See [Note: Inductor bucketize op]
        r  )ra   r  r)  r*  r+  r,  s         r'   	bucketizezKernel.bucketize  s     "##r)   r   c                     t               r9   r  r   s    r'   assert_functionzKernel.assert_function  s    !##r)   c                     t               r9   r  )ra   r@   s     r'   index_to_strzKernel.index_to_str  r   r)   c                 f     G  fdd      }t                     j                  sJ  j                  t        j                                j
                  j                  t        j                   |                     j
                  j                  t        j                                 S )Nc            	          e Zd ZdW _        edededef   f fd       Zedfd	       Z	edede
j                  ffd       Zedfd
	       Zefd       Zefd       Zedede
j                  dej"                  deffd       Zy	)"Kernel.__enter__.<locals>.CSEProxyCSEProxyr+   r   .c                       fd}|S )Nc                     t        j                         }t        t        j                  d      rdt        j                  j
                  }t        j                  t              sJ j                  j                  |t        j                               }j                  j                  j                   t              | i ||      }|j                  | |       |S )Nr  r  )r   r  hasattrr   interpreterr  rp   r  rj  rz  r  r  r	  r  r  )r   r  
buf_boundsfx_nodecsevarr+   parent_handlerra   s        r'   r  z=Kernel.__enter__.<locals>.CSEProxy.__getattr__.<locals>.inner  s    !,!4!4!6Jq}}n="#--"<"<)$*=*=tDDD%)%8%8%<%<#[%8%8%:&
 "XX..55tFvF) / F
 ))$f=!Mr)   rT   )r+   r  r?  ra   s   ` r'   r  z.Kernel.__enter__.<locals>.CSEProxy.__getattr__  s    "$ r)   c           	         | j                   j                  dk  rt        j                         }| j                   t        j                         k7  rt	        |t
        j                        r| j                   t        t
        j                   d      z  }t        |j                  |z   |j                  |z         }| j                   j                  dk\  r,| j                   t        dt
        j                        z  }||z  }t        j                  | j                  |            }| j                   j                  dk\  r-t        j                  | d      }t        j                  |||       }j                  j                  j                   ||      }|j#                  d| fi        |} j%                  |      rj'                  |       }	| |	f}
j(                  j+                  |
d      \  }}|t        j,                  ||      }n>d}j                   j/                  t1        |j2                  | |	j(                               |j5                  |      fj(                  |
<   t7        t9        |             S )Nr   r   0r9  
index_wrapNNz8{assert_fn}({cond}, "index out of bounds: {cond_print}"))r  r  r   r  rp   r:  Numberoor  r   r5  rename_indexingrO   r4  r  r  r	  r  generate_assert	load_maskr  rz  MinrV  r  r0  r2  r   r   )r  r  check
new_boundsnegposstmrO   new_varr  map_keyexisting_sizerX  rC  ra   s                 r'   indirect_indexingz4Kernel.__enter__.<locals>.CSEProxy.indirect_indexing  s    ::##a'!,!4!4!6Jzz[%8%8%::zell@ "jj;y"+EE%0T1A399tCS%T
::++q0"%**{1ehh/G"GC)3c)9J''#t';';D'ABCzz''1, VVC-!iiC5"hh//c*/UG**<#D!C''.>>#.D  #DkG'+'>'>'B'B($M1 %0$yy}= W  ... $ $ 4 4 # $ $ 7 7 9=d>O>OPT>U7VD++G4#CH--r)   r@   c                 $   | j                   j                  v r)t        j                  j                  j                  |        t        |d      rj                  | |      S j                   j                  }| |v r||    S j                  | |      S )Nr  )
r  r  r   rH  r  r5  r   r"  r  r   )r+   r@   r  ra   s      r'   r   z'Kernel.__enter__.<locals>.CSEProxy.load:  s    488666 HH..2248)%7--dE::"hh22;&&t,,yyu--r)   Nc                 \   j                   j                  |        |]|j                  j                  | <   j                  r8j                  j                         D ]  }|j                  j                  |<    | t        j                  j                  vrj                  | |||      S y )N)r%  )
r  r5  r  r  r  get_mutationsr   r]   rG  r   )r+   r@   r  r%  
other_namera   s        r'   r   z(Kernel.__enter__.<locals>.CSEProxy.storeG  s    ''++D1<16DHH((.((*.*;*;*I*I*KJ?DDHH00< +Lqww666::dE5t:DD 7r)   c                 T   j                   j                  |        |j                  j                  | <   j                  r8j                  j                         D ]  }|j                  j                  |<    | t        j                  j                  vrj                  | ||      S y r9   )
r  r5  r  r  r  rU  r   r]   rG  r   )r+   r@   r  rV  ra   s       r'   r   z2Kernel.__enter__.<locals>.CSEProxy.store_reductionR  s    ''++D1-2$$T*$$&*&7&7&E&E&G
;@,,Z8 'H qww666//eUCC 7r)   c                 ,    j                  | |||      S r9   )r   )r-   r'  r(  r  ra   s       r'   r   z,Kernel.__enter__.<locals>.CSEProxy.reduction]  s    ~~eYNNr)   r)  r*  r+  r,  c                 .    j                  | ||||      S )ay  
                [Note: Inductor bucketize op]

                Given values (tensor) and offsets_name (reference to the name of a 1D
                tensor), calculate the bucket that each value belongs to.

                e.g. for values [-1, 0, 1, 2, 3, 4, 5, 9], offsets [0, 4, 4, 8], right=True
                return =        [ 0, 1, 1, 1, 1, 3, 3, 4].

                When right == False, bucket i refers to range (offsets[i], offsets[i+1]].
                When right == True,  bucket i refers to range [offsets[i], offsets[i+1]).

                Offsets must be non-decreasing or the result is undefined.
                )r.  )r  r)  r*  r+  r,  ra   s        r'   r.  z,Kernel.__enter__.<locals>.CSEProxy.bucketizea  s!    , ~~L, r)   )Tr9   )r   r   r   r+   r   r   r   r   r  rR  r:  Exprr   r   r   r   rq   r-   r   r.  )r?  ra   s   r'   r6  r5    s    "DI# (33C*D  * 6. 6.p 
.3 
.uzz 
. 
. E E D D O O ! $jj !&	
  r)   r6  )	r  r  	overridesr   get_ops_handlerr  enter_contextset_ops_handlerset_kernel_handler)ra   r6  r?  r  s   ` @r'   r  zKernel.__enter__  s    Q	 Q	f 	~~~(9(9(;<%%a&7&7
&CD%%a&:&:4&@Ar)   c                     t         j                  j                  r(t         j                  j                  j                          t        |   |||       y)zj
        Note that V.graph.scheduler can be None when codegening triton template
        kernels.
        N)r   r]   r   remove_kernel_local_buffersr  r   )ra   r  r  r  r  s       r'   r   zKernel.__exit__  s9    
 77GG99;7F3r)   c                 N    |xs t         j                  xr t         j                  S r9   )r   debug_index_assertsassert_indirect_indexing)ra   rJ  s     r'   rG  zKernel.generate_assert  s    333X9X9XXr)   c                      y)Nr   rT   )ra   r  s     r'   rH  zKernel.load_mask  s    r)   c                 D   t        |t        t        f      r|D cg c]  }| j                  |       c}S t        j
                  j                  j                  |      }t        |j                  d       }|D ci c]  }|j                  j                  d      sQ|j                  j                  d      s6|j                  j                  d      r7|j                  j                  d      s|| j                  j                  |       }}t        ||      S c c}w c c}w )Nc                     | j                   S r9   rF  )ss    r'   <lambda>z(Kernel.rename_indexing.<locals>.<lambda>  s    !&&r)   )rj   rh  psr   idx)rp   r  tuplerF  r   r]   rn  simplifysortedfree_symbolsr+   r   r   r  r   )ra   r@   r   sorted_symbolsreplacementss        r'   rF  zKernel.rename_indexing  s     edE]+5:;UD((+U;;  ))%0 2 28HI $
#vv  %vv  &!!#&qvv/@/@/G	 tyy~~a  # 	 
 %.. <
s   D;BDc                     t        |i |S r9   )r   )ra   r   r  s      r'   r  zKernel.create_cse_var  s    D+F++r)   )NTrC  r9   )#r   r   r   r  r  r[  load_formatstore_formatrd   rZ  r[  r  r  r   r:  rZ  r   r"  r   r   r   rq   r-   r   r.  propertyr0  r2  r  r   rG  rH  rF  r  r>  r?  s   @r'   r  r  |  s%   MFIKL%8 & &  &$ $UZZ $# ejj $$$$ $ jj	$
 $ $ $ $ $$%** $ $Yv4Y/

 / ,r)   r  c                       e Zd ZU dZee   ed<   dZeed<   dZ	e
ej                     ed<   dZeed<   dZeed	<   dZeed
<   y)ri   r   rj   Fis_load_as_maskNr-   r   ops_nameis_most_inner_loop_irrevelantis_load_uint8_as_float)r   r   r   rj   r   r   ra  rw  r   r-   r   rq   rx  ry  rz  rT   r)   r'   ri   ri     sQ    "C#" "OT!#'E8EKK 'Hc*/!4/ $)D(r)   ri   c                  b    	 dd l } | j                  | j                        S # t        $ r Y y w xY w)Nr   )	undefined)jinja2EnvironmentStrictUndefinedImportError)r}  s    r'   
jinja2_envr    s?    !!,, " 
 	
  s   " 	..c                   T     e Zd ZdZ fdZdefdZdefdZd Z	defdZ
d	dZ xZS )
ChoiceCallera.  
    Represents a possible choice used in autotune_process.py.
    During autotuning, self.benchmark() is first called to get benchmark result,
    and if this choice is selected, self.output_node() is called to get the output_node.

    Children classes: TritonTemplateCaller, CUDATemplateCaller.
    c                 L    t         |           || _        || _        || _        y r9   )r  rd   r+   layoutr{   )ra   r+   r{   r  r  s       r'   rd   zChoiceCaller.__init__  s$    	&r)   r   c                H    | j                         t        fd      S )Nc                        diS )NoutrT   )algor   r  s   r'   ri  z(ChoiceCaller.benchmark.<locals>.<lambda>  s    d 4 4r)   )to_callabler   )ra   r  r   r  s    ``@r'   	benchmarkzChoiceCaller.benchmark  s    !455r)   c                     t               r9   r  r   s    r'   	call_namezChoiceCaller.call_name  r   r)   c                     t               r9   r  r   s    r'   r  zChoiceCaller.to_callable  r   r)   c                     t               r9   r  r   s    r'   hash_keyzChoiceCaller.hash_key  r   r)   c                     t               r9   r  r   s    r'   output_nodezChoiceCaller.output_node  r   r)   )r   	TensorBox)r   r   r   rN  rd   r   r  r   r  r  r  r  r>  r?  s   @r'   r  r    s;    '6u 6$3 $$$# $$r)   r  c                   N    e Zd ZdZed        Zed        ZdefdZd Z	de
fdZy	)
KernelTemplatezg
    Base class for defining kernel templates.

    Children classes: TritonTemplate, CUDATemplate
    c                 >    t               }||j                  |       S y r9   )r  from_string)sourceenvs     r'   _template_from_stringz$KernelTemplate._template_from_string  s     l???6**r)   c                 J     t         j                  j                   fd}|S )Nc                 Z    | j                         k(  rj                         S  |       S r9   )get_namer   )r+   _get_dtype_realfake_outs    r'   r   z1KernelTemplate._fake_get_dtype.<locals>.get_dtype  s.    x((**))++"4((r)   )r   r]   r   )r  r   r  s   ` @r'   _fake_get_dtypezKernelTemplate._fake_get_dtype  s    ''++	)
 r)   r+   c                     || _         y r9   rF  rt  s     r'   rd   zKernelTemplate.__init__  s	    	r)   c                 f    	 |j                   | j                  di |       y# t        $ r Y yw xY w)z
        Maybe generates a new ChoiceCaller and appends it into existing choices.

        choices: A list of ChoiceCallers.
        kwargs: Additional kwargs to be passed to self.generate() to generate a new ChoiceCaller.
        NrT   )r  r  r   )ra   choicesr  s      r'   maybe_append_choicez"KernelTemplate.maybe_append_choice  s3    	NN=4==2623" 		s   !$ 	00r   c                     t               )zM
        Generates a ChoiceCaller instance from the given arguments.
        r  )ra   r  s     r'   r  zKernelTemplate.generate
  s    
 "##r)   N)r   r   r   rN  r   r  r  r   rd   r  r  r  rT   r)   r'   r  r    sL        S $L $r)   r  )^rZ  dataclassesrw   r  r#   r   r   collectionsr   r   typingr   r   r   r   r	   r
   r   r   r   r   r:  sympy.printing.printerr   rq   torch.fxtorch.utils._sympy.value_rangesr   r   r   r   utilsr   r   r   r   r   r   r   r   virtualizedr   r   r   _logginggetArtifactLoggerr   r!   r(   r*   r/   r1   r4   r   ra  r   r:   r=   r?   rZ  rG   	lru_cacherU   bfloat16r   float16r   float32float64int8int16int32r   uint8r   rW   r   r   r
  rA  rP  r^  rc  r   r  r  r  r  r  	dataclassri   r  r  r  )r-   s   0r'   <module>r     s         	 "     *   7 	 	 	 + *~~//*E=
 {$RS	
Y 0
1?\;L,MN,.c=() .0WW$(WBFWUc U3 UD$4 U T " 
NNEKK	MM5;; JJMMMMJJKKKKKKKK	
	
E 	u	
 &z; z;z=5' =5@;@K ;@|>5 >5B-# -0> *Z 
I IX 2: U Up(
) (
V
< 
<g,W g,T	 ) ) ) T $ $@.$ .$O#s   
I>