a
    h+(                     @   s   d dl Z d dlZd dlmZmZmZ d dlZd dlm  m	Z
 d dlmZ d dlmZmZmZmZmZ d dlmZ ejjjZdd Zdd	 Zd
d Zdd Zdd Zeeeef  eeeejef  dddZdejedddZ G dd deZ!dS )    N)AnyCallableUnion)
OpOverload)
FakeTensorFakeTensorModeMetadataMismatchErrortree_flatten_onlyUnsupportedFakeTensorException)TorchDispatchModec                    s4   dd t tj|D  t fddt tj| D S )Nc                 S   s"   h | ]}t j|r| jqS  torch_C_has_storage_typed_storage_cdata.0inpr   r   J/var/www/auris/lib/python3.9/site-packages/torch/_subclasses/fake_utils.py	<setcomp>   s   z'outputs_alias_inputs.<locals>.<setcomp>c                 3   s(   | ] }t j|o| j v V  qd S Nr   r   outZinput_storagesr   r   	<genexpr>   s   z'outputs_alias_inputs.<locals>.<genexpr>r	   r   Tensoranyoutputsinputsr   r   r   outputs_alias_inputs   s    

r#   c                    s4   dd t tj|D  t fddt tj| D S )Nc                 S   s   h | ]}t |qS r   idr   r   r   r   r   $       z%outputs_are_inputs.<locals>.<setcomp>c                 3   s   | ]}t | v V  qd S r   r$   r   Z	input_idsr   r   r   %   r&   z%outputs_are_inputs.<locals>.<genexpr>r   r    r   r'   r   outputs_are_inputs#   s    r(   c                 C   sL   t  }ttj| D ]4}tj|s$q| j}||v r< dS || qdS )NTF)	setr	   r   r   r   r   r   r   add)r!   Zstoragesr   Zstorr   r   r   output_alias_each_other(   s    
r+   c                 C   s   t ||}t ||}||kr4t|  d| d| t||}t||}||krht|  d| d| t|}	t|}
|	|
krt|  d|
 d|	 d S )Nz( mismatch in outputs_alias_inputs check  != z& mismatch in outputs_are_inputs check z, mismatch in outputs_alias_each_other check )r#   r   r(   r+   )contextreal_outZreal_infake_outZfake_inZ
r_aliasingZ
f_aliasingZr_identity_eqZf_identity_eqZr_output_alias_each_otherZf_output_alias_each_otherr   r   r   _check_alias_info4   s,    



r0   c                 C   s   | t jju s| t jju r0|dv r0dt|v r0dS | t jju sH| t jju r`|dv r`dt|v r`dS | t jju r|dv rdt|v rdS dS )N)      ZDevicesT)      F)atenZ#_scaled_dot_product_flash_attentiondefaultZ_flash_attention_forwardreprZ'_scaled_dot_product_efficient_attentionZ_efficient_attention_forwardZ#_scaled_dot_product_cudnn_attention)funcidxer   r   r   is_sdpa_errorL   s4    







r;   )ten_listreturnc                    sT  t dd | D d}|du r | S |j}|jj}|j}dd |j D }dd |j D }g }| D ]}t|t	r~|j
tjks|| qd|| }	|	du rdn||	}
|
du r|| qddfdd	  | } fd
d|jD } fdd| D }r|| qdtjg |j|jd}|j|
|||d ||  qd|S )ai  
    Attempt to convert fake tensors to a corresponding real tensor with the correct underlying storage by looking up
    the FakeTensorMode meta to real storage mapping. On failure to find the storage mapping, the FakeTensor will
    remain in the list.

    Note: this is not currently optimized (makes copies of the meta converter internal dictionaries)
    c                 s   s   | ]}t |tr|V  qd S r   )
isinstancer   )r   itemr   r   r   r   t   r&   z+try_convert_fake_to_real.<locals>.<genexpr>Nc                 S   s   i | ]\}}||qS r   r   r   kvr   r   r   
<dictcomp>}   r&   z,try_convert_fake_to_real.<locals>.<dictcomp>c                 S   s   i | ]\}}||qS r   r   r@   r   r   r   rC   ~   r&   Fc                    s*   t | tjs| S  s n| j  | jjS r   )r>   r   ZSymIntnodeZhas_hinthint)s)unhintedr   r   
map_symint   s    z,try_convert_fake_to_real.<locals>.map_symintc                    s   g | ]} |qS r   r   r   rF   rH   r   r   
<listcomp>   r&   z,try_convert_fake_to_real.<locals>.<listcomp>c                    s   g | ]} |qS r   r   rI   rJ   r   r   rK      r&   )dtypedevice)storage_offsetsizestride)next	fake_modeZfake_tensor_convertermeta_converterZ	describerZstorage_memoitemsZlookup_storager>   r   Zlayoutr   ZstridedappendgetZuntyped_storagerN   shaperP   emptyrL   rM   set_clone)r<   Zfake_tensorrR   rS   descZstorage_to_keyZkey_to_real_storager   tkeyZreal_storageZstor_offsetrO   rP   Z
new_tensorr   )rH   rG   r   try_convert_fake_to_realh   sR    


r^    TF)r.   r/   c           	      C   sl   |r| j |j krt| dtj| rP|  }| }||krPt| dtjjj| |||dd d S )Nz mismatched requires_grad-ness of outputs. This usually means that you have added autograd support for your operator at a dispatch key other than Autograd, which will lead to problemsz mismatched storage offsetT)Zcheck_sizescheck_stridesZallow_rhs_unbacked)	requires_gradr   r   r   r   rN   Z_primsutilsZcompare_tensor_meta)	r.   r/   r-   sizesstridesrN   ra   Zr_offsetZf_offsetr   r   r   _check_fake_real_tensors   s"    	re   c                       sJ   e Zd Zd
ddddeeegef df d fddZddd	Z  Z	S )CrossRefFakeModeNT)r`   check_aliasingonly_check_ops_with_meta)ignore_op_fnc                   s6   t    |d ur|ndd | _|| _|| _|| _d S )Nc                 S   s   dS )NFr   )fnr   r   r   <lambda>   r&   z+CrossRefFakeMode.__init__.<locals>.<lambda>)super__init__ri   r`   rg   rh   )selfri   r`   rg   rh   	__class__r   r   rm      s    
zCrossRefFakeMode.__init__r   c                 C   s  |pi }d }|t jjt jjt jjfvr(| |s(| jrJtj	j
|r(tjj|jvr(tjj|jvr(tjj|jvr(ddlm} zt| dj}ttjtj|jdd||f\}}	t  ||i |	}W d    n1 s0    Y  W d    n1 s0    Y  W n ty&   Y n0 d| d}
||i |}|d urt|}t|}t|t|ksJ |
 dt| d	t| | jrt |
|||f|||	f t!t"t|t|D ]\}\}}t#|tj}|t#|tjksJ |
 d
|rzt$||d| j%ddd W n| t&y } zbt'|||rRW Y d }~qt|dkrn|
 d| n|
 d| d| }t(||W Y d }~n
d }~0 0 q|S )Nr   )ShapeEnv)Z	shape_envT)Zstatic_shapeszWhen comparing the output of z* on FakeTensor and concrete Tensors, foundz mismatch in number of returns r,   z$ mismatched number of tensor outputs)rc   rd   rN   ra      z mismatched tensor metadata: z' mismatched tensor metadata for output[z]: ))r5   Z
lift_freshr6   Zlift_fresh_copyrY   Zsource_Storage_storage_offsetri   rh   r   Z_subclassesZ
fake_implsZhas_metaTagZdynamic_output_shapetagsZinplace_viewZdata_dependent_outputZ%torch.fx.experimental.symbolic_shapesrq   r   pytreeZtree_map_onlyr   	functoolspartialZfrom_tensorwarningscatch_warningsr
   Ztree_leaveslenrg   r0   	enumeratezipr>   re   r`   	Exceptionr;   r   )rn   r8   typesargskwargsZfake_rrq   rR   Z	fake_argsZfake_kwargsr-   rZr_flatZf_flatr9   Zr_outZf_outZr_is_tenr:   error_messager   r   r   __torch_dispatch__   s    	

P







$z#CrossRefFakeMode.__torch_dispatch__)N)r   N)
__name__
__module____qualname__r   r   r   boolrm   r   __classcell__r   r   ro   r   rf      s    rf   )r_   TFTT)"rv   rx   typingr   r   r   r   Ztorch.utils._pytreerb   Z_pytreeru   Z
torch._opsr   Ztorch._subclasses.fake_tensorr   r   r   r	   r
   Ztorch.utils._python_dispatchr   Z_opsopsr5   r#   r(   r+   r0   r;   listr   r^   re   rf   r   r   r   r   <module>   s4   
G     !