o
    i:$                     @   sl   d dl Z d dlmZ d dlZd dlZd dlmZmZ g dZG dd dZ	dd Z
d	d
 ZG dd dZdS )    N)OrderedDict)AnyTuple)RemovableHandleunserializable_hookwarn_if_has_hooksBackwardHookc                   @   s   e Zd ZU dZeed< dZeed< dddeded	dfd
dZdddZ	dd Z
dddZdddZdededed	dfddZdS )r   a]  
    A handle which provides the capability to remove a hook.

    Args:
        hooks_dict (dict): A dictionary of hooks, indexed by hook ``id``.
        extra_dict (Union[dict, List[dict]]): An additional dictionary or list of
            dictionaries whose keys will be deleted when the same keys are
            removed from ``hooks_dict``.
    idr   next_idN)
extra_dict
hooks_dictr   returnc                C   sj   t || _tj| _t jd7  _d| _t|tr"t |f| _d S t|t	r3t
dd |D | _d S d S )N    c                 s       | ]}t |V  qd S Nweakrefref.0dr   r   `/var/www/html/eduruby.in/lip-sync/lip-sync-env/lib/python3.10/site-packages/torch/utils/hooks.py	<genexpr>        z+RemovableHandle.__init__.<locals>.<genexpr>)r   r   hooks_dict_refr   r
   r	   extra_dict_ref
isinstancedictlisttuple)selfr   r   r   r   r   __init__   s   

zRemovableHandle.__init__c                 C   sR   |   }|d ur| j|v r|| j= | jD ]}| }|d ur&| j|v r&|| j= qd S r   )r   r	   r   )r!   r   r   r   r   r   r   remove"   s   
zRemovableHandle.removec                 C   s8   | j d u r|  | jfS |  | jtdd | j D fS )Nc                 s   s    | ]}| V  qd S r   r   )r   r   r   r   r   r   0   s    z/RemovableHandle.__getstate__.<locals>.<genexpr>)r   r   r	   r    r!   r   r   r   __getstate__,   s   
 zRemovableHandle.__getstate__c                 C   s   |d d u rt t | _nt |d | _|d | _ttj| jd t_t|dk s1|d d u r6d| _	d S t
dd |d D | _	d S )Nr   r         r   c                 s   r   r   r   r   r   r   r   r   >   r   z/RemovableHandle.__setstate__.<locals>.<genexpr>)r   r   r   r   r	   maxr   r
   lenr   r    )r!   stater   r   r   __setstate__2   s   

zRemovableHandle.__setstate__c                 C   s   | S r   r   r$   r   r   r   	__enter__@   s   zRemovableHandle.__enter__typevaluetbc                 C   s   |    d S r   )r#   )r!   r-   r.   r/   r   r   r   __exit__C   s   zRemovableHandle.__exit__)r   N)r   r   )__name__
__module____qualname____doc__int__annotations__r
   r   r"   r#   r%   r+   r,   r0   r   r   r   r   r   	   s   
 




r   c                 C   s
   d| _ | S )z
    Decorator which marks a function as an unserializable hook.
    This suppresses warnings that would otherwise arise if you attempt
    to serialize a tensor that has a hook.
    T)__torch_unserializable__)fr   r   r   r   G   s   r   c                 C   sD   | j r| j D ]}| j | }t|dstdt| d qd S d S )Nr7   zbackward hook z on tensor will not be serialized.  If this is expected, you can decorate the function with @torch.utils.hooks.unserializable_hook to suppress this warning)Z_backward_hookshasattrwarningswarnrepr)Ztensorkhookr   r   r   r   Q   s   


r   c                   @   sH   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )r   a  
    A wrapper class to implement nn.Module backward hooks.
    It handles:
      - Ignoring non-Tensor inputs and replacing them by None before calling the user hook
      - Generating the proper Node to capture a set of Tensor's gradients
      - Linking the gradients captures for the outputs with the gradients captured for the input
      - Calling the user hook once both output and input gradients are available
    c                 C   s4   || _ || _|| _d | _d| _d | _d| _d | _d S )N)
user_hooksuser_pre_hooksmodulegrad_outputs	n_outputsoutput_tensors_indexn_inputsinput_tensors_index)r!   rB   r@   rA   r   r   r   r"   e   s   
zBackwardHook.__init__c                 C   s.   d g| }t ||D ]\}}|||< q
t|S r   )zipr    )r!   indicesvaluessizeresidxvalr   r   r   _pack_with_nonep   s   

zBackwardHook._pack_with_nonec                 C   s$   g }|D ]	}| ||  qt|S r   )appendr    )r!   rI   rJ   rL   rM   r   r   r   _unpack_nonew   s   zBackwardHook._unpack_nonec                    s    fdd}| | d S )Nc                    s    j d u rd S   j|  j} jD ]'}| j| j }|d u r"qt|t|kr8tdt| dt| |}qd  _   j|S )Nz<Backward hook returned an invalid number of grad_input, got , but expected )	rC   rO   rG   rF   r@   rB   r)   RuntimeErrorrQ   )Z
grad_input_rL   r>   outr$   r   r   r>      s    

z)BackwardHook._set_user_hook.<locals>.hookregister_hook)r!   grad_fnr>   r   r$   r   _set_user_hook~   s   zBackwardHook._set_user_hookc                 C   s   g }g }d}t |D ]\}}t|tjr#|| || ||jO }q
|r*t s.|d fS tjjj	j
j| }t|dkrAtddd |D }	t|	dkrRtd||	d  t|}
t||D ]\}}||
|< qat|
|fS )NFr   zCCannot set Module backward hook for a Module with no input Tensors.c                 S   s*   g | ]}|j d ur|j  dkr|j qS )NZBackwardHookFunctionBackward)rX   name)r   tr   r   r   
<listcomp>   s   * z2BackwardHook._apply_on_tensors.<locals>.<listcomp>zaError while setting up backward hooks. Please open an issue with a code sample to reproduce this.)	enumerater   torchZTensorrP   requires_gradZis_grad_enablednnmodulesZ
_functionsZBackwardHookFunctionapplyr)   rS   r   rH   r    )r!   fnargsZtensors_idxZtensorsr_   iargZnew_tensorsZgrad_fnsarg_listrM   rN   r   r   r   _apply_on_tensors   s,   



zBackwardHook._apply_on_tensorsc                    s0    fdd}  ||\}}t| _| _|S )Nc                    s     |  d S r   )rY   )rX   r$   r   r   rc      s   z)BackwardHook.setup_input_hook.<locals>.fn)rh   r)   rF   rG   )r!   rd   rc   rL   Z	input_idxr   r$   r   setup_input_hook   s
   
zBackwardHook.setup_input_hookc                    sT    fdd}d}t |ts|f}d} ||\}}t| _| _|s(|d }|S )Nc                    s    fdd}|  | d S )Nc           	         s     j| j _ jr9t j} jD ]#}| j j}|d u r#qt|}||kr5td| d| | _q jd u rm  g g  j	} j
D ] }| j| j}|d urit|tretdd |D sitdqId  _ jd ur jd usyJ t fdd jD S d S )NzABackward pre hook returned an invalid number of grad_output, got rR   c                 s   s    | ]}|d u V  qd S r   r   )r   elr   r   r   r      s    zKBackwardHook.setup_output_hook.<locals>.fn.<locals>.hook.<locals>.<genexpr>zoBackward hook for Modules where no input requires gradient should always return None or None for all gradients.c                 3   s    | ]} j | V  qd S r   )rC   )r   re   r$   r   r   r      r   )rO   rE   rD   rC   rA   r)   rB   rS   rG   rF   r@   r   r    all)	rT   Zgrad_outputexpected_lenZuser_pre_hookZhook_grad_outputsZ
actual_lenZgrad_inputsZ	user_hookrL   r$   r   r   r>      s<   



$
z8BackwardHook.setup_output_hook.<locals>.fn.<locals>.hookrV   )rX   r>   r$   r   r   rc      s   !z*BackwardHook.setup_output_hook.<locals>.fnTFr   )r   r    rh   r)   rD   rE   )r!   rd   rc   is_tuplerL   Z
output_idxr   r$   r   setup_output_hook   s   $

zBackwardHook.setup_output_hookN)r1   r2   r3   r4   r"   rO   rQ   rY   rh   ri   rn   r   r   r   r   r   [   s    	!	r   )r^   collectionsr   r   r:   typingr   r   __all__r   r   r   r   r   r   r   r   <module>   s    >

