a
    ==ic "                     @   s"  d dl Z d dlmZ d dlmZmZmZmZm	Z	 d dlm  m
Z
 d dlmZ d dlmZmZmZ d dlZd dlmZmZ d dlZd dlZd dlmZ eeeef e jeeeef ddd	Zeeed
ddZdd ZG dd deZedddZ eedddZ!eedddZ"dd Z#dS )    N)Number
NumberType
TensorLikeTensorLikeTypeELEMENTWISE_TYPE_PROMOTION_KIND)tree_flatten)CallableSequenceUnion)wrapsreduce)chain)adtypereturnc                    sr   t | tr$| j kr t|  S | S t | tr<t | S t | tr\t	 fdd| D S t
dt| d S )Nc                 3   s   | ]}t | V  qd S N)_maybe_convert_to_dtype.0xr    f/home/droni/.local/share/virtualenvs/DPS-5Je3_V2c/lib/python3.9/site-packages/torch/_prims/wrappers.py	<genexpr>!       z*_maybe_convert_to_dtype.<locals>.<genexpr>z7Received type {0} that is neither a tensor or a number!)
isinstancer   r   primsZconvert_element_typer   utilsZdtype_to_typer	   tuple
ValueErrorformattype)r   r   r   r   r   r      s    



r   )r   typr   c                 C   sR   t | ts dt| }t|tt| |sJd| t| |}t||| S )Nz6Found unknown type {0} when trying to convert scalars!z9Scalar {0} of type {1} cannot be safely cast to type {2}!)r   r   r    r!   r   r   Zis_weakly_lesser_type)r   r"   msgr   r   r   _maybe_convert_to_type(   s    

r$   c                 C   s4   t |dr,|jD ]}t| |dr dS qdS | |u S )N__args__)r"   
annotationTF)hasattrr%   _annotation_has_type)r"   r&   r   r   r   r   r(   5   s    

r(   c                   @   s:   e Zd ZdZddeee dddZeeddd	Z	dS )
"elementwise_type_promotion_wrappera  
    Adds elementwise type promotion to a Python reference implementation.

    Takes two kwargs, type_promoting_args and type_promotion_kind.

    type_promoting_args must be a string Sequence specifiying the argument names of all
    arguments that participate in type promotion (and should be type promoted). If the
    arg specifies a Sequence-type then every element of the Sequence will participate in
    type promotion.

    type_promotion_kind must be one of the kinds specified by ELEMENTWISE_TYPE_PROMOTION_KIND.
    See its documentation for details.

    Other type promotion behavior, like validating the Python type of scalar arguments, must
    be handled separately.
    N)type_promoting_args)type_promotion_kindr*   c                C   s   || _ || _d S r   )type_promoting_arg_namesr+   )selfr+   r*   r   r   r   __init__Q   s    z+elementwise_type_promotion_wrapper.__init__fnr   c                    s,   t  t  fdd}|_|S )Nc                     s   j | i | t fddjD }t|d }tj|dji\} fddjD } j| f i  j}t	|t
sJ t||S )Nc                 3   s&   | ]}| j  v r j | V  qd S r   )	argumentskeysr   )boundr   r   r   `   s   zKelementwise_type_promotion_wrapper.__call__.<locals>._fn.<locals>.<genexpr>r   r+   c                    s,   i | ]$}| j  v r|t j | qS r   )r1   r2   r   r   r3   Zcompute_dtyper   r   
<dictcomp>l   s   zLelementwise_type_promotion_wrapper.__call__.<locals>._fn.<locals>.<dictcomp>)bindr   r,   r   r   Zelementwise_dtypesr+   r1   updater   r   r   )argskwargsr*   Zflattened_type_promoting_argsZresult_dtypeZpromoted_argsresultr0   r-   sigr4   r   _fn]   s"    
z8elementwise_type_promotion_wrapper.__call__.<locals>._fn)inspect	signaturer   __signature__)r-   r0   r=   r   r;   r   __call__Z   s
    
z+elementwise_type_promotion_wrapper.__call__)
__name__
__module____qualname____doc__r   r	   strr.   r   rA   r   r   r   r   r)   ?   s   	r)   outc                 C   s^   |   dkrt| |S |   ttj|dkrZdt| jt|}t	
| t| |S | S )Nr      aY  An output with one or more elements was resized since it had shape {0} which does not match the required output shape {1}. This behavior is deprecated, and in a future PyTorch release outputs will not be resized unless they have zero elements. You can explicitly reuse an out tensor t by resizing it, inplace, to zero elements with t.resize_(0).)Znumelr   resizer   operatormulr    rF   shapewarningswarn)rH   rM   r#   r   r   r   _maybe_resize_out~   s    	
rP   	copy_fromcopy_toc                 C   sZ   | j |j kr$d| j |j }t|tj| j|jdsNd| j|j}t|t|| S )NzZAttempting to copy from device {0} to device {1}, but cross-device copies are not allowed!)Z	cast_fromZcast_tozhAttempting to cast from {0} to out tensor with dtype {1}, but this can't be cast because it is not safe!)Zdevicer    RuntimeErrorr   Zcan_safe_cast_tor   r   rS   )rR   rS   r#   r   r   r   _safe_copy_out   s    rU   r/   c                    st   t  dd fdd
}t }tjdtjjdtd}t|j |f}tj	||j
d|_ j|_t|jd< |S )z
    Adds the out parameter to a Python reference.

    Note that this currently only supports operations that return a single tensor.
    NrG   c                    s@    |i |}| d ur<t | ts$J t| |j} t|| dS |S NrQ   )r   r   rP   rM   rU   )rH   r8   r9   r:   r0   r   r   r=      s     zout_wrapper.<locals>._fnrH   kinddefaultr&   
parametersreturn_annotation)r   r>   r?   	ParameterKEYWORD_ONLYr   r   r\   values	Signaturer]   r@   __annotations__)r0   r=   r<   Z	out_paramparamsr   rW   r   out_wrapper   s     	

rd   c                     s   t t d fdd}|S )Nr/   c              	      s   t   fdd}t }g }D ] }|tj|tjjd td q(t|j	 |}tj
||jd|_ j|_D ]}t|j|< qx|S )Nc            	         s   i }d }D ]>}| |d ||< |d u r6|| d u}q||| d uksJ q | i |}t|tshJ |rg }tD ]D\}}|| }t|tsJ t||| j}|t|| |d qxt|S |S rV   )	popr   r   	enumerater   rP   rM   appendrU   )	r8   r9   Z
out_kwargsZhas_out_kwargsor:   Zfinal_resultirH   )r0   	out_namesr   r   r=      s$    z*out_wrapper_multi.<locals>.go.<locals>._fnrX   r[   )r   r>   r?   rg   r^   r_   r   r   r\   r`   ra   r]   r@   rb   )r0   r=   r<   Z
out_paramsrh   rc   rj   rW   r   go   s*    
zout_wrapper_multi.<locals>.go)r   )rj   rl   r   rk   r   out_wrapper_multi   s    ,rm   )$ZtorchZtorch._primsZ_primsr   Ztorch._prims.utilsr   r   r   r   r   r   Ztorch.utils._pytreer   typingr   r	   r
   r>   	functoolsr   r   rK   rN   	itertoolsr   r   r   r!   r$   r(   objectr)   rP   rU   rd   rm   r   r   r   r   <module>   s(   
?!