a
    8Sic6                     @   sj   d dl mZmZ d dlZd dlmZ d dlmZ d dl	Z	d dl
Z
G dd deZe ZG dd deZdS )	    )defaultdictabcN)deepcopy)chainc                   @   s   e Zd ZdZdd ZdS )_RequiredParameterzCSingleton class representing a required parameter for an Optimizer.c                 C   s   dS )Nz<required parameter> selfr   r   Q/var/www/html/django/DPS/env/lib/python3.9/site-packages/torch/optim/optimizer.py__repr__   s    z_RequiredParameter.__repr__N)__name__
__module____qualname____doc__r   r   r   r   r
   r   
   s   r   c                   @   sp   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d ZdedddZdd Zdd ZdS )	OptimizeraX  Base class for all optimizers.

    .. warning::
        Parameters need to be specified as collections that have a deterministic
        ordering that is consistent between runs. Examples of objects that don't
        satisfy those properties are sets and iterators over values of dictionaries.

    Args:
        params (iterable): an iterable of :class:`torch.Tensor` s or
            :class:`dict` s. Specifies what Tensors should be optimized.
        defaults: (dict): a dict containing default values of optimization
            options (used when a parameter group doesn't specify them).
    c                 C   s   t jd || _|   t|t jr8tdt | t	t
| _g | _t|}t|dkrdtdt|d t
s|d|ig}|D ]}| | qd| _d S )Nzpython.optimizerzZparams argument given to the optimizer should be an iterable of Tensors or dicts, but got r   z%optimizer got an empty parameter listparamsT)torch_C_log_api_usage_oncedefaults_hook_for_profile
isinstanceTensor	TypeErrortypenamer   dictstateparam_groupslistlen
ValueErroradd_param_group$_warned_capturable_if_run_uncaptured)r	   r   r   r   param_groupr   r   r
   __init__!   s"    

zOptimizer.__init__c                 C   s   | j | j| jdS )Nr   r   r   r%   r   r   r   r
   __getstate__=   s    zOptimizer.__getstate__c                 C   s   | j | |   d S N)__dict__updater   )r	   r   r   r   r
   __setstate__D   s    zOptimizer.__setstate__c                 C   sp   | j jd }t| jD ]L\}}|d7 }|d|7 }t| D ] }|dkr@|d||| 7 }q@q|d7 }|S )Nz (
zParameter Group {0}
r   z    {0}: {1}
))	__class__r   	enumerater   formatsortedkeys)r	   format_stringigroupkeyr   r   r
   r   H   s    zOptimizer.__repr__c                 C   sh   t jrdt j rdt j }|r<| jd s<td| jj d t	| ddsd| jd rd|sdt
d d| _d S )NZ
capturablez;Attempting CUDA graph capture of step() for an instance of z9 but this instance was constructed with capturable=False.r"   FzWarning: This instance was constructed with capturable=True, but step() is running without CUDA graph capture. If you never intend to graph-capture this instance, capturable=True can impair performance, and you should set capturable=False.T)r   has_cudacudais_availableis_current_stream_capturingr   RuntimeErrorr-   r   getattrprintr"   )r	   Z	capturingr   r   r
    _cuda_graph_capture_health_checkT   s     

z*Optimizer._cuda_graph_capture_health_checkc                 C   sJ   d | jj| _dd }t| jjdd }|sF|| jj| j_d| jj_d S )Nz Optimizer.zero_grad#{}.zero_gradc                    s   t   fdd}|S )Nc                     sV   | ^}}d |jj}tjj|  | i |W  d    S 1 sH0    Y  d S )NzOptimizer.step#{}.step)r/   r-   r   r   autogradprofilerrecord_function)argskwargsobj_Zprofile_namefuncr   r
   wrapperl   s    zGOptimizer._hook_for_profile.<locals>.profile_hook_step.<locals>.wrapper)	functoolswraps)rF   rG   r   rE   r
   profile_hook_stepj   s    z6Optimizer._hook_for_profile.<locals>.profile_hook_stephookedT)r/   r-   r   _zero_grad_profile_namer;   steprK   )r	   rJ   rK   r   r   r
   r   g   s    
zOptimizer._hook_for_profilec                    sL   i dfdd  fdd| j D }fdd| j D }||dS )	aK  Returns the state of the optimizer as a :class:`dict`.

        It contains two entries:

        * state - a dict holding current optimization state. Its content
            differs between optimizer classes.
        * param_groups - a list containing all parameter groups where each
            parameter group is a dict
        r   c                    sb   dd |   D }  fddt| d D   fdd| d D |d< t|d 7 |S )Nc                 S   s   i | ]\}}|d kr||qS )r   r   .0kvr   r   r
   
<dictcomp>       z<Optimizer.state_dict.<locals>.pack_group.<locals>.<dictcomp>c                    s&   i | ]\}}t | vrt ||qS r   id)rO   r3   pparam_mappingsr   r
   rR      s   r   c                    s   g | ]} t | qS r   rT   )rO   rV   rW   r   r
   
<listcomp>   rS   z<Optimizer.state_dict.<locals>.pack_group.<locals>.<listcomp>)itemsr)   r.   r   )r4   packed)rX   start_indexr   r
   
pack_group   s
    "z(Optimizer.state_dict.<locals>.pack_groupc                    s   g | ]} |qS r   r   rO   g)r]   r   r
   rY      rS   z(Optimizer.state_dict.<locals>.<listcomp>c                    s.   i | ]&\}}t |tjr$ t| n||qS r   )r   r   r   rU   rN   rW   r   r
   rR      s   z(Optimizer.state_dict.<locals>.<dictcomp>r   r   )r   r   rZ   )r	   r   Zpacked_stater   )r]   rX   r\   r
   
state_dicty   s    
zOptimizer.state_dictc                    s&  t |}| j}|d }t|t|kr.tddd |D }dd |D }tdd t||D rjtddd	 ttd
d |D tdd |D D }d fdd	 tt	}|d 
 D ]0\}}	||v r|| }
 |
|	||
< q|	||< qdd fddt||D }| ||d dS )zLoads the optimizer state.

        Args:
            state_dict (dict): optimizer state. Should be an object returned
                from a call to :meth:`state_dict`.
        r   z<loaded state dict has a different number of parameter groupsc                 s   s   | ]}t |d  V  qdS r   Nr   r^   r   r   r
   	<genexpr>   rS   z,Optimizer.load_state_dict.<locals>.<genexpr>c                 s   s   | ]}t |d  V  qdS rb   rc   r^   r   r   r
   rd      rS   c                 s   s   | ]\}}||kV  qd S r'   r   )rO   Zp_lens_lenr   r   r
   rd      rS   z]loaded state dict contains a parameter group that doesn't match the size of optimizer's groupc                 S   s   i | ]\}}||qS r   r   )rO   Zold_idrV   r   r   r
   rR      rS   z-Optimizer.load_state_dict.<locals>.<dictcomp>c                 s   s   | ]}|d  V  qdS rb   r   r^   r   r   r
   rd      rS   c                 s   s   | ]}|d  V  qdS rb   r   r^   r   r   r
   rd      rS   Nc                    s   t |tjr8|dkr4  r(| j}| j}|S t |trZ fdd| D S t |t	j
rt| fdd|D S |S dS )zBMake a deep copy of value, casting all tensors to device of param.rM   c                    s    i | ]\}}| ||d qS ))r5   r   rN   castparamr   r
   rR      rS   z;Optimizer.load_state_dict.<locals>.cast.<locals>.<dictcomp>c                 3   s   | ]} |V  qd S r'   r   )rO   rQ   rf   r   r
   rd      rS   z:Optimizer.load_state_dict.<locals>.cast.<locals>.<genexpr>N)r   r   r   is_floating_pointtodtypedevicer   rZ   container_abcsIterabletype)rh   valuer5   )rg   )rh   r
   rg      s    
z'Optimizer.load_state_dict.<locals>.castr   c                 S   s   | d |d< |S )Nr   r   )r4   	new_groupr   r   r
   update_group   s    z/Optimizer.load_state_dict.<locals>.update_groupc                    s   g | ]\}} ||qS r   r   )rO   r_   Zng)rr   r   r
   rY      s   z-Optimizer.load_state_dict.<locals>.<listcomp>r`   )N)r   r   r   r    anyzipr   from_iterabler   r   rZ   r*   )r	   ra   groupsZsaved_groupsZ
param_lensZ
saved_lensid_mapr   rP   rQ   rh   r   r   )rg   rr   r
   load_state_dict   s4    

zOptimizer.load_state_dictF)set_to_nonec           	      C   s  | j dd}t| ds |   |r0tdd }tjj| j	 | j
D ]}|d D ]r}|jdurT|rnd|_qT|jjdur|j  n|jd |r|jjr|j  qT||jj |jj |j qTqH|r| D ] \}}| D ]}t| qqW d   n1 s0    Y  dS )a  Sets the gradients of all optimized :class:`torch.Tensor` s to zero.

        Args:
            set_to_none (bool): instead of setting to zero, set the grads to None.
                This will in general have lower memory footprint, and can modestly improve performance.
                However, it changes certain behaviors. For example:
                1. When the user tries to access a gradient and perform manual ops on it,
                a None attribute or a Tensor full of 0s will behave differently.
                2. If the user requests ``zero_grad(set_to_none=True)`` followed by a backward pass, ``.grad``\ s
                are guaranteed to be None for params that did not receive a gradient.
                3. ``torch.optim`` optimizers have a different behavior if the gradient is 0 or None
                (in one case it does the step with a gradient of 0 and in the other it skips
                the step altogether).
        foreachFrL   c                   S   s   t tS r'   )r   r   r   r   r   r
   <lambda>   rS   z%Optimizer.zero_grad.<locals>.<lambda>r   N)r   gethasattrr   r   r   r>   r?   r@   rL   r   gradgrad_fndetach_requires_grad_	is_sparsezero_rl   rk   appendrZ   valuesZ_foreach_zero_)	r	   ry   rz   per_device_and_dtype_gradsr4   rV   rD   per_dtype_gradsgradsr   r   r
   	zero_grad   s*    


 zOptimizer.zero_gradc                 C   s   t dS )af  Performs a single optimization step (parameter update).

        Args:
            closure (callable): A closure that reevaluates the model and
                returns the loss. Optional for most optimizers.

        .. note::
            Unless otherwise specified, this function should not modify the
            ``.grad`` field of the parameters.
        N)NotImplementedError)r	   closurer   r   r
   rM     s    zOptimizer.stepc                 C   sF  t |tsJ d|d }t |tjr2|g|d< n t |trFtdnt||d< |d D ]0}t |tjs|tdt| |jsZt	dqZ| j
 D ]2\}}|tu r||vrt	d| q||| q|d }t|tt|krtjddd	 t }| jD ]}|t|d  q |t|d s6t	d
| j| dS )a  Add a param group to the :class:`Optimizer` s `param_groups`.

        This can be useful when fine tuning a pre-trained network as frozen layers can be made
        trainable and added to the :class:`Optimizer` as training progresses.

        Args:
            param_group (dict): Specifies what Tensors should be optimized along with group
                specific optimization options.
        zparam group must be a dictr   zoptimizer parameters need to be organized in ordered collections, but the ordering of tensors in sets will change between runs. Please use a list instead.z>optimizer can only optimize Tensors, but one of the params is z can't optimize a non-leaf TensorzJparameter group didn't specify a value of required optimization parameter zoptimizer contains a parameter group with duplicate parameters; in future, this will cause an error; see github.com/pytorch/pytorch/issues/40967 for more information   )
stacklevelz7some parameters appear in more than one parameter groupN)r   r   r   r   setr   r   r   is_leafr    r   rZ   required
setdefaultr   warningswarnr   r)   
isdisjointr   )r	   r#   r   rh   namedefault	param_setr4   r   r   r
   r!     s>    




zOptimizer.add_param_groupN)F)r   r   r   r   r$   r&   r*   r   r=   r   ra   rx   boolr   rM   r!   r   r   r   r
   r      s   @)r   )collectionsr   r   rm   r   copyr   	itertoolsr   r   rH   objectr   r   r   r   r   r   r
   <module>   s   