a
    d1                     @   sB  d dl Z d dlmZmZ d dlmZ d dlmZmZm	Z	m
Z
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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* edZ+edZ,e -e.Z/G dd deZ0G dd deZ1G dd deZ2dS )    N)ABCabstractmethod)contextmanager)
AnyDict	GeneratorIterableListMappingOptionalTupleTypeVarUnion)Tensor)Module)	Optimizer)
DataLoader)Accelerator)CheckpointIO)TorchCheckpointIO)	Precision)	_Launcher)move_data_to_device)_optimizer_to_device)_PATHOptimizableReduceOp
TBroadcastTReducec                   @   sZ  e Zd ZdZdaee ee ee ddddZe	e
ej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jeddddZe	edddZejee ddddZe	edddZejee ddddZddddZddddZeedddZeee eeee f d d!d"Zeed#d$d%Zeed&d'd(Z e
edd#d)d*Z!dbe"eej e"d+d,d-Z#e$ee e"e"dd.d/d0Z%e&e"e"d1d2d3Z'e
dce$ee" ee$d5d6d7Z(e
dde)e$e"f ee" ee)e*e+f  e)e$e"f d9d:d;Z,e
deee+ dd<d=d>Z-e
dfe.e/e.d@dAdBZ0dgeeedDdEdFZ1dhe2e+e"f e3ee" ddGdHdIZ4ee2e+e)e"e$f f d#dJdKZ5ee2e+e$f d&dLdMZ6e3e2e+e"f dNdOdPZ7ee8e+e"f ddQdRdSZ9e)ee:e f e8e+e"f ddTdUdVZ;e3ddWdXdYZ<dddZd[Z=e>e2e+e"f dd\d]d^Z?e+dd_d`Z@dS )iStrategyzcBase class for all strategies that change the behaviour of the training, validation and test- loop.N)acceleratorcheckpoint_io	precisionreturnc                 C   s"   || _ || _|| _d | _d | _d S N)_accelerator_checkpoint_io
_precision	_launcherZ_backward_sync_control)selfr    r!   r"    r*   m/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/lightning_fabric/strategies/strategy.py__init__+   s
    zStrategy.__init__r#   c                 C   s   dS )zReturns the root device.Nr*   r)   r*   r*   r+   root_device7   s    zStrategy.root_devicec                 C   s   dS )zcWhether the current process is the rank zero process not only on the local node, but for all nodes.Nr*   r.   r*   r*   r+   is_global_zero<   s    zStrategy.is_global_zeroc                 C   s   | j S r$   )r(   r.   r*   r*   r+   launcherA   s    zStrategy.launcherc                 C   s   | j S r$   r%   r.   r*   r*   r+   r    E   s    zStrategy.accelerator)r    r#   c                 C   s
   || _ d S r$   r2   )r)   r    r*   r*   r+   r    I   s    c                 C   s   | j d u rt | _ | j S r$   )r&   r   r.   r*   r*   r+   r!   M   s    
zStrategy.checkpoint_io)ior#   c                 C   s
   || _ d S r$   )r&   )r)   r3   r*   r*   r+   r!   S   s    c                 C   s   | j d ur| j S t S r$   )r'   r   r.   r*   r*   r+   r"   W   s    zStrategy.precision)r"   r#   c                 C   s
   || _ d S r$   )r'   )r)   r"   r*   r*   r+   r"   [   s    c                 C   s   dS )z&Attach the launcher based on Strategy.Nr*   r.   r*   r*   r+   _configure_launcher_   s    zStrategy._configure_launcherc                 C   s    | j dusJ | j | j dS )zSetup any processes or distributed connections.

        This must be called by the framework at the beginning of every process, before any distributed communication
        takes place.
        N)r    Zsetup_devicer/   r.   r*   r*   r+   setup_environmentb   s    zStrategy.setup_environment)
dataloaderr#   c                 C   s   |S )zWraps the dataloader if necessary.

        Args:
            dataloader: iterable. Ideally of type: :class:`torch.utils.data.DataLoader`
        r*   )r)   r6   r*   r*   r+   process_dataloaderk   s    zStrategy.process_dataloader)module
optimizersr#   c                    s$     |} fdd|D }||fS )zSet up a model and multiple optimizers together.

        The returned objects are expected to be in the same order they were passed in. The default implementation will
        call :meth:`setup_module` and :meth:`setup_optimizer` on the inputs.
        c                    s   g | ]}  |qS r*   )setup_optimizer).0	optimizerr.   r*   r+   
<listcomp>|       z8Strategy.setup_module_and_optimizers.<locals>.<listcomp>)setup_module)r)   r8   r9   r*   r.   r+   setup_module_and_optimizerss   s    
z$Strategy.setup_module_and_optimizersr8   r#   c                 C   s   |S )zDPerforms setup for the model, e.g., by wrapping it by another class.r*   r)   r8   r*   r*   r+   r?      s    zStrategy.setup_module)r<   r#   c                 C   s   |S )zHPerforms setup for the optimizer, e.g., by wrapping it by another class.r*   r)   r<   r*   r*   r+   r:      s    zStrategy.setup_optimizerc                 C   s   dS )z&Moves the model to the correct device.Nr*   rB   r*   r*   r+   module_to_device   s    zStrategy.module_to_device)batchdevicer#   c                 C   s   |p| j }t||S )a%  Moves the batch to the correct device.

        The returned batch is of the same type as the input batch, just
        having all tensors on the correct device.

        Args:
            batch: The batch of samples to move to the correct device
            device: The target device
        )r/   r   )r)   rE   rF   r*   r*   r+   batch_to_device   s    

zStrategy.batch_to_device)tensorr8   argskwargsr#   c                 O   s<   | j || | j j||g|R i | | j || dS )z0Forwards backward-calls to the precision plugin.N)r"   Zpre_backwardbackwardZpost_backward)r)   rH   r8   rI   rJ   r*   r*   r+   rK      s    zStrategy.backward)r<   rJ   r#   c                 K   s   | j j|fi |S )zPerforms the actual optimizer step.

        Args:
            optimizer: the optimizer performing the step
            **kwargs: Any extra arguments to ``optimizer.step``
        )r"   optimizer_step)r)   r<   rJ   r*   r*   r+   rL      s    zStrategy.optimizer_stepF)rH   group
sync_gradsr#   c                 C   s   dS )a  Perform an all_gather on all processes.

        Args:
            tensor: the tensor to all_gather
            group: the process group to gather results from
            sync_grads: flag that allows users to synchronize gradients for all_gather op
        Nr*   )r)   rH   rM   rN   r*   r*   r+   
all_gather   s    zStrategy.all_gathermean)rH   rM   	reduce_opr#   c                 C   s   dS )a+  Reduces the given tensor (e.g. across GPUs/processes).

        Args:
            tensor: the tensor to sync and reduce
            group: the process group to reduce
            reduce_op: the reduction operation. Defaults to 'mean'.
                Can also be a string 'sum' or ReduceOp.
        Nr*   )r)   rH   rM   rQ   r*   r*   r+   
all_reduce   s    zStrategy.all_reduce)namer#   c                 C   s   dS )zSynchronizes all processes which blocks processes until the whole group enters this function.

        Args:
            name: an optional name to pass into barrier.
        Nr*   )r)   rS   r*   r*   r+   barrier   s    zStrategy.barrierr   )objsrcr#   c                 C   s   dS )zBroadcasts an object to all processes.

        Args:
            obj: the object to broadcast
            src: source rank
        Nr*   )r)   rU   rV   r*   r*   r+   	broadcast   s    zStrategy.broadcastT)decisionallr#   c                 C   s   |S )z/Reduce a boolean decision across all processes.r*   )r)   rX   rY   r*   r*   r+   reduce_boolean_decision   s    z Strategy.reduce_boolean_decision)
checkpointfilepathstorage_optionsr#   c                 C   s   | j r| jj|||d dS )a>  Save model/training states as a checkpoint file through state-dump and file-write.

        Args:
            checkpoint: dict containing model and trainer state
            filepath: write-target file's path
            storage_options: parameter for how to save to storage, passed to ``CheckpointIO`` plugin
        )r]   N)r0   r!   save_checkpoint)r)   r[   r\   r]   r*   r*   r+   r^      s    
zStrategy.save_checkpointc                 C   s   |  S )zReturns model state.)
state_dictrB   r*   r*   r+   get_module_state_dict   s    zStrategy.get_module_state_dictc                 C   s,   t |dr$|  | jr | S i S | S )zReturns state of an optimizer.

        Allows for syncing/collating optimizer state from processes in custom plugins.
        consolidate_state_dict)hasattrra   r0   r_   rC   r*   r*   r+   get_optimizer_state   s    
zStrategy.get_optimizer_state)checkpoint_pathr#   c                 C   s   t j  | j|S r$   )torchZcudaZempty_cacher!   load_checkpoint)r)   rd   r*   r*   r+   rf      s    
zStrategy.load_checkpoint)r8   r[   r#   c                 C   s   | |d  d S )Nr_   )load_state_dict)r)   r8   r[   r*   r*   r+   load_module_state_dict   s    zStrategy.load_module_state_dict)r9   r[   r#   c                 C   sF   t |ts|g}|d }t||D ]\}}|| t|| j q"d S )Noptimizer_states)
isinstancer   ziprg   r   r/   )r)   r9   r[   ri   r<   Z	opt_stater*   r*   r+   load_optimizer_state_dict  s    

z"Strategy.load_optimizer_state_dict)r\   r#   c                 C   s   | j r| j| dS )zpRemove checkpoint filepath from the filesystem.

        Args:
            filepath: Path to checkpoint
        N)r0   r!   remove_checkpoint)r)   r\   r*   r*   r+   rm     s    zStrategy.remove_checkpointc                 C   s0   | j   | jdusJ | j  | j  dS )zThis method is called to teardown the training process.

        It is the right place to release memory and free other resources.
        N)r"   teardownr    r!   r.   r*   r*   r+   rn     s    

zStrategy.teardown)strategy_registryr#   c                 C   s   d S r$   r*   )clsro   r*   r*   r+   register_strategies  s    zStrategy.register_strategiesc                 C   s   dt | j dS )NzThe `z` does not support setting up the module and optimizer(s) independently. Please call `setup_module_and_optimizers(model, [optimizer, ...])` to jointly set them up.)type__name__r.   r*   r*   r+   _err_msg_joint_setup_required#  s    z&Strategy._err_msg_joint_setup_required)NNN)N)NF)NrP   )N)r   )T)N)Ars   
__module____qualname____doc__r   r   r   r   r,   propertyr   re   rF   r/   boolr0   r   r1   r    setterr!   r"   r4   r5   r   r7   r   r	   r   r   r@   r?   r:   rD   r   rG   r   rK   r   rL   rO   r   r   strrR   rT   r   intrW   rZ   r   r   r^   r`   rc   rf   r
   rh   r   rl   rm   rn   classmethodrq   rt   r*   r*   r*   r+   r   (   s      			  

  
	
r   c                   @   s(   e Zd ZdZeeeedddZdS )_BackwardSyncControla  Interface for any :class:`Strategy` that wants to offer a functionality to enable or disable gradient
    synchronization during/after back-propagation.

    The most common use-case is gradient accumulation. If a :class:`Strategy` implements this interface, the user can
    implement their gradient accumulation loop very efficiently by disabling redundant gradient synchronization.
    rA   c                 C   s   dS )zBlocks the synchronization of gradients during the backward pass.

        This is a context manager. It is only effective if it wraps a call to `.backward()`.
        Nr*   rB   r*   r*   r+   no_backward_sync2  s    z%_BackwardSyncControl.no_backward_syncN)	rs   ru   rv   rw   r   r   r   r   r   r*   r*   r*   r+   r~   *  s   r~   c                   @   s&   e Zd ZdZeeedddZdS )_ShardedzoMixin-interface for any :class:`Strategy` that wants to expose functionality for sharding model
    parameters.r-   c                 c   s
   dV  dS )a  A context manager that goes over the instantiation of an :class:`torch.nn.Module` and handles sharding
        of parameters on creation.

        By sharding layers directly on instantiation, one can reduce peak memory usage and initialization time.
        Nr*   r.   r*   r*   r+   module_sharded_context?  s    z_Sharded.module_sharded_contextN)rs   ru   rv   rw   r   r   r   r   r*   r*   r*   r+   r   ;  s   r   )3loggingabcr   r   
contextlibr   typingr   r   r   r   r	   r
   r   r   r   r   re   r   Ztorch.nnr   Ztorch.optimr   Ztorch.utils.datar   Zlightning_fabric.acceleratorsr   Z)lightning_fabric.plugins.io.checkpoint_ior   Z$lightning_fabric.plugins.io.torch_ior   Z"lightning_fabric.plugins.precisionr   Z*lightning_fabric.strategies.launchers.baser   Z%lightning_fabric.utilities.apply_funcr   Z$lightning_fabric.utilities.optimizerr   Z lightning_fabric.utilities.typesr   r   r   r   r   	getLoggerrs   logr   r~   r   r*   r*   r*   r+   <module>   s0   0
  