U
    yhz                  	   @   s  d dl Z d dlZd dlZd dlZd dlZd dlZd dlmZ d dlm	Z	m
Z
mZmZmZmZmZmZmZ d dlZd dlZd dlm  mZ d dlmZ d dlmZmZ d dlmZ ee Z!zrd dl"Z"e"j#e$ddd	Z%eG d
d dZ&e
de
dddZ'G dd dejj(Z)G dd dZ*G dd dZ+W n& e,k
rT   dZ-ddddgZ.Y nX dZ-d	ddddddddg	Z.d dl/m0Z1 e2dddZ3e4dddZ5dd  Z6G d!d deZ7G d"d deZ8e6  d#d$ Z9dS )%    N)	dataclass)	AnyCallableDictListOptionalSetTupleTypeUnion)TorchDynamoException)ArgumentTarget)sympy_interpereturnc           
         s  t | std|  t jtt ddd}t | } t | sPtd|  t 	| sdt 
| rl|  S |  }| t|}|| }t jkrd}nt jt jfkrƇ fdd  | }nt jkr8|  d	kst| d
}t |st|  }t jdt jdt jdi}||kr|| }||}nxt jt jfkr|  d	ks\tt| d
}|drd|dd   S |S t jkr|  d
kstt|S |d d| }	d|	  dS )Nzunsupported expression type: r   c                    s    fddt   D S )Nc                    s   g | ]}t  |qS  )z3strarg).0ir   r   Q/var/www/html/venv/lib/python3.8/site-packages/torch/fx/experimental/validator.py
<listcomp>@   s     z/z3str.<locals>.get_args_str.<locals>.<listcomp>)rangenum_argsr   r   r   r   get_args_str?   s    zz3str.<locals>.get_args_strzcan't print Z3 expression: powc                    sD   t  r   ks$t gS  fddt  D S 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   r   z!=><z(/z(idiv    ())r!   Zis_exprAssertionErrorExprRefr   strsimplifyr"   
ValueErrorZis_int_valueZis_rational_value	as_stringr#   r$   ZZ3_OP_POWERZ	Z3_OP_ADDZ	Z3_OP_MULZ	Z3_OP_NOTr   r   ZZ3_OP_EQZZ3_OP_LEZZ3_OP_GEZZ3_OP_TO_INTZZ3_OP_TO_REALr   
startswithZZ3_OP_UNINTERPRETEDjoinrstrip)
r   r   r#   opargsr   ZargkindZlogic_inverseZargstrstringr   r%   r   r   <   sT    





   

r   c                   @   s:  e Zd ZU ded< eejejdddZeejejdddZejejejdd	d
Z	ejejdddZ
ejejejdddZejejdddZejejejdddZejejejdddZejejejdddZejejejdddZejejdddZejejddd Zejejdd!d"Zd#S )$_Z3OpsTranslationValidator	validator)r   r   c                 C   s   |   r| S t| S N)is_realr!   ToRealr   r   r   r   to_real   s    z_Z3Ops.to_realc                 C   s   |   r| S t| S r<   )Zis_intr!   ToIntr?   r   r   r   to_int   s    z_Z3Ops.to_int	numeratordenominatorr   c                 C   s$   | j |dk t|t| S Nr   )r;   add_assertionr9   r@   selfrD   rE   r   r   r   div   s    z
_Z3Ops.div)numberr   c                 C   s
   t |S r<   )r9   rB   rI   rK   r   r   r   floor   s    z_Z3Ops.floorc                 C   s4   |  p|  }t| ||}|r0t|S |S r<   )r=   r9   rB   rJ   r@   )rI   rD   rE   Zcast_result_to_realresultr   r   r   floordiv   s    z_Z3Ops.floordivc                 C   s"   t | ||k | |d |S Nr&   )r!   IfrM   rL   r   r   r   ceil   s
    z_Z3Ops.ceil)abr   c                 C   s   t ||k||S r<   r!   rQ   rI   rS   rT   r   r   r   max   s    z
_Z3Ops.maxc                 C   s   t ||k ||S r<   rU   rV   r   r   r   min   s    z
_Z3Ops.minpqr   c                 C   s   ||  |||  S r<   )rO   rI   rZ   r[   r   r   r   mod   s    z
_Z3Ops.modbaseexpr   c                 C   s$   | j t|dk|dk || S rF   )r;   rG   r!   OrrI   r_   r`   r   r   r   r      s    z
_Z3Ops.powc                 C   s"   t |}| j|dk |d S )Nr         ?)r9   r@   r;   rG   rL   r   r   r   sqrt   s    
z_Z3Ops.sqrtc                 C   s
   t |S r<   )r!   ZAbsrL   r   r   r   abs   s    z
_Z3Ops.absc                 C   s4   t | |t ddk| |d | |d S )Nr)   rc   )r!   rQ   r]   IntValrR   rM   rL   r   r   r   round_to_int   s
    	z_Z3Ops.round_to_intN)__name__
__module____qualname____annotations__staticmethodr!   ArithRefr@   rB   rJ   rM   rO   rR   rW   rX   r]   r   rd   re   rg   r   r   r   r   r9      s    
	r9   r:   )r6   r;   r   c                     s  t jt jt jh}| |k  fdd}t|}t j|tjt j|tj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|dd tj||jtjtji}| |kr||  S || S )Nc                    s0   t jdfddt  fdd}|S )Nr   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rZt	t| S t | t
tjfrxtt
| S tdt|  d S )Nzcan't lift type: )
isinstancer!   rm   BoolRefboolintBoolValsympyIntegerrf   floatFloatRealValr1   type)rS   Zas_boolr   r   wrap   s    z z3op.<locals>.lift.<locals>.wrapc                     s   fdd| D } | S )Nc                 3   s   | ]} |V  qd S r<   r   r   rS   )r{   r   r   	<genexpr>  s     z6z3op.<locals>.lift.<locals>.wrapper.<locals>.<genexpr>r   )r7   Zwrapped_argsfuncr{   r   r   wrapper
  s    z#z3op.<locals>.lift.<locals>.wrapper)r!   r.   	functoolswraps)r   r   rz   r~   r   lift   s    zz3op.<locals>.liftc                 S   s   | r|S |S r<   r   )rT   tfr   r   r   <lambda>'      zz3op.<locals>.<lambda>)operatornot_and_or_r9   r!   NotAndra   rO   truedivrJ   r]   re   builtinsroundrg   mathrR   rM   torchZ	sym_floatr@   Zsym_maxrW   Zsym_minrX   Zsym_iteZ	_sym_sqrtrd   _assert)r6   r;   Zboolean_opsr   ZopsZreplacement_mapr   rz   r   z3op   sL                  
  r   c                       st   e Zd Zejjdd fddZeee	df e
eef edddZeee	df e
eef ed fd	d
Z  ZS )PopulateValidatorr:   )graphr;   c                    s*   || _ tjji |d}t j|dd d S )N)rootr   T)Zgarbage_collect_values)r;   r   fxZGraphModulesuper__init__)rI   r   r;   module	__class__r   r   r   9  s    zPopulateValidator.__init__.)targetr7   kwargsr   c                 C   s   t  d }| j|S )Nsymbol)fx_tracebackZget_current_metar;   z3var)rI   r   r7   r   r   r   r   r   placeholderA  s    zPopulateValidator.placeholderc                    sV   |t jkr"t t|| j||S t|dksBtdt| d| j|d  d S )Nr&   z'expected 1 argument on assertion. Got: r*   r   )	r   r   r   call_functionr   r;   lenr-   add_source_expr)rI   r   r7   r   r   r   r   r   E  s    
 zPopulateValidator.call_function)rh   ri   rj   r   r   ZGraphr   r   r	   r   r   r/   r   r   r   __classcell__r   r   r   r   r   8  s   $r   c                   @   s  e Zd ZddddddddhZd	d
dddZeejej	dddZ
ejejejdddZejejejdddZejejejdddZejejejdddZejejejdddZejejejdddZejejejddd Zejejejd!d"d#Zejejejd!d$d%Zejejejd&d'd(Zejejejdd)d*Zejejejdd+d,Zeed-d.d/Zejej	d0d1d2Zd
S )3	SympyToZ3addmuleqneltgtleger:   N)r;   r   c                 C   s   || _ t| j | _d S r<   )
_validatorr9   _ops)rI   r;   r   r   r   r   W  s    zSympyToZ3.__init__)valuedtyper   c                 C   sZ   |t jkrtt|S |t jkr0tt|S |t jkrHt	t|S t
d| d S )Nzunsupported dtype (SympyToZ3): )r   Zint64r!   rf   rr   doublerx   rv   rq   rs   r1   )rI   r   r   r   r   r   constant^  s    


zSympyToZ3.constant)r   r   r   c                 C   s(   |t jkrt|S td| dd S )Nz	to_dtype z NYI)r   Zfloat64r!   r>   NotImplementedErrorrI   r   r   r   r   r   to_dtypeh  s    

zSympyToZ3.to_dtypec                 C   s
   t |S r<   )r!   rA   r   r   r   r   trunc_to_intm  s    zSympyToZ3.trunc_to_intc                 C   s   | j |S r<   )r   rg   r   r   r   r   rg   p  s    zSympyToZ3.round_to_intrC   c                 C   s   | j ||S r<   r   rJ   rH   r   r   r   int_truedivs  s    zSympyToZ3.int_truedivc                 C   s   | j ||S r<   r   rH   r   r   r   r   v  s    zSympyToZ3.truedivc                 C   s   | j ||S r<   r   rO   rH   r   r   r   rO   y  s    zSympyToZ3.floordivc                 C   s   | j ||S r<   r   rH   r   r   r   rJ   |  s    zSympyToZ3.divr^   c                 C   s   | j ||S r<   r   r   rb   r   r   r   r     s    zSympyToZ3.powc                 C   s   | j ||S r<   r   rb   r   r   r   pow_by_natural  s    zSympyToZ3.pow_by_naturalrY   c                 C   s   | j ||S r<   )r   r]   r\   r   r   r   r]     s    zSympyToZ3.modc                 C   s   | j |S r<   )r   rR   r   r   r   r   ceil_to_int  s    zSympyToZ3.ceil_to_intc                 C   s   | j |S r<   )r   rM   r   r   r   r   floor_to_int  s    zSympyToZ3.floor_to_int)namer   c                 C   s`   t jt jt j| jj| jj| jj| jjd}||kr:|| S || j	krNt
t|S td| d S )N)r   r   r   rM   rR   minimummaximumzunhandled operator: )r!   r   ra   r   r   rM   rR   rX   rW   OPERATOR_HANDLESgetattrr   AttributeError)rI   r   ZREPLACEMENTr   r   r   __getattr__  s    


zSympyToZ3.__getattr__)exprr   c                 C   s   t | | jj|S r<   )r   r   symbols)rI   r   r   r   r   run  s    zSympyToZ3.run)rh   ri   rj   r   r   r   r   r   r!   r.   r   rm   r   r   rg   r   r   rO   rJ   r   r   r]   r   r   r/   r   rt   Basicr   r   r   r   r   r   T  s&   
r   c                   @   s   e Zd ZddddZejejdddZeje	ejdd	d
Z
ejddddZejejdddZejddddZejddddZeejejf ddddZddddZdS )r:   Nrn   c                 C   s,   t d i | _t | _t | _t | _d S )Nznew instance)logdebugr   set_source_exprs_target_exprs_assertionsrI   r   r   r   r     s
    
zTranslationValidator.__init__)r   r   c                 C   s"   || j kstd| | j | S )NzZ3 variable not found for: )r   r-   )rI   r   r   r   r   r     s    zTranslationValidator.z3var)r   ry   r   c                 C   s   || j kr| j | S td|j|j |tkrRt|j}|jr| j	
|dk n:|tkrht|j}n$|tkr~t|j}ntd| || j |< |S )Nznew variable: %s (%s)r   z"unsupported type for Z3 variable: )r   r   r   r   rh   rr   r!   ZIntZis_positiver   r   rv   Realrq   ZBoolRuntimeError)rI   r   ry   varr   r   r   add_var  s    


zTranslationValidator.add_varr   c                 C   s*   |j D ]}t|tjst| | qd S r<   )Zfree_symbolsro   rt   Symbolr-   r   )rI   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   ro   r!   rp   r-   rI   r   Zz3exprr   r   r   to_z3_boolean_expr  s    z'TranslationValidator.to_z3_boolean_exprc                 C   s*   || j krtdt| | j | d S )Nzadd source guard: %s)r   r   r   r   r   )rI   r   r   r   r   r     s    
z$TranslationValidator.add_source_exprc                 C   s>   |  | | |}|| jk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   s`   t |tjr"| | | |}n|}t |tjs6t|| jkrPt	
dt| | j| d S )Nzadd assertion: %s)ro   rt   r   r   r   r!   rp   r-   r   r   r   r   r   )rI   r   refr   r   r   rG     s    

z"TranslationValidator.add_assertionc                    s   ddl m} t| jdks(t| jdkr,d S td}|jt d | j	D ]}|
| qJ|
ttj| j  |j
| j  td | |j }|tjkr|  t | j	| j fdd| jD dn.|tjkrtd	 n|tjksttd
 d S )Nr   )dynamo_timedZQF_NRA)timeoutztranslation validation: startc                    s   g | ]}  |s|qS r   )evaluate)r   Zinpmodelr   r   r   .  s    
 z1TranslationValidator.validate.<locals>.<listcomp>)failed_source_exprsz:translation validation: could not validate: got z3.unknownztranslation validation: success)Ztorch._dynamo.utilsr   r   r   r   r!   Z	SolverForr   translation_validation_timeoutr   r   r   r   r   r   checksatr   ValidationExceptionunknownwarningZunsatr-   )rI   r   ZsolverZ	assertionrr   r   r   validate  s2    



  

zTranslationValidator.validate)rh   ri   rj   r   rt   r   r!   r.   r   r
   r   r   r   rp   r   r   Exprr   r   rG   r   r   r   r   r   r:     s   Ftranslation_validation_enabledr   r   BisectValidationExceptionT)_configrn   c                   C   s   t   totjS r<   )_assert_z3_installed_if_tv_set_HAS_Z3configtranslation_validationr   r   r   r   r   P  s    c                   C   s   t jS r<   )r   r   r   r   r   r   r   W  s    c                   C   s   t stjrtdd S )Nzotranslation validation requires Z3 package. Please, either install z3-solver or disable translation validation.)r   r   r   r-   r   r   r   r   r   [  s    r   c                   @   s   e Zd Zdd Zdd ZdS )r   c                    s   t sttd fdd}tddd}|tt| }|ttt|}|ttt|}	|ttt|}
d| _d| d| d	|	 d
|
 | _d S )Nrn   c                    s   |  d |   S )N: r   )symr   r   r   	symbolstrf  s    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   r}   j  s     zBValidationException.__init__.<locals>.joinlines.<locals>.<genexpr>)r4   )Zxsr   r   r   	joinlinesi  s    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)rI   r   Z
assertionsZtarget_exprsr   r   r   Z	model_strZassertions_strZtarget_exprs_strZfailed_source_exprs_strr   r   r   r   c  s"    zValidationException.__init__c                 C   s   | j  d| j S N

r   r   r   r   r   r   __str__  s    zValidationException.__str__Nrh   ri   rj   r   r  r   r   r   r   r   b  s   c                   @   s   e Zd Zdd Zdd ZdS )r   c                 C   s.   d| d| | _ d|  d|j | _d S )Nz#translation validation failed when r   z)Failure occurred while running node:
    r   )r   Zformat_noder   )rI   Zvalidation_excr   failed_actiontraced_noder   r   r   r     s    z"BisectValidationException.__init__c                 C   s   | j  d| j S r   r   r   r   r   r   r    s    z!BisectValidationException.__str__Nr  r   r   r   r   r     s   c                    s@  ddl m}mm} ddlm m}m | jt	j
j|dfdd}|td fdd	|ttt  tt d
fddt	j
jtt dfdd}| |  }|std d S | jrtjr|i }dd | jjD }ddt|d   }	}
}|	|k rX|	| d }
||
 }td|
|| ||||
< ||
 rL|
}n|
d }	q |	|krrt||	 tsvt||	 }||}| rd}n| std| d}|j}|d k	stt|dkstd|j dt| t|d t j!std|j dt"|d  t#||	 |d ||j$| dd S )Nr   )ShapeEnvSHAPEENV_EVENT_KEYCURRENT_NODE_KEY)FakeTensorMetaShapeEnvEventreplay_shape_env_events)noder   c                    s    | j kst| j    S r<   )metar-   )r  )r  eventsr   r   get_node_event  s    zbisect.<locals>.get_node_event)	shape_envr   c                    s   t |tr|S t |tjr,t|j S t |s:tt fdd| D t fdd|	 D  |
 |jS )Nc                 3   s   | ]} |V  qd S r<   r   r   r   new_with_shape_envr  r   r   r}     s     z5bisect.<locals>.new_with_shape_env.<locals>.<genexpr>c                 3   s   | ]} |V  qd S r<   r   r  r  r   r   r}     s     )ro   rr   r   ZSymIntr  Zwith_shape_envr-   tuplesizeZstrideZstorage_offsetZ	is_nested)r  fake)r  r  r  r   r    s    
z"bisect.<locals>.new_with_shape_env)r  tracked_fakesr   c              
      sv   |d k	st z: j fdd|D dd |D dd |D d W d S  tk
rp } z| W Y S d }~X Y nX d S )Nc                    s   g | ]} |j qS r   )r  r|   r  r   r   r     s     z8bisect.<locals>.check_shapeenv_fails.<locals>.<listcomp>c                 S   s   g | ]
}|j qS r   )sourcer|   r   r   r   r     s     c                 S   s   g | ]
}|j qS r   )Zsymbolic_contextr|   r   r   r   r     s     )Zinput_contexts)r-   Zproduce_guardsr   )r  r  r   )r  r  r   check_shapeenv_fails  s    z$bisect.<locals>.check_shapeenv_failsc                    s8   | j   }d |d  }|j  || jS rP   )r  r   Zlintr  )r  rK   r  )r  r  r  r
  r   r   check_node_fails  s    

z bisect.<locals>.check_node_failsz2translation validation succeeded: no errors found.c                 S   s   g | ]}|j tjkr|qS r   )r   r   r   )r   r  r   r   r   r     s      zbisect.<locals>.<listcomp>r&   r)   zbisecting at %s: %sZ
evaluatingzunexpected event type: zadding runtime assertzbisecting expects z/ to have at least 2 positional arguments. Got: z9 to have a SymPy expression as its second argument. Got: )r   r  r  )%Z%torch.fx.experimental.symbolic_shapesr  r  r  Ztorch.fx.experimental.recordingr  r	  r
  r  r   r   Noder   r   r   r   Z_snapshot_tracked_fakesr   infoZshould_record_eventsr   Z translation_validation_no_bisectr   Znodesr   r   ro   r-   Zis_evaluate_exprZis_defer_runtime_assertr7   r   rt   r   ry   r   r  )r  r  r  r	  r  r  Zlast_exception	exceptionZassert_nodesleftmidrightr  eventr  r7   r   )r  r  r  r  r  r
  r   bisect  sZ    	""



r"  ):r   loggingr   r   rt   r   dataclassesr   typingr   r   r   r   r   r   r	   r
   r   r   Ztorch.fxZtorch.fx.tracebackr   	tracebackr   Ztorch._dynamo.excr   Ztorch.fx.noder   r   Ztorch.utils._sympy.interpr   	getLoggerrh   r   r!   r.   r/   r   r9   r   ZInterpreterr   r   r:   ImportErrorr   __all__Ztorch.fx.experimentalr   r   rq   r   rr   r   r   r   r   r"  r   r   r   r   <module>   sd   ,
%X^E\   
      !
