U
    Mh                  	   @   s   d dl Z d dlmZmZmZmZmZmZmZ d dl	m
Z
 d dlZd dlmZ d dlmZmZmZ eejeej f ZdddgZd	d
 Zedeeeeee ejdddZe
deddeeeeee ejdddZedeeee ddddZdS )    N)UnionIterableListDictTupleOptionalcast)
deprecated)Tensor)"_group_tensors_by_device_and_dtype_has_foreach_support_device_has_foreach_supportclip_grad_norm_clip_grad_normclip_grad_value_c                    s    fdd}t |  |S )z
    This wrapper is needed to avoid a circular import when using @torch.no_grad on the exposed functions
    clip_grad_norm_ and clip_grad_value_ themselves.
    c               
      s*   t    | |W  5 Q R  S Q R X d S N)torchZno_grad)argskwargsfunc J/var/www/html/venv/lib/python3.8/site-packages/torch/nn/utils/clip_grad.py_no_grad_wrapper   s    
z"_no_grad.<locals>._no_grad_wrapper)	functoolsupdate_wrapper)r   r   r   r   r   _no_grad   s    r          @F)
parametersmax_norm	norm_typeerror_if_nonfiniteforeachreturnc                    s  t | tjr| g} dd | D }t|}tt|dkrFtdS |d j t|g}g }| D ]t\\}}	\\}
}	|dkrt	|
|s|rt
|r|t|
 qf|rtd|j dqf|fdd|
D  qftjt fd	d|D }|r*t| | r*td
 d||d  }tj|dd}| D ]\\}}	\\}
}	|dkrtt	|
|s|rt
|rt|
|| n:|rtd|j dn ||}|
D ]}|| qqL|S )aG  Clip the gradient norm of an iterable of parameters.

    The norm is computed over all gradients together, as if they were
    concatenated into a single vector. Gradients are modified in-place.

    Args:
        parameters (Iterable[Tensor] or Tensor): an iterable of Tensors or a
            single Tensor that will have gradients normalized
        max_norm (float): max norm of the gradients
        norm_type (float): type of the used p-norm. Can be ``'inf'`` for
            infinity norm.
        error_if_nonfinite (bool): if True, an error is thrown if the total
            norm of the gradients from :attr:`parameters` is ``nan``,
            ``inf``, or ``-inf``. Default: False (will switch to True in the future)
        foreach (bool): use the faster foreach-based implementation.
            If ``None``, use the foreach implementation for CUDA and CPU native tensors and silently
            fall back to the slow implementation for other device types.
            Default: ``None``

    Returns:
        Total norm of the parameter gradients (viewed as a single vector).
    c                 S   s   g | ]}|j d k	r|j qS r   grad.0pr   r   r   
<listcomp>5   s     
 z#clip_grad_norm_.<locals>.<listcomp>r   g        N:foreach=True was passed, but can't use the foreach API on  tensorsc                    s   g | ]}t j| qS r   )r   linalgvector_norm)r'   g)r    r   r   r)   H   s     c                    s   g | ]}|  qS r   )to)r'   Znorm)first_devicer   r   r)   J   s     zThe total norm of order z for gradients from `parameters` is non-finite, so it cannot be clipped. To disable this error and scale the gradients by the non-finite norm anyway, set `error_if_nonfinite=False`gư>g      ?)max)
isinstancer   r
   floatlenZtensordevicer   itemsr   r   extendZ_foreach_normRuntimeErrortyper,   r-   stack
logical_orisnanisinfclampZ_foreach_mul_r/   Zmul_)r   r   r    r!   r"   gradsgrouped_gradsZnormsr5   _Zdevice_gradsZ
total_normZ	clip_coefZclip_coef_clampedZclip_coef_clamped_devicer.   r   )r0   r    r   r      s^    

"

z_`torch.nn.utils.clip_grad_norm` is now deprecated in favor of `torch.nn.utils.clip_grad_norm_`.)categoryc                 C   s   t | ||||S )zClip the gradient norm of an iterable of parameters.

    .. warning::
        This method is now deprecated in favor of
        :func:`torch.nn.utils.clip_grad_norm_`.
    )r   )r   r   r    r!   r"   r   r   r   r   g   s    )r   
clip_valuer"   r#   c                 C   s   t | tjr| g} t|}dd | D }t|g}| D ]\\}}\\}}|dkrjtttt ||dsv|rt	|rt
ttt ||  tttt || q:|rtd|j dq:|D ]}tt|j| |d qq:dS )a  Clip the gradients of an iterable of parameters at specified value.

    Gradients are modified in-place.

    Args:
        parameters (Iterable[Tensor] or Tensor): an iterable of Tensors or a
            single Tensor that will have gradients normalized
        clip_value (float): maximum allowed value of the gradients.
            The gradients are clipped in the range
            :math:`\left[\text{-clip\_value}, \text{clip\_value}\right]`
        foreach (bool): use the faster foreach-based implementation
            If ``None``, use the foreach implementation for CUDA and CPU native tensors and
            silently fall back to the slow implementation for other device types.
            Default: ``None``
    c                 S   s   g | ]}|j d k	r|j qS r   r$   r&   r   r   r   r)      s     
 z$clip_grad_value_.<locals>.<listcomp>N)r5   r*   r+   )minr1   )r2   r   r
   r3   r   r6   r   r   r   r   Z_foreach_clamp_min_Z_foreach_clamp_max_r8   r9   Zclamp_)r   rC   r"   r?   r@   r5   rA   r%   r   r   r   r   x   s(    
)r   FN)r   FN)N)r   typingr   r   r   r   r   r   r   typing_extensionsr	   r   r
   Ztorch.utils._foreach_utilsr   r   r   Z_tensor_or_tensors__all__r   r3   boolr   FutureWarningr   r   r   r   r   r   <module>   sJ   $
        M        