U
    ¯Ê¹jˆ  ã                   @   s,   d Z ddlZddlmZ G dd„ deƒZdS )an   PyTorch LARS / LARC Optimizer

An implementation of LARS (SGD) + LARC in PyTorch

Based on:
  * PyTorch SGD: https://github.com/pytorch/pytorch/blob/1.7/torch/optim/sgd.py#L100
  * NVIDIA APEX LARC: https://github.com/NVIDIA/apex/blob/master/apex/parallel/LARC.py

Additional cleanup and modifications to properly support PyTorch XLA.

Copyright 2021 Ross Wightman
é    N)Ú	Optimizerc                	       s@   e Zd ZdZd‡ fdd„	Z‡ fd	d
„Ze ¡ ddd„ƒZ‡  Z	S )ÚLarsa»   LARS for PyTorch
    
    Paper: `Large batch training of Convolutional Networks` - https://arxiv.org/pdf/1708.03888.pdf

    Args:
        params (iterable): iterable of parameters to optimize or dicts defining parameter groups.
        lr (float, optional): learning rate (default: 1.0).
        momentum (float, optional): momentum factor (default: 0)
        weight_decay (float, optional): weight decay (L2 penalty) (default: 0)
        dampening (float, optional): dampening for momentum (default: 0)
        nesterov (bool, optional): enables Nesterov momentum (default: False)
        trust_coeff (float): trust coefficient for computing adaptive lr / trust_ratio (default: 0.001)
        eps (float): eps for division denominator (default: 1e-8)
        trust_clip (bool): enable LARC trust ratio clipping (default: False)
        always_adapt (bool): always apply LARS LR adapt, otherwise only when group weight_decay != 0 (default: False)
    ç      ð?r   Fçü©ñÒMbP?ç:Œ0âŽyE>c                    sŠ   |dk rt d|› �ƒ‚|dk r,t d|› �ƒ‚|dk rBt d|› �ƒ‚|r^|dksV|dkr^t dƒ‚t||||||||	|
d�	}tƒ  ||¡ d S )Ng        zInvalid learning rate: zInvalid momentum value: zInvalid weight_decay value: r   z8Nesterov momentum requires a momentum and zero dampening)	ÚlrÚmomentumÚ	dampeningÚweight_decayÚnesterovÚtrust_coeffÚepsÚ
trust_clipÚalways_adapt)Ú
ValueErrorÚdictÚsuperÚ__init__)ÚselfÚparamsr   r   r	   r
   r   r   r   r   r   Údefaults©Ú	__class__© úN/var/www/html/bwave/python/venv/lib/python3.8/site-packages/timm/optim/lars.pyr   #   s(    ÷zLars.__init__c                    s(   t ƒ  |¡ | jD ]}| dd¡ qd S )Nr   F)r   Ú__setstate__Úparam_groupsÚ
setdefault)r   ÚstateÚgroupr   r   r   r   F   s    
zLars.__setstate__Nc              
   C   sÄ  d}|dk	r&t  ¡ � |ƒ }W 5 Q R X | jd d d j}t jd|d�}| jD �]n}|d }|d }|d }|d	 }	|d
 }
|d }|d D �].}|jdkržqŒ|j}|dks¶|d �r8| d¡}| d¡}|
| |||  |  }t  |dkt  |dk||¡|¡}|d �r t  ||d  |¡}|j	||d� | 
|¡ |dk�r¨| j| }d|k�rnt  |¡ ¡  }|d< n |d }| 
|¡j	|d| d� |	�r¤|j||d�}n|}|j	||d  d� qŒqN|S )z¡Performs a single optimization step.

        Args:
            closure (callable, optional): A closure that reevaluates the model and returns the loss.
        Nr   r   r   )Údevicer
   r   r	   r   r   r   r   g       @r   r   )ÚalphaZmomentum_buffer)ÚtorchZenable_gradr   r    ZtensorÚgradZnormÚwhereÚminimumZadd_Zmul_r   ÚcloneÚdetachÚadd)r   ÚclosureZlossr    Z
one_tensorr   r
   r   r	   r   r   r   Úpr#   Zw_normZg_normZtrust_ratioZparam_stateÚbufr   r   r   ÚstepK   sR    



ý




z	Lars.step)	r   r   r   r   Fr   r   FF)N)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r"   Zno_gradr,   Ú__classcell__r   r   r   r   r      s            õ#r   )r0   r"   Ztorch.optim.optimizerr   r   r   r   r   r   Ú<module>   s   