
      iJ              
           d dl Z d dlmZmZ d dlmZ d dlmZ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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+m,Z, e
rd dl-m.Z.  ed      Z/ ed      Z0 e jb                  e2      Z3 G d de      Z4 G d de      Z5 G d de      Z6dee7   dee7   de8ddfd Z9d!e7d"e:e7ee7ege8f   f   d#e;d$e:e7ef   ddf
d%Z<y)&    N)ABCabstractmethod)Iterable)AbstractContextManager	ExitStack)TYPE_CHECKINGAnyCallableOptionalTypeVarUnion)Tensor)Module)	Optimizer)
DataLoader)Accelerator)CheckpointIO)TorchCheckpointIO)	Precision)	_Launcher)_StrategyRegistry)move_data_to_device)
_EmptyInit)_PATHOptimizableReduceOp	_Stateful)_LRScheduler
TBroadcastTReducec                      e Zd ZdZ	 	 	 dNdee   dee   dee   ddfdZe	e
dej                  fd              Ze	e
defd	              Ze	dee   fd
       Ze	dee   fd       Zej&                  deddfd       Ze	defd       Zej&                  deddfd       Ze	defd       Zej&                  dee   ddfd       ZdOdZdOdZdedefdZdefdZdPdee   defdZ	 dPdedee   ded   de eee   ed   f   fdZ!dedefdZ"dedefd Z#e
deddfd!       Z$dPd"e%d#eej                     de%fd$Z&d%e'dee   d&e%d'e%ddf
d(Z(de)d'e%de%fd)Z*e
dQd%e'd*ee%   d+ede'fd,       Z+e
	 	 dRd%e,e'e%f   d*ee%   d-ee,e-e.f      de,e'e%f   fd.       Z/e
dPd/ee.   ddfd0       Z0e
dSd1e1d2e2de1fd3       Z3dTd4ed5edefd6Z4	 	 dUd7e5d8e6e.e,eee%f   f   d9ee%   d:ee6e.e7e.e%gef   f      ddf
d;Z8dede6e.e,e%e'f   f   fd<Z9	 dTded=e6e.e,e%e'f   f   d>eddfd?Z:dede6e.e'f   fd@Z;	 	 	 dVd7e5d8ee,eee6e.e,eee%f   f   f      d>edAee   de6e.e%f   f
dBZ<dOdCZ=	 	 dWdej|                  j:                  dedDe,e?e2f   dEe,e?e2f   dFedejN                  fdGZ@dej|                  j:                  dedHe,e?e2f   ddfdIZAeBdJeCddfdK       ZDde.fdLZEd8e6e.e,eee%f   f   d:e6e.e7e.e%gef   f   de6e.e%f   fdMZFy)XStrategyzcBase class for all strategies that change the behaviour of the training, validation and test- loop.Nacceleratorcheckpoint_io	precisionreturnc                 X    || _         || _        d | _        || _        d | _        d | _        y N)_accelerator_checkpoint_io
_precisionr%   	_launcher_backward_sync_control)selfr#   r$   r%   s       y/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/lightning/fabric/strategies/strategy.py__init__zStrategy.__init__0   s1     4?6C/3".2FJ#    c                      y)zReturns the root device.N r.   s    r/   root_devicezStrategy.root_device>       r1   c                      y)zcWhether the current process is the rank zero process not only on the local node, but for all nodes.Nr3   r4   s    r/   is_global_zerozStrategy.is_global_zeroC   r6   r1   c                     | j                   S r(   )r,   r4   s    r/   launcherzStrategy.launcherH   s    ~~r1   c                     | j                   S r(   r)   r4   s    r/   r#   zStrategy.acceleratorL   s       r1   c                     || _         y r(   r<   )r.   r#   s     r/   r#   zStrategy.acceleratorP   s
    'r1   c                 P    | j                   t               | _         | j                   S r(   )r*   r   r4   s    r/   r$   zStrategy.checkpoint_ioT   s%    &"3"5D"""r1   ioc                     || _         y r(   )r*   )r.   r?   s     r/   r$   zStrategy.checkpoint_ioZ   s
     r1   c                 F    | j                   | j                   S t               S r(   )r+   r   r4   s    r/   r%   zStrategy.precision^   s    "&//"=tN9;Nr1   c                     || _         y r(   )r+   )r.   r%   s     r/   r%   zStrategy.precisionb   s	    #r1   c                      y)z&Attach the launcher based on Strategy.Nr3   r4   s    r/   _configure_launcherzStrategy._configure_launcherf   r6   r1   c                 j    | j                   J | j                   j                  | j                         y)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#   setup_devicer5   r4   s    r/   setup_environmentzStrategy.setup_environmenti   s0     +++%%d&6&67r1   
dataloaderc                     |S )zWraps the dataloader if necessary.

        Args:
            dataloader: iterable. Ideally of type: :class:`torch.utils.data.DataLoader`

        r3   )r.   rH   s     r/   process_dataloaderzStrategy.process_dataloaders   s
     r1   c                     | j                   j                         }t               }|j                  | j                         |j                  |       |S )z1Controls how tensors get created (device, dtype).)r%   tensor_init_contextr   enter_contextr5   )r.   precision_init_ctxstacks      r/   rL   zStrategy.tensor_init_context|   sD    !^^??AD,,-./r1   
empty_initc                     | j                   j                         }t               }|j                  | j                         |j                  t        t        |                   |j                  |       |S )a  A context manager wrapping the model instantiation.

        Here, the strategy can control how the parameters of the model get created (device, dtype) and or apply other
        patches to the model.

        Args:
            empty_init: Whether to initialize the model with empty weights (uninitialized memory).
                If ``None``, the strategy will decide. Some strategies may not support all options.

        )enabled)r%   module_init_contextr   rM   r5   r   bool)r.   rP   precision_module_ctxrO   s       r/   rS   zStrategy.module_init_context   s^      $~~AACD,,-JtJ/?@A01r1   module
optimizers	schedulerr   c                 t    | j                  |      }|D cg c]  }| j                  |       }}|||fS c c}w )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.

        )setup_modulesetup_optimizer)r.   rV   rW   rX   	optimizers        r/   setup_module_and_optimizersz$Strategy.setup_module_and_optimizers   sF     ""6*GQRz)d**95z
Rz9,, Ss   5c                     |S )zDPerforms setup for the model, e.g., by wrapping it by another class.r3   r.   rV   s     r/   rZ   zStrategy.setup_module   s    r1   r\   c                     |S )zHPerforms setup for the optimizer, e.g., by wrapping it by another class.r3   r.   r\   s     r/   r[   zStrategy.setup_optimizer   s    r1   c                      y)z&Moves the model to the correct device.Nr3   r_   s     r/   module_to_devicezStrategy.module_to_device   r6   r1   batchdevicec                 :    |xs | 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

        )r5   r   )r.   rd   re   s      r/   batch_to_devicezStrategy.batch_to_device   s!     +4++"5&11r1   tensorargskwargsc                     | j                   j                  ||        | j                   j                  ||g|i | | j                   j                  ||       y)z0Forwards backward-calls to the precision plugin.N)r%   pre_backwardbackwardpost_backward)r.   rh   rV   ri   rj   s        r/   rm   zStrategy.backward   sJ    ##FF3@@@$$VV4r1   c                 <     | 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   s      r/   rp   zStrategy.optimizer_step   s      -t~~,,YA&AAr1   group
sync_gradsc                      y)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

        Nr3   )r.   rh   rq   rr   s       r/   
all_gatherzStrategy.all_gather   r6   r1   	reduce_opc                      y)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.

        Nr3   )r.   rh   rq   ru   s       r/   
all_reducezStrategy.all_reduce   r6   r1   namec                      y)zSynchronizes all processes which blocks processes until the whole group enters this function.

        Args:
            name: an optional name to pass into barrier.

        Nr3   )r.   rx   s     r/   barrierzStrategy.barrier   r6   r1   objsrcc                      y)zBroadcasts an object to all processes.

        Args:
            obj: the object to broadcast
            src: source rank

        Nr3   )r.   r{   r|   s      r/   	broadcastzStrategy.broadcast   r6   r1   decisionallc                     |S )z/Reduce a boolean decision across all processes.r3   )r.   r   r   s      r/   reduce_boolean_decisionz Strategy.reduce_boolean_decision   s    r1   pathstatestorage_optionsfilterc                     | j                  ||xs i       }| j                  r| j                  j                  |||       yy)a  Save model, optimizer, and other state as a checkpoint file.

        Args:
            path: A path to where the file(s) should be saved
            state: A dictionary with contents to be saved. If the dict contains modules or optimizers, their
                state-dict will be retrieved and converted automatically.
            storage_options: Additional options for the ``CheckpointIO`` plugin
            filter: An optional dictionary containing filter callables that return a boolean indicating whether the
                given item should be saved (``True``) or filtered out (``False``). Each filter key should match a
                state key, where its filter will be applied to the ``state_dict`` generated.

        )r   )
checkpointr   r   N)"_convert_stateful_objects_in_stater8   r$   save_checkpoint)r.   r   r   r   r   s        r/   r   zStrategy.save_checkpoint  sH    & 77v|QS7U..%d\k.l r1   c                 "    |j                         S )zReturns model state.)
state_dictr_   s     r/   get_module_state_dictzStrategy.get_module_state_dict  s      ""r1   r   strictc                 *    |j                  ||       y)z%Loads the given state into the model.r   N)load_state_dict)r.   rV   r   r   s       r/   load_module_state_dictzStrategy.load_module_state_dict  s     	z&9r1   c                     t        |d      r.|j                          | j                  r|j                         S i S |j                         S )zReturns state of an optimizer.

        Allows for syncing/collating optimizer state from processes in custom plugins.

        consolidate_state_dict)hasattrr   r8   r   ra   s     r/   get_optimizer_statezStrategy.get_optimizer_state%  sJ     967 ,,.-1-@-@9'')HbH ##%%r1   weights_onlyc                    t         j                  j                          | j                  j	                  ||      }|s|S t        |t              r| j                  |||       i S t        |t              r|j                  |       i S t        |j                         |j                         |       |j                         j                         D ]  \  }}||vrt        |t              rUt        |t              r$| j                  ||j                  |      |       O|j                  |j                  |             p|j                  |      ||<    |S )a  Load the contents from a checkpoint and restore the state of the given objects.

        Args:
            path: A path to where the file is located
            state: Can be one of:

                - A dictionary of objects whose state will be restored in-place from the checkpoint path.
                - ``None`` or the empty dict: The loaded checkpoint will be returned in full.
                - A :class:`~torch.nn.Module` instance, if the checkpoint file contains a raw module state dict.
                - A :class:`~torch.optim.Optimizer` instance, if the checkpoint file contains a raw optimizer state.

            strict: Whether to enforce that the keys in `state` match the keys in the checkpoint.
            weights_only: Defaults to ``None``. If ``True``, restricts loading to ``state_dicts`` of plain
                ``torch.Tensor`` and other primitive types. If loading a checkpoint from a trusted source that contains
                an ``nn.Module``, use ``weights_only=False``. If loading checkpoint from an untrusted source, we
                recommend using ``weights_only=True``. For more information, please refer to the
                `PyTorch Developer Notes on Serialization Semantics <https://docs.pytorch.org/docs/main/notes/serialization.html#id3>`_.

        Returns:
            The remaining items that were not restored into the given state dictionary. If no state dictionary is
            given, the full checkpoint will be returned.

        )r   )rV   r   r   r   )torchcudaempty_cacher$   load_checkpoint
isinstancer   r   r   r   !_validate_keys_for_strict_loadingkeyscopyitemsr   pop)r.   r   r   r   r   r   rx   r{   s           r/   r   zStrategy.load_checkpoint4  s!   < 	

 ''77<7X
eV$''uTZ'[IeY'!!*-I)%**,
8IRXY++-ID#:%#y)c6*//sz~~VZG[dj/k''
t(<=(nnT2d . r1   c                     | j                   j                          | j                  J | j                  j                          | j                  j                          y)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$   r4   s    r/   r   zStrategy.teardownl  sJ     	!+++!!###%r1   max_norm	norm_typeerror_if_nonfinitec                     | j                   j                  |       | j                   j                  |      }t        j                  j
                  j                  ||||      S )zClip gradients by norm.)r   r   r   )r%   unscale_gradientsmain_paramsr   nnutilsclip_grad_norm_)r.   rV   r\   r   r   r   
parameterss          r/   clip_gradients_normzStrategy.clip_gradients_normw  sT     	((3^^//	:
xx~~--YSe . 
 	
r1   clip_valc                     | j                   j                  |       | j                   j                  |      }t        j                  j
                  j                  ||      S )zClip gradients by value.)
clip_value)r%   r   r   r   r   r   clip_grad_value_)r.   rV   r\   r   r   s        r/   clip_gradients_valuezStrategy.clip_gradients_value  sF    ((3^^//	:
xx~~..zh.OOr1   strategy_registryc                      y r(   r3   )clsr   s     r/   register_strategieszStrategy.register_strategies  s    r1   c                 4    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__r4   s    r/   _err_msg_joint_setup_requiredz&Strategy._err_msg_joint_setup_required  s%    DJ''( )j j	
r1   c                 (   i }|j                         D ]|  \  }}t        |t              r| j                  |      }nFt        |t              r| j                  |      }n#t        |t              r|j                         }n|}t        ||||       ~ |S )N)rV   )r\   )	r   r   r   r   r   r   r   r   _apply_filter)r.   r   r   converted_statekeyr{   	converteds          r/   r   z+Strategy._convert_stateful_objects_in_state  s     +-HC#v& 66c6B	C+ 44s4C	C+NN,		#vy/B & r1   )NNN)r&   Nr(   )NF)Nmean)r   )T)NN)NTN)g       @T)Gr   
__module____qualname____doc__r   r   r   r   r0   propertyr   r   re   r5   rT   r8   r   r:   r#   setterr$   r%   rD   rG   r   rJ   r   rL   rS   r   listr   tupler]   rZ   r[   rc   r	   rg   r   rm   r   rp   rt   r   r   strrw   rz   r   intr~   r   r   dictr
   r   r   r   r   r   r   r   floatr   r   classmethodr   r   r   r   r3   r1   r/   r"   r"   -   s   m .204)-	Kk*K  -K I&	K
 
K 'U\\ '  ' r r  r (9-   !Xk2 ! ! ({ (t ( ( #| # #
 ! ! ! ! O9 O O $8I#6 $4 $ $58Z J %; htn H^ & bf--*.y/-FN~F^-	vtI(@@	A-6 f  y  5v 5$ 5 52S 2(5<<2H 2TW 25v 5x/? 5 5WZ 5_c 5BB B 
	B   RV ci     $4:	fck" } E(C-01	
 
vs{	   HSM T   Z c *   4 4  *.BFmm Cvy#5667m "#	m
 c8S#J,<#==>?m 
m.#F #tCsF{AS<S7T #
 Y]::*.sE#v+4F/F*G:QU:	:&Y &4V;L &$ _c'+66 fic5TWAW;X6X1YYZ[6 	6
 tn6 
c3h6p	&  (+#'

 
 s
#	

 $
 !
 

P588?? Py P\abgilbl\m Prv P 4E $  
s 
#uVY%;<<=GKCQY[^`cZdfjZjQkLkGl	c3hr1   r"   c                   .    e Zd ZdZedededefd       Zy)_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.

    rV   rR   r&   c                      y)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()`.

        Nr3   )r.   rV   rR   s      r/   no_backward_syncz%_BackwardSyncControl.no_backward_sync  r6   r1   N)	r   r   r   r   r   r   rT   r   r   r3   r1   r/   r   r     s1     v  AW  r1   r   c                   &    e Zd ZdZedefd       Zy)_ShardedzkMixin-interface for any :class:`Strategy` that wants to expose functionality for sharding model parameters.r&   c                      y)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.

        Nr3   r4   s    r/   module_sharded_contextz_Sharded.module_sharded_context  r6   r1   N)r   r   r   r   r   r   r   r3   r1   r/   r   r     s    u(>  r1   r   requested_keyscheckpoint_keysr   r&   c                 d    | D cg c]	  }||vs| }}|r|rt        d|d    d      y y c c}w )Nz$The requested state contains a key 'r   z^' that does not exist in the loaded checkpoint. To disable strict loading, set `strict=False`.)KeyError)r   r   r   kinvalid_keyss        r/   r   r     sU      .J~!/1IA~LJ,2<?2C D> ?
 	
 v Ks   	--r   r   source_dicttarget_dictc                     | |v rRt        |t              rB||    }|j                         D ])  \  }} |||      s|j                  | i        |||    |<   + y ||| <   y r(   )r   r   r   
setdefault)r   r   r   r   	filter_fnr   vs          r/   r   r     sh     f}K63K	%%'DAqA&&sB/&'C #	 ( 'Cr1   )=loggingabcr   r   collections.abcr   
contextlibr   r   typingr   r	   r
   r   r   r   r   r   torch.nnr   torch.optimr   torch.utils.datar   lightning.fabric.acceleratorsr   )lightning.fabric.plugins.io.checkpoint_ior   $lightning.fabric.plugins.io.torch_ior   "lightning.fabric.plugins.precisionr   .lightning.fabric.strategies.launchers.launcherr   $lightning.fabric.strategies.registryr   %lightning.fabric.utilities.apply_funcr   lightning.fabric.utilities.initr    lightning.fabric.utilities.typesr   r   r   r   torch.optim.lr_schedulerr   r   r    	getLoggerr   logr"   r   r   r   rT   r   r   objectr   r3   r1   r/   <module>r      s    # $ 8 I I    ! ' 5 B B 8 D B E 6 T T5\"

)
g!xs xv3 $
s 

SM
4<SM
KO
	
'	'3#sT)9 ::;'JP'_cdgildl_m'	'r1   