U
    yh'                      @   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	Z	m
Z
mZmZ ddlmZ ddlmZ G d	d
 d
eZe jG dd dZe
jeedddZeedddZdd Zdd ZejZejZejZdS )    N)	dataclass)AnyCallableDictOptionalProtocol   )_C_opsautogradTensor)_pytree   )utilsc                   @   s&   e Zd ZU ee ed< ee ed< dS )InfoProtocol_backward_fn_setup_context_fnN__name__
__module____qualname__r   r   __annotations__ r   r   I/var/www/html/venv/lib/python3.8/site-packages/torch/_library/autograd.pyr      s   
r   c                   @   s&   e Zd ZU ee ed< ee ed< dS )Infor   r   Nr   r   r   r   r   r      s   
r   )opinforeturnc                    s   dj  dj dj }tjtG dd dfdd}fdd}t|tj	ft
|t
|d	 j}td
d |j|jD rt   fdd}|S )NZGeneratedBackwardFor__c                   @   s(   e Zd ZU ejed< eeef ed< dS )z$make_autograd_impl.<locals>.Metadatakeysetkeyword_only_argsN)	r   r   r   r	   ZDispatchKeySetr   r   strr   r   r   r   r   Metadata   s   

r"   c              
      s   |d }|d d }t  x |j}|j}j|t j@ f||}jrtj	||\}} rtj| |||d nj| ||d |W  5 Q R  S Q R X d S )N)ctxinputsZkeyword_only_inputsoutput)r$   r%   r&   )
r	   Z_AutoDispatchBelowAutogradr   r    Z
redispatchZ_after_autograd_keysetr   r   Zfill_defaults_schema)r$   argsmetadatar   kwargsresult)has_kwarg_only_argsr   r   r   r   forward!   s"    
   z#make_autograd_impl.<locals>.forwardc                    sh    j rTz*| j}| jd d | _ j | f| }W 5 || _X t|trL|dS |d fS td dd S )Nr#   zTrying to backward through zQ but no autograd formula was registered. Please use register_autograd to add one.)N)r   needs_input_grad
isinstancetupleRuntimeError)r$   gradsprev_needs_input_gradr+   )r   r   r   r   backward>   s    

z$make_autograd_impl.<locals>.backward)r-   r4   c                 s   s   | ]}t |jV  qd S N)r   Zis_tensorlist_like_typetype).0ar   r   r   	<genexpr>Y   s   z%make_autograd_impl.<locals>.<genexpr>c                    s    j || |f }|S r5   )apply)r   r(   r    r+   )	Generatedr"   r   r   autograd_impla   s    z)make_autograd_impl.<locals>.autograd_impl)Z
_namespaceZ_opnameZ_overloadnamer   r,   r'   r   r6   r   Functionstaticmethodany	argumentsZreturnssupports_tensorlist)r   r   namer-   r4   Zschemar<   r   )r;   r"   r,   r   r   r   make_autograd_impl   s(    	
rC   )clsr   c                    sb   | j | j| jtG dd d  fdd}fdd} fdd}|| _ || _|| _| S )	a4  Allows a given autograd.Function class to support List[Tensor] inputs/outputs.

    Regular autograd.Function has a constraint that it only directly supports autograd for
    Tensors. Applying @supports_tensorlist enables an autograd.Function to support
    autograd for List[Tensor] inputs and outputs.
    c                   @   s6   e Zd ZU eed< dZee ed< dZee ed< dS )z%supports_tensorlist.<locals>.Metadata
input_specNoutput_specresult_is_tuple)	r   r   r   spec_tr   rF   r   rG   boolr   r   r   r   r"   s   s   
r"   c                    s   |d }|d d }t | s&tdtt||j}| f| }t |t|_|js\|f}t|t\}}||_	t
| drtd|| _t|S )Nr#   zNYI: calling supports_tensorlist autograd.Function.forward directly. You should probably be calling .apply instead. Please file an issue if not._pt_metadataz@Please don't set ctx._pt_metadata; PyTorch uses it to store info)r/   NotImplementedError	unflattenlistrE   r0   rG   flattennot_list_of_tensorrF   hasattrr1   rJ   )r$   r(   r)   r+   Zflat_resultrF   )r"   orig_forwardr   r   new_forwardy   s&    

z(supports_tensorlist.<locals>.new_forwardc                    s   t | dstd| j}tt||j}| j}z.tt| jd d |j| _ | f| }W 5 || _X t|t	sv|f}t
|t\}}||jkrtd| d|j dt	|d g S )NrJ   zNYI: calling supports_tensorlist autograd.Function.backward directly. This will automatically get called by PyTorch autograd. Please file an issue if you need this.r#   zRExpected the return from backward to be of the same structure as the inputs. Got: z (return from backward), z	 (inputs))rP   rK   rJ   rL   rM   rF   r.   rE   r/   r0   rN   not_list_of_optional_tensorr1   )r$   r2   r)   r3   Zgrad_inputsZflat_grad_inputsZgrad_inputs_spec)orig_backwardr   r   new_backward   s2    
 
 
z)supports_tensorlist.<locals>.new_backwardc                     st   t | td\}} |}||f }|jd k	s4ttt||j}|jspt|tsXtt	|dksht|d S |S )N)Zis_leafr   r   )
rN   rO   rF   AssertionErrorrL   rM   rG   r/   r0   len)r(   Z	flat_argsrE   r)   r+   )r"   
orig_applyr   r   	new_apply   s    z&supports_tensorlist.<locals>.new_apply)r-   r4   r:   r   )rD   rR   rU   rY   r   )r"   rX   rT   rQ   r   rA   h   s    ,rA   c                 C   s.   t | trdS t | tr*tdd | D S dS )NFc                 s   s   | ]}t |t V  qd S r5   r/   r   r7   lr   r   r   r9      s     z%not_list_of_tensor.<locals>.<genexpr>Tr/   r0   rM   r?   treer   r   r   rO      s
    

rO   c                 C   s.   t | trdS t | tr*tdd | D S dS )NFc                 s   s"   | ]}|d k	ot |t V  qd S r5   rZ   r[   r   r   r   r9      s     z.not_list_of_optional_tensor.<locals>.<genexpr>Tr]   r^   r   r   r   rS      s
    

rS   )dataclassesr   typingr   r   r   r   r    r	   r
   r   r   r   r   r   r   Z
OpOverloadrC   rA   rO   rS   Ztree_flattenrN   Ztree_unflattenrL   ZTreeSpecrH   r   r   r   r   <module>   s   Qh