o
    ei                     @   s  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 d dlZd dlZd dlZd dlm  mZ d dlmZ d dlmZ d dlmZmZ d dlmZ eeZz@d dl Z d	e j!d
e"fddZ#dd Z$eG dd dZ%deddd
efddZ&G dd dejj'Z(G dd dZ)G dd dZ*W n e+y   dZ,g dZ-Y nw dZ,g dZ-d dl.m/Z0 d
e1fd d!Z2d
e3fd"d#Z4d$d% Z5G d&d' d'eZ6G d(d) d)eZ7e5  d*d+ Z8dS ),    N)Callable)	dataclass)AnyOptionalUnion)TorchDynamoException)dynamo_timed)ArgumentTarget)sympy_interpereturnc           
         s  t | std|  dt jdtt fdd}t | } t | s)td|  t 	| s3t 
| r7|  S |  }| t|}|| }t jkrOd}nt jt jfv rc fdd	  | }nt jkr|  d
krwtd|   | d}t |std|  }t jdt jdt jdi}||v r|| }||}nEt jt jfv r|  d
krtd|   t| d}|drd|dd   S |S t jkr|  dkrtd|   t|S |d d| }	d|	  dS )Nzunsupported expression type: r   r   c                    s    fddt   D S )Nc                    s   g | ]	}t  |qS  )z3strarg).0ir   r   i/var/www/addictedbytheproject.nl/epg/venv/lib/python3.10/site-packages/torch/fx/experimental/validator.py
<listcomp>B   s    z/z3str.<locals>.get_args_str.<locals>.<listcomp>)rangenum_argsr   r   r   r   get_args_strA   s   zz3str.<locals>.get_args_strzcan't print Z3 expression: powc                    s@   t  r   kst gS  fddt  D S )Nc                    s$   g | ]}  |D ]}|qqS r   )r   )r   r   x)collect_str_argsr   r   r   r   `   s    z3z3str.<locals>.collect_str_args.<locals>.<listcomp>)z3is_appdeclkindr   r   r   r   r   r   r   r   r   \   s
   

zz3str.<locals>.collect_str_args   zExpected 1 arg, got r   zExpected z3 appz!=><z(/z(idiv   zExpected 0 args, got  ())r   is_exprAssertionErrorExprRefliststrsimplifyr   
ValueErroris_int_valueis_rational_value	as_stringr   r   Z3_OP_POWER	Z3_OP_ADD	Z3_OP_MUL	Z3_OP_NOTr   r   Z3_OP_EQZ3_OP_LEZ3_OP_GEZ3_OP_TO_INTZ3_OP_TO_REALr   
startswithZ3_OP_UNINTERPRETEDjoinrstrip)
r   r   r   opargsr   argkindlogic_inverseargstrstringr   r    r   r   =   sZ   










r   c                    s   t   fdd}|S )Nc                    sB   d urt dd |D r| S tdd |D }t | S )Nc                 s   s    | ]	}t |tjV  qd S N)
isinstancer   BoolRef)r   r   r   r   r   	<genexpr>   s    
z/_bitwise_op.<locals>.wrapper.<locals>.<genexpr>c                 s   s    | ]	}t |d V  qdS )@   N)r   Int2BVr   ar   r   r   rH      s    )alltupler   BV2Int)selfr@   wrapped_argsbitwise_func	bool_funcr   r   wrapper   s   z_bitwise_op.<locals>.wrapper)	functoolswraps)rS   rT   rU   r   rR   r   _bitwise_op   s   	rX   c                   @   s  e Zd ZU ded< edejdejfddZedejdejfddZd	ejdejfd
dZ	dejdejdejfddZ
dejdejfddZdejdejdejfddZdejdejfddZdejdejfddZdejdejdejfddZdejdejdejfddZdejd ejdejfd!d"Zd#ejd$ejdejfd%d&Zdejdejfd'd(Zdejdejfd)d*Zdejdejfd+d,ZeejejZeejejZeejd-Zeejd-Zd-S )._Z3OpsTranslationValidator	validatorr   r   c                 C      |   r| S t| S rE   )is_realr   ToRealr   r   r   r   to_real      z_Z3Ops.to_realc                 C   r\   rE   )is_intr   ToIntr_   r   r   r   to_int   ra   z_Z3Ops.to_intr@   c                 C   s   t |S rE   )sum)rP   r@   r   r   r   sym_sum   s   z_Z3Ops.sym_sum	numeratordenominatorc                 C   s$   | j |dk t|t| S Nr   )r[   add_assertionrY   r`   rP   rg   rh   r   r   r   div   s   z
_Z3Ops.divnumberc                 C   
   t |S rE   )rY   rd   rP   rm   r   r   r   floor   s   
z_Z3Ops.floorc                 C   s4   |  p|  }t| ||}|rt|S |S rE   )r]   rY   rd   rl   r`   )rP   rg   rh   cast_result_to_realresultr   r   r   floordiv   s   z_Z3Ops.floordivc                 C   s"   t | ||k | |d |S Nr!   )r   Ifrp   ro   r   r   r   ceil   s   "z_Z3Ops.ceilc                 C   s   t |dk| || |S ri   )r   ru   rp   rv   ro   r   r   r   trunc   s   z_Z3Ops.truncrL   bc                 C   s   t ||k||S rE   r   ru   rP   rL   rx   r   r   r   max      z
_Z3Ops.maxc                 C   s   t ||k ||S rE   ry   rz   r   r   r   min   r|   z
_Z3Ops.minpqc                 C   s   ||  |||  S rE   )rs   rP   r~   r   r   r   r   mod      z
_Z3Ops.modbaseexpc                 C   s$   | j t|dk|dk || S ri   )r[   rj   r   OrrP   r   r   r   r   r   r      s   z
_Z3Ops.powc                 C   s"   t |}| j|dk |d S )Nr         ?)rY   r`   r[   rj   ro   r   r   r   sqrt   s   
z_Z3Ops.sqrtc                 C   rn   rE   )r   Absro   r   r   r   abs      
z
_Z3Ops.absc                 C   s4   t | |t ddk| |d | |d S )Nr$   r   )r   ru   r   IntValrv   rp   ro   r   r   r   round_to_int   s
   	z_Z3Ops.round_to_intN) __name__
__module____qualname____annotations__staticmethodr   ArithRefr`   rd   rf   rl   rp   rs   rv   rw   r{   r}   r   r   r   r   r   rX   operatorand_Andbitwise_andor_r   
bitwise_orlshiftrshiftr   r   r   r   rY      s:   
 
		rY   r?   r[   rZ   c                    sT  t jh}| |v   fdd}t|}i t j|tjt j||jt j||jt j	||j	t j
||j
t j||jt j||jt j||jt j||jtj||jtj||jtj||jtj||jtj||jtj||jtj||jtj||jtj|dd tj ||j!tj"tj"i}| |v r||  S || S )Nc                    s0   dt jffddt  fdd}|S )Nr   c                    s   t | tjtjfr| S t | ts rt | trtt| S t | ttjfr-t	t| S t | t
tjfr<tt
| S tdt|  )Nzcan't lift type: )rF   r   r   rG   boolintBoolValsympyIntegerr   floatFloatRealValr.   type)rL   as_boolr   r   wrap  s   z z3op.<locals>.lift.<locals>.wrapc                     s`   t | dkr!t| d ttfr!tfdd| d D f} | S tfdd| D } | S )Nr!   r   c                 3       | ]} |V  qd S rE   r   rK   r   r   r   rH   ,      z6z3op.<locals>.lift.<locals>.wrapper.<locals>.<genexpr>c                 3   r   rE   r   rK   r   r   r   rH   .  r   )lenrF   r+   rN   )r@   rQ   funcr   r   r   rU   (  s
   z#z3op.<locals>.lift.<locals>.wrapper)r   r*   rV   rW   )r   rU   r   r   r   lift  s   	zz3op.<locals>.liftc                 S   s   | r|S |S rE   r   )rx   tfr   r   r   <lambda>J  s    zz3op.<locals>.<lambda>)#r   not_rY   r   Notr   r   r   r   r   r   rs   truedivrl   r   r   builtinsroundr   mathrv   rp   rw   torch	sym_floatr`   sym_maxr{   sym_minr}   rf   sym_ite	_sym_sqrtr   _assert)r?   r[   boolean_opsr   opsreplacement_mapr   r   r   z3op  sX   	
r   c                       s   e Zd Zdejjddf fddZdedee	df d	e
eef d
efddZdedee	df d	e
eef d
ef fddZ  ZS )PopulateValidatorgraphr[   rZ   c                    s*   || _ tjji |d}t j|dd d S )N)rootr   T)garbage_collect_values)r[   r   fxGraphModulesuper__init__)rP   r   r[   module	__class__r   r   r   \  s   zPopulateValidator.__init__targetr@   .kwargsr   c                 C   s   t  d }| j|S )Nsymbol)fx_tracebackget_current_metar[   z3var)rP   r   r@   r   r   r   r   r   placeholderd  s   zPopulateValidator.placeholderc                    sV   |t jurt t|| j||S t|dkr!tdt| d| j|d  d S )Nr!   z'expected 1 argument on assertion. Got: r%   r   )	r   r   r   call_functionr   r[   r   r)   add_source_expr)rP   r   r@   r   r   r   r   r   j  s   
zPopulateValidator.call_function)r   r   r   r   r   Graphr   r
   rN   r	   dictr,   r   r   r   __classcell__r   r   r   r   r   [  s(    




r   c                   @   s  e Zd Zh dZ				d3ddZded	ejdej	fd
dZ
dejd	ejdejfddZdejd	ejdejfddZdejd	ejdejfddZdejdejdejfddZdejdejdejfddZdejdejdejfddZdejdejdejfddZdejdejdejfdd Zdejdejdejfd!d"Zd#ejd$ejdejfd%d&Zd#ejd$ejdejfd'd(Zdejd	ejdejfd)d*Zdejd	ejdejfd+d,Zd-edefd.d/Zd0ejdej	fd1d2ZdS )4	SympyToZ3>   eqgegtleltneaddmulr[   rZ   r   Nc                 C   s   || _ t| j | _d S rE   )
_validatorrY   _ops)rP   r[   r   r   r   r     s   zSympyToZ3.__init__valuedtypec                 C   sV   |t ju rtt|S |t ju rtt|S |t ju r$t	t|S t
d| )Nzunsupported dtype (SympyToZ3): )r   int64r   r   r   doubler   r   r   r   r.   )rP   r   r   r   r   r   constant  s   


zSympyToZ3.constantr   c                 C   s$   |t jkr
t|S td| d)Nz	to_dtype z NYI)r   float64r   r^   NotImplementedErrorrP   r   r   r   r   r   to_dtype  s   

zSympyToZ3.to_dtypec                 C   rn   rE   )r   rc   r   r   r   r   trunc_to_int  r   zSympyToZ3.trunc_to_intc                 C      | j |S rE   )r   r   r   r   r   r   r        zSympyToZ3.round_to_intrg   rh   c                 C      | j ||S rE   r   rl   rk   r   r   r   int_truediv     zSympyToZ3.int_truedivc                 C   r   rE   r   rk   r   r   r   r     r   zSympyToZ3.truedivc                 C   r   rE   r   rs   rk   r   r   r   rs     r   zSympyToZ3.floordivc                 C   r   rE   r   rk   r   r   r   rl        zSympyToZ3.divr   r   c                 C   r   rE   r   r   r   r   r   r   r     r   zSympyToZ3.powc                 C   r   rE   r   r   r   r   r   pow_by_natural  r   zSympyToZ3.pow_by_naturalr~   r   c                 C   r   rE   r   r   r   r   r   r   r     r   zSympyToZ3.modc                 C   r   rE   r   r   r   r   r   
python_mod  r   zSympyToZ3.python_modc                 C   r   rE   )r   rv   r   r   r   r   ceil_to_int  r   zSympyToZ3.ceil_to_intc                 C   r   rE   )r   rp   r   r   r   r   floor_to_int  r   zSympyToZ3.floor_to_intnamec                 C   st   t jt jt j| jj| jj| jj| jj| jj	| jj
| jj| jjd}||v r)|| S || jv r3tt|S td| )N)r   r   r   r   r   r   r   rp   rv   minimummaximumzunhandled operator: )r   r   r   r   r   r   r   r   r   rp   rv   r}   r{   OPERATOR_HANDLESgetattrr   AttributeError)rP   r   REPLACEMENTr   r   r   __getattr__  s"   

zSympyToZ3.__getattr__exprc                 C   s   t | | jj|S rE   )r   r   symbols)rP   r  r   r   r   run  s   zSympyToZ3.run)r[   rZ   r   N)r   r   r   r   r   r   r   r   r   r*   r   r   r   r   r   r   r   rs   rl   r   r   r   r   r   r   r,   r  r   Basicr  r   r   r   r   r   ~  sR    




r   c                   @   s   e Zd ZdddZdejdejfddZdejde	dejfd	d
Z
dejddfddZdejdejfddZdejddfddZdddZdeejejf ddfddZdddZdddZdS )rZ   r   Nc                 C   s,   t d i | _t | _t | _t | _d S )Nznew instance)logdebugr  set_source_exprs_target_exprs_assertionsrP   r   r   r   r     s
   
zTranslationValidator.__init__r   c                 C   s"   || j vrtd| | j | S )NzZ3 variable not found for: )r  r)   )rP   r   r   r   r   r     s   

zTranslationValidator.z3varr   c                 C   s   || j v r
| j | S td|j|j |tu r)t|j}|jr(| j	
|dk n|tu r4t|j}n|tu r?t|j}ntd| || j |< |S )Nznew variable: %s (%s)r   z"unsupported type for Z3 variable: )r  r	  r
  r   r   r   r   Intis_positiver  r   r   Realr   BoolRuntimeError)rP   r   r   varr   r   r   add_var  s   


zTranslationValidator.add_varr   c                 C   s8   |j D ]}t|tjstdt| | | qd S )NzExpected sympy.Symbol, got )free_symbolsrF   r   Symbolr)   r   r   )rP   r   sr   r   r   _check_freesymbols  s
   
z'TranslationValidator._check_freesymbolsc                 C   s,   t | |}t|tjstd| |S )Nz"expected boolean expression. Got: )r   r  rF   r   rG   r)   rP   r   z3exprr   r   r   to_z3_boolean_expr#  s   z'TranslationValidator.to_z3_boolean_exprc                 C   s*   || j vrtdt| | j | d S )Nzadd source guard: %s)r  r	  r
  r   r   )rP   r   r   r   r   r   )  s   
z$TranslationValidator.add_source_exprsympy.logic.boolalg.Booleanc                 C   s>   |  | | |}|| jvrtdt| | j| d S )Nzadd target guard: %s)r  r  r  r	  r
  r   r   r  r   r   r   add_target_expr.  s
   


z$TranslationValidator.add_target_exprc                 C   sn   t |tjr| | | |}n|}t |tjs"tdt| || j	vr/t
dt| | j	| d S )NzExpected z3.BoolRef, got zadd assertion: %s)rF   r   r  r  r  r   rG   r)   r   r  r	  r
  r   r   )rP   r   refr   r   r   rj   5  s   

z"TranslationValidator.add_assertionc                 C   s4   t d |  W  d    S 1 sw   Y  d S )NTranslationValidator.validate)r   	_validater  r   r   r   validateA  s   
$r!  c                    s   t | jdkst | jdkrd S td}|jt d | jD ]}|| q|t	tj
| j  |j| j  td | }|tjkr]|  t | j| j fdd| jD d|tjkritd d S |tjkrutd	| td
 d S )Nr   QF_NRA)timeoutztranslation validation: startc                    s   g | ]	}  |s|qS r   )evaluate)r   inpmodelr   r   r   l  s
    
z2TranslationValidator._validate.<locals>.<listcomp>)failed_source_exprsz:translation validation: could not validate: got z3.unknownzExpected z3.unsat, got ztranslation validation: success)r   r  r  r   	SolverForr  translation_validation_timeoutr  r   r   r   r	  r
  checksatr)  ValidationExceptionunknownwarningunsatr)   )rP   solver	assertionrr   r(  r   r"  E  s6   





	
zTranslationValidator._validate)r   N)r   r  r   N)r   r   r   r   r   r  r   r*   r   r   r  r  r  rG   r  r   r  r   rj   r#  r"  r   r   r   r   rZ     s    


F)translation_validation_enabledr,  r/  BisectValidationExceptionT)	r   r   r   r   rZ   r6  r,  r/  r7  )_configc                   C   s   t   totjS rE   )_assert_z3_installed_if_tv_set_HAS_Z3configtranslation_validationr   r   r   r   r6    s   
r6  c                   C   s   t jS rE   )r;  r,  r   r   r   r   r,    s   r,  c                   C   s   t s	tjrtdd S d S )Nzotranslation validation requires Z3 package. Please, either install z3-solver or disable translation validation.)r:  r;  r<  r)   r   r   r   r   r9    s
   
r9  c                   @      e Zd Zdd Zdd ZdS )r/  c                    s   t stddtf fdd}dtfdd}|tt| }|ttt|}|ttt|}	|ttt|}
d| _d| d	| d
|	 d|
 | _d S )NzZ3 is requiredr   c                    s   |  d |   S )N: r   )symr(  r   r   	symbolstr  r|   z/ValidationException.__init__.<locals>.symbolstrc                 S   s   d dd | D S )N
c                 s   s    | ]}d | V  qdS )z  ==> Nr   )r   r   r   r   r   rH         zBValidationException.__init__.<locals>.joinlines.<locals>.<genexpr>)r=   )xsr   r   r   	joinlines  r   z/ValidationException.__init__.<locals>.joinlinesztranslation validation failed.zModel:
z

Assertions:
z

Target Expressions:
z

Failed Source Expressions:
)r:  r)   r,   sortedmapr   msgdetails)rP   r)  
assertionstarget_exprsr*  r@  rD  	model_strassertions_strtarget_exprs_strfailed_source_exprs_strr   r(  r   r     s$   zValidationException.__init__c                 C      | j  d| j S N

rG  rH  r  r   r   r   __str__  r|   zValidationException.__str__Nr   r   r   r   rS  r   r   r   r   r/    s    r/  c                   @   r=  )r7  c                 C   s.   d| d| | _ d|  d|j | _d S )Nz#translation validation failed when r>  z)Failure occurred while running node:
    rQ  )rG  format_noderH  )rP   validation_excr  failed_actiontraced_noder   r   r   r     s   z"BisectValidationException.__init__c                 C   rO  rP  rR  r  r   r   r   rS    r|   z!BisectValidationException.__str__NrT  r   r   r   r   r7    s    r7  c                    sT  ddl m mm} ddlm}m}m | jdt	j
jd|ffdd}d|dtf fd	d
d|dttt  dtt ffdddt	j
jdtt ffdd}| |  }|sftd d S | jrltjrn|i }dd | jjD }ddt|d }	}
}||| ||< |	|k r|	| d }
||
 }td|
|| ||||
< ||
 r|
}n|
d }	|	|k s|	|v rt||	 tstd||	 }||}| rd}n| std| d}|j}|d u rtdt|dk rtd|j dt| t|d t j!std|j dt"|d  t#||	 |d ||j$| d)Nr   )FakeTensorMetareplay_shape_env_eventsShapeEnvEvent)CURRENT_NODE_KEYShapeEnvSHAPEENV_EVENT_KEYnoder   c                    s     | j vr	td| j    S )Nz#SHAPEENV_EVENT_KEY not in node.meta)metar)   )r_  )r^  eventsr   r   get_node_event  s   
zbisect.<locals>.get_node_event	shape_envc                    s   t |tr|S t |tjrt|j S t |tjr%t|j S t |s3tdt| t	 fdd|
 D t	 fdd| D  | |jS )NzExpected FakeTensorMeta, got c                 3       | ]} |V  qd S rE   r   r   r  new_with_shape_envrc  r   r   rH     rB  z5bisect.<locals>.new_with_shape_env.<locals>.<genexpr>c                 3   rd  rE   r   re  rf  r   r   rH     rB  )rF   r   r   SymIntr_  with_shape_envSymFloatr)   r   rN   sizestridestorage_offset	is_nested)rc  fake)rY  rg  rc  r   rg    s   

z"bisect.<locals>.new_with_shape_envtracked_fakesc              
      st   |d u rt dz j fdd|D dd |D dd |D d W d S  ty9 } z|W  Y d }~S d }~ww )Nztracked_fakes is Nonec                    s   g | ]} |j qS r   )ro  rK   rf  r   r   r     s    z8bisect.<locals>.check_shapeenv_fails.<locals>.<listcomp>c                 S      g | ]}|j qS r   )sourcerK   r   r   r   r         c                 S   rr  r   )symbolic_contextrK   r   r   r   r     rt  )input_contexts)r)   produce_guardsr/  )rc  rq  r   )rg  rp  r   check_shapeenv_fails  s   z$bisect.<locals>.check_shapeenv_failsc                    s8   | j   }d |d  }|j  || jS rt   )r`  r   lintrq  )r_  rm   rc  )r^  rx  ra  rZ  r   r   check_node_fails&  s   

z bisect.<locals>.check_node_failsz2translation validation succeeded: no errors found.c                 S   s   g | ]
}|j tju r|qS r   )r   r   r   )r   r_  r   r   r   r   A  s    zbisect.<locals>.<listcomp>r!   r$   zbisecting at %s: %sz-Expected ValidationException at bisect result
evaluatingzunexpected event type: zadding runtime assertzevent.args is Nonezbisecting expects z/ to have at least 2 positional arguments. Got: z9 to have a SymPy expression as its second argument. Got: )r  rW  rX  )%torch.fx.experimental.recordingrY  rZ  r[  %torch.fx.experimental.symbolic_shapesr\  r]  r^  ra  r   r   Noder   r   r+   r/  _snapshot_tracked_fakesr	  infoshould_record_eventsr;   translation_validation_no_bisectr   nodesr   r
  rF   r)   is_evaluate_expris_defer_runtime_assertr@   r   r   r  r   r7  r`  )rc  r[  r\  r]  rb  rz  last_exception	exceptionassert_nodesleftmidrightr_  eventrW  r@   r   )rY  r^  rx  ra  rg  rZ  r   bisect  s   

$




r  )9r   rV   loggingr   r   collections.abcr   dataclassesr   typingr   r   r   r   r   torch.fxtorch.fx.tracebackr   	tracebackr   torch._dynamo.excr   torch._dynamo.utilsr   torch.fx.noder	   r
   torch.utils._sympy.interpr   	getLoggerr   r	  r   r*   r,   r   rX   rY   r   Interpreterr   r   rZ   ImportErrorr:  __all__torch.fx.experimentalr8  r;  r   r6  r   r,  r9  r/  r7  r  r   r   r   r   <module>   sT   
$ZgJ#i "