a
    d	'                     @   s  d dl mZ d dlmZmZmZmZmZmZ d dl	Z	d dl
mZ d dlmZ d dl	mZ d dlmZ d dlZd dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dlm Z  d dl!m"Z" d dl#m$Z$ d dl%m&Z&m'Z' edZ(e(rd dl)m	Z* G dd de Z+dS )    )	ExitStack)AnyDictListOptionalTupleUnionN)module_available)Tensor)	Optimizer)CheckpointIO)_distributed_available)group)ReduceOp)LightningOptimizer)PrecisionPlugin)ParallelStrategy)
TBroadcast)MisconfigurationException)rank_zero_deprecationrank_zero_onlyzhorovod.torchc                       s  e Zd ZdZdZd;ed eeej  ee	 ee
 d fddZeedd	d
ZeedddZeedddZeejdddZeeeef dddZeedddZddd fddZeeddddZd<eeedddZddd d!Zddd"d#Zd=eeef ee eee ef  eeef d%d&d'Z!e"j#d(feee eed)d*d+Z$edd,d-d.Z%ee& eed/ d0d1d2Z'e(e)j*e&ee+ee)j,f  d3d4d5Z-e.edd6d7d8Z/dd fd9d:Z0  Z1S )>HorovodStrategyz4Plugin for Horovod distributed training integration.horovodNzpl.accelerators.Accelerator)acceleratorparallel_devicescheckpoint_ioprecision_pluginc                    s<   t d tstdt j||d ||d | jt_d | _d S )Nz`The `HorovodStrategy`: `Trainer(strategy='horovod')` has been deprecated in v1.9.0 and will be removed in v2.0.0. You can try using the `Trainer(strategy='ddp')` instead.zRequested `strategy="horovod"`, but Horovod is not installed. Install with `HOROVOD_WITH_PYTORCH=1 pip install horovod[pytorch]`)r   r   Zcluster_environmentr   r   )	r   _HOROVOD_AVAILABLEr   super__init__global_rankr   rank_exit_stack)selfr   r   r   r   	__class__ m/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/pytorch_lightning/strategies/horovod.pyr   -   s     zHorovodStrategy.__init__)returnc                 C   s   t  S N)hvdr!   r#   r&   r&   r'   r    G   s    zHorovodStrategy.global_rankc                 C   s   t  S r)   )r*   
local_rankr+   r&   r&   r'   r,   K   s    zHorovodStrategy.local_rankc                 C   s   t  S r)   )r*   sizer+   r&   r&   r'   
world_sizeO   s    zHorovodStrategy.world_sizec                 C   s   t | jtsJ | j| j S r)   )
isinstancer   listr,   r+   r&   r&   r'   root_deviceS   s    zHorovodStrategy.root_devicec                 C   s   t | j| jd}|S )N)Znum_replicasr!   )dictr.   r    )r#   distributed_sampler_kwargsr&   r&   r'   r3   X   s    z*HorovodStrategy.distributed_sampler_kwargsc                 C   s   dS )z<Whether the plugin handles gradient accumulation internally.Tr&   r+   r&   r&   r'   handles_gradient_accumulation]   s    z-HorovodStrategy.handles_gradient_accumulationz
pl.Trainer)trainerr(   c           	         s>     t | t _j  |js0d S ttddd j} fdd|D }|D ]"}|j	D ]}|d  j
9  < qfq\j}|D ]*}|j}t|drfdd|jD |_qjd usJ tjj d	d
 |D ]}tj|d	d
 q|j}|jd	gkrtd||j_jD ]}j|  q"d S )N)optr(   c                 S   s   t | tr| jS | S r)   )r/   r   Z
_optimizer)r6   r&   r&   r'   _unpack_lightning_optimizern   s    z:HorovodStrategy.setup.<locals>._unpack_lightning_optimizerc                    s   g | ]} |qS r&   r&   .0r6   )r7   r&   r'   
<listcomp>r       z)HorovodStrategy.setup.<locals>.<listcomp>lrbase_lrsc                    s   g | ]}| j  qS r&   )r.   )r9   r<   r+   r&   r'   r:      r;   r   )Z	root_rankz[Horovod currently does not support different `accumulate_grad_batches` at different epochs.)model_to_devicer   setupr   r"   	__enter__Ztrainingr   
optimizersparam_groupsr.   lr_scheduler_configs	schedulerhasattrr=   lightning_moduler*   Zbroadcast_parametersZ
state_dictZbroadcast_optimizer_stateaccumulation_schedulerZepochsr   _wrap_optimizersaccumulate_grad_batchesenter_contextZskip_synchronize)	r#   r5   rA   	optimizerZparam_grouprC   configrD   rG   r$   )r7   r#   r'   r?   b   s:    



zHorovodStrategy.setup)argskwargsr(   c                 O   s   t  r|   d S r)   )r   join)r#   rM   rN   r&   r&   r'   barrier   s    zHorovodStrategy.barrierr   )objsrcr(   c                 C   s   t ||}|S r)   )r*   Zbroadcast_object)r#   rQ   rR   r&   r&   r'   	broadcast   s    zHorovodStrategy.broadcastc                 C   s:   | j jdkrtj| j  | jd us(J | j| j  d S Ncuda)r1   typetorchrU   Z
set_devicemodeltor+   r&   r&   r'   r>      s    zHorovodStrategy.model_to_devicec                 C   s&   | j jdkrt| j nt  d S rT   )r1   rV   r*   rO   r,   r+   r&   r&   r'   rO      s    zHorovodStrategy.joinmean)tensorr   	reduce_opr(   c                 C   sZ   |durt d|dv r tj}n$|dtjfv r6tj}nt d| |   tj||dS )a  Reduces a tensor from several distributed processes to one aggregated tensor.

        Args:
            tensor: the tensor to sync and reduce
            group: the process group to gather results from. Defaults to all processes (world)
            reduce_op: the reduction operation. Defaults to 'mean'/'avg'.
                Can also be a string 'sum' to calculate the sum during reduction.

        Return:
            reduced value, except when the input was not a tensor the output remains is unchanged
        NzWHorovod does not support allreduce using a subcommunicator at this time. Unset `group`.)NavgrZ   sumzunrecognized `reduce_op`: )op)
ValueErrorr*   ZAverager   ZSUMZSumrO   Z	allreduce)r#   r[   r   r\   r&   r&   r'   reduce   s    zHorovodStrategy.reduceF)resultr   
sync_gradsr(   c                 C   sD   |d ur|t jkrtdt|jdkr2|d}|   t|S )NzWHorovod does not support allgather using a subcommunicator at this time. Unset `group`.r      )	
dist_groupWORLDr`   lenshapeZreshaperO   r*   Z	allgather)r#   rb   r   rc   r&   r&   r'   
all_gather   s    
zHorovodStrategy.all_gather)closure_lossr(   c                 C   s   | j D ]}|  qd S r)   )rA   Zsynchronize)r#   rj   rK   r&   r&   r'   post_backward   s    
zHorovodStrategy.post_backwardzhvd.DistributedOptimizer)rA   rI   r(   c                    s"   j dusJ  fdd|D S )z?Wraps optimizers to perform gradient aggregation via allreduce.Nc              	      s8   g | ]0}d t |jvr0tj| j|dn|qS )r   )Zbackward_passes_per_stepnamed_parameters)strr%   r*   ZDistributedOptimizer_filter_named_parametersrF   r8   rI   r#   r&   r'   r:      s   z4HorovodStrategy._wrap_optimizers.<locals>.<listcomp>)rF   )r#   rA   rI   r&   ro   r'   rH      s    z HorovodStrategy._wrap_optimizers)rX   rK   r(   c                    s&   dd |j D   fdd|  D S )Nc                 S   s"   h | ]}| d g D ]}|qqS )params)get)r9   r   pr&   r&   r'   	<setcomp>   r;   z;HorovodStrategy._filter_named_parameters.<locals>.<setcomp>c                    s    g | ]\}}| v r||fqS r&   r&   )r9   namerr   Z
opt_paramsr&   r'   r:      r;   z<HorovodStrategy._filter_named_parameters.<locals>.<listcomp>)rB   rl   )rX   rK   r&   ru   r'   rn      s    z(HorovodStrategy._filter_named_parameters)strategy_registryr(   c                 C   s   |j | j| | jj d d S )N)description)registerstrategy_namer%   __name__)clsrv   r&   r&   r'   register_strategies   s
    z#HorovodStrategy.register_strategiesc                    s2   | j r| j d d d  d | _ |   t   d S r)   )r"   __exit__rO   r   teardownr+   r$   r&   r'   r~      s
    zHorovodStrategy.teardown)NNNN)r   )NrZ   )2rz   
__module____qualname____doc__ry   r   r   rW   Zdevicer   r   r   propertyintr    r,   r.   r1   r   rm   r   r3   boolr4   r?   rP   r   rS   r>   rO   r   r
   r   ra   re   rf   ri   rk   r   rH   staticmethodnnModuler   	Parameterrn   classmethodr|   r~   __classcell__r&   r&   r$   r'   r   (   s^       0	  

 $r   ),
contextlibr   typingr   r   r   r   r   r   rW   Ztorch.nnr   Z lightning_utilities.core.importsr	   r
   Ztorch.optimr   Zpytorch_lightningplZlightning_fabric.pluginsr   Z&lightning_fabric.utilities.distributedr   r   re   Z lightning_fabric.utilities.typesr   Z pytorch_lightning.core.optimizerr   Z#pytorch_lightning.plugins.precisionr   Z%pytorch_lightning.strategies.parallelr   Z%pytorch_lightning.strategies.strategyr   Z&pytorch_lightning.utilities.exceptionsr   Z%pytorch_lightning.utilities.rank_zeror   r   r   Zhorovod.torchr*   r   r&   r&   r&   r'   <module>   s*    