a
    d,                     @   s  d Z ddl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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mZ d-e
ee ee ee ddddZee edddZ!ee"ef ee ef dddZ#eeedddZ$edddZ%eeedddZ&G dd  d ej'j(Z)eeedd!d"Z*eeedd#d$Z+eeedd%d&Z,eeedd'd(Z-e.dd)d*Z/eeedd+d,Z0dS ).z5Utilities that can be used with distributed training.    )AnyCallableDictOptionalTupleN)Tensor)DistributedDataParallel)_all_gather_ddp_if_available)_distributed_available)_gather_all_tensors)-_get_default_process_group_backend_for_device)_init_dist_connection)	_sync_ddp)_sync_ddp_if_available)rank_zero_debugrank_zero_deprecationrank_zero_info)modelddp_comm_stateddp_comm_hookddp_comm_wrapperreturnc                 C   s^   |du rdS |}|dur:t d|j d|j d ||}td|j d | j||d dS )a5  Function to register communication hook for DDP model https://pytorch.org/docs/master/ddp_comm_hooks.html.

    Args:
        model:
            DDP model
        ddp_comm_state:
            state is passed to the hook and can be used to maintain
            and update any state information that users would like to
            maintain as part of the training process. Examples: error
            feedback in gradient compression, peers to communicate with
            next in GossipGrad etc.
        ddp_comm_hook:
            hook(state: object, bucket: dist._GradBucket) -> torch.futures.Future

            This callable function is called once the bucket is ready. The
            hook can perform whatever processing is needed and return
            a Future indicating completion of any async work (ex: allreduce).
            If the hook doesn't perform any communication, it can also
            just return a completed Future. The Future should hold the
            new value of grad bucket's tensors. Once a bucket is ready,
            c10d reducer would call this hook and use the tensors returned
            by the Future and copy grads to individual parameters.
        ddp_comm_wrapper:
            communication hook wrapper to support a communication hook such
            as FP16 compression as wrapper, which could be combined with
            ddp_comm_hook

    Examples:

        >>> from torch.distributed.algorithms.ddp_comm_hooks import ( # doctest: +SKIP
        ...     default_hooks as default,
        ...     powerSGD_hook as powerSGD,
        ...     post_localSGD_hook as post_localSGD,
        ... )
        >>>
        >>> # fp16_compress_hook for compress gradients
        >>> ddp_model = ...
        >>> register_ddp_comm_hook( # doctest: +SKIP
        ...     model=ddp_model,
        ...     ddp_comm_hook=default.fp16_compress_hook,
        ... )
        >>>
        >>> # powerSGD_hook
        >>> ddp_model = ...
        >>> register_ddp_comm_hook( # doctest: +SKIP
        ...     model=ddp_model,
        ...     ddp_comm_state=powerSGD.PowerSGDState(
        ...         process_group=None,
        ...         matrix_approximation_rank=1,
        ...         start_powerSGD_iter=5000,
        ...     ),
        ...     ddp_comm_hook=powerSGD.powerSGD_hook,
        ... )
        >>>
        >>> # post_localSGD_hook
        >>> subgroup, _ = torch.distributed.new_subgroups() # doctest: +SKIP
        >>> ddp_model = ...
        >>> register_ddp_comm_hook( # doctest: +SKIP
        ...     model=ddp_model,
        ...     state=post_localSGD.PostLocalSGDState(
        ...         process_group=None,
        ...         subgroup=subgroup,
        ...         start_localSGD_iter=1_000,
        ...     ),
        ...     ddp_comm_hook=post_localSGD.post_localSGD_hook,
        ... )
        >>>
        >>> # fp16_compress_wrapper combined with other communication hook
        >>> ddp_model = ...
        >>> register_ddp_comm_hook( # doctest: +SKIP
        ...     model=ddp_model,
        ...     ddp_comm_state=powerSGD.PowerSGDState(
        ...         process_group=None,
        ...         matrix_approximation_rank=1,
        ...         start_powerSGD_iter=5000,
        ...     ),
        ...     ddp_comm_hook=powerSGD.powerSGD_hook,
        ...     ddp_comm_wrapper=default.fp16_compress_wrapper,
        ... )
    Nz$DDP comm wrapper is provided, apply (z).zRegistering DDP comm hook: .)statehook)r   __qualname__r   Zregister_comm_hook)r   r   r   r    r   p/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/pytorch_lightning/utilities/distributed.pyregister_ddp_comm_hook!   s    Vr   )objrankr   c                 C   s0   t j |kr| nd g}t jj||d |d S )N)srcr   )torchdistributedget_rankZbroadcast_object_list)r    r!   Zobjectsr   r   r   _broadcast_object_list   s    r&   )r   r   c                    s*   t  sd iS  fddttj D S )aT  This distributed utility collects dictionary state across all processes.

    Args:
        state: Dictionary containing the state of the current process

    Returns:
        states: On global rank 0, a dictionary where the primary keys are
            the process rank and the values their associated states. Otherwise, returns None.
    r   c                    s   i | ]}|t  |qS r   )r&   ).0r!   r   r   r   
<dictcomp>       z0_collect_states_on_rank_zero.<locals>.<dictcomp>)new_distributed_availableranger#   r$   get_world_sizer(   r   r(   r   _collect_states_on_rank_zero   s    
r.   )argskwargsr   c                  O   s   t d t| i |S )Nz`pytorch_lightning.utilities.distributed.all_gather_ddp_if_available` has been deprecated in v1.8.0 and will be removed in v2.0.0. This function is internal but you can copy over its implementation.)r   new_all_gather_ddp_if_availabler/   r0   r   r   r   all_gather_ddp_if_available   s    r3   )r   c                   C   s   t d t S )Nz`pytorch_lightning.utilities.distributed.distributed_available` has been deprecated in v1.8.0 and will be removed in v2.0.0. This function is internal but you can copy over its implementation.)r   r+   r   r   r   r   distributed_available   s    r4   c                  O   s   t d t| i |S )Nz`pytorch_lightning.utilities.distributed.gather_all_tensors` has been deprecated in v1.8.0 and will be removed in v2.0.0. This function is internal but you can copy over its implementation.)r   new_gather_all_tensorsr2   r   r   r   gather_all_tensors   s    r6   c                   @   sL   e Zd ZdZed
eeed edddZeeee	edf ddd	Z
dS )AllGatherGrada!  Gathers tensors from the whole group and stacks them.

    This implementation is copied from PyTorch.

    .. deprecated:: v1.8.0
        This function has been deprecated in v1.8.0 in favor of :func:`torch.distributed.nn.functional.all_gather` and
        will be removed in v2.0.0.
    Nztorch.distributed.ProcessGroup)ctxtensorgroupr   c                    sR   t ddd || _ fddttj D }tjj| |d tj|dd}|S )	Nz`AllGatherGrad` has been deprecated in v1.8.0 and will be removed in v2.0.0. Use `torch.distributed.nn.functional.all_gather` instead.   )
stacklevelc                    s   g | ]}t  qS r   )r#   Z
zeros_like)r'   _r9   r   r   
<listcomp>   r*   z)AllGatherGrad.forward.<locals>.<listcomp>)r:   r   )Zdim)r   r:   r,   r#   r$   r-   Z
all_gatherstack)r8   r9   r:   Zgathered_tensorr   r>   r   forward   s    zAllGatherGrad.forward)r8   grad_outputr   c                 G   s8   t |}t jj|t jjjd| jd |t j  d fS )NF)opZasync_opr:   )r#   catr$   Z
all_reduceZReduceOpZSUMr:   r%   )r8   rB   r   r   r   backward   s    
zAllGatherGrad.backward)N)__name__
__module__r   __doc__staticmethodr   r   r   rA   r   rE   r   r   r   r   r7      s   	 r7   c                  O   s   t d t| i |S )Na6  `pytorch_lightning.utilities.distributed.get_default_process_group_backend_for_device` has been deprecated in v1.8.0 and will be removed in v2.0.0. This function is internal but you can copy over its implementation. `lightning_fabric.utilities.distributed.get_default_process_group_backend_for_device` instead.)r   0new_get_default_process_group_backend_for_devicer2   r   r   r   ,get_default_process_group_backend_for_device   s    rK   c                  O   s   t d t| i |S )Nz`pytorch_lightning.utilities.distributed.init_dist_connection` has been deprecated in v1.8.0 and will be removed in v2.0.0. This function is internal but you can copy over its implementation.)r   new_init_dist_connectionr2   r   r   r   init_dist_connection   s    rM   c                  O   s   t d t| i |S )Nz`pytorch_lightning.utilities.distributed.sync_ddp` has been deprecated in v1.8.0 and will be removed in v2.0.0. This function is internal but you can copy over its implementation.)r   new_sync_ddpr2   r   r   r   sync_ddp   s    rO   c                  O   s   t d t| i |S )Nz`pytorch_lightning.utilities.distributed.sync_ddp_if_available` has been deprecated in v1.8.0 and will be removed in v2.0.0. This function is internal but you can copy over its implementation.)r   new_sync_ddp_if_availabler2   r   r   r   sync_ddp_if_available   s    rQ   c                  C   s   t d ddlm}  |  S )Nz`pytorch_lightning.utilities.distributed.tpu_distributed` has been deprecated in v1.8.0 and will be removed in v2.0.0. This function is internal but you can copy over its implementation.r   _tpu_distributed)r   Z!lightning_fabric.accelerators.tpurS   rR   r   r   r   tpu_distributed   s
    rT   c                  O   s"   t d ddlm} || i |S )Nz`pytorch_lightning.utilities.distributed.rank_zero_only` has been deprecated in v1.8.1 and will be removed in v2.0.0. You can import it from `pytorch_lightning.utilities` instead.r   )rank_zero_only)r   %pytorch_lightning.utilities.rank_zerorU   )r/   r0   Znew_rank_zero_onlyr   r   r   rU     s
    rU   )NNN)1rH   typingr   r   r   r   r   r#   r   Ztorch.nn.parallel.distributedr   Z&lightning_fabric.utilities.distributedr	   r1   r
   r+   r   r5   r   rJ   r   rL   r   rN   r   rP   rV   r   r   r   objectr   intr&   strr.   r3   r4   r6   ZautogradZFunctionr7   rK   rM   rO   rQ   boolrT   rU   r   r   r   r   <module>   sD      e "	
