
      iZ                        d dl Z d dlZd dlZd dlmZ d dlmZmZmZ d dl	m
Z
 d dl mZ d dlmZmZmZmZ d dlmZ d dlmZmZmZ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!  G d de      Z"de#de$fdZ%de#dee&   fdZ'de#dee   fdZ(dedeeef   defdZ)dedeeef   de*e*e   e+e,ef   f   fdZ-dedeeef   de+e,ef   fdZ.de#de&ddfdZ/dddededee0   dedef
d Z1d7d!ed"ee,   defd#Z2d$ed%e"defd&Z3e
d7d'e0d"ee,   ded(   fd)       Z4d*e,d+ede*ed,f   de+e,ef   d-e+e,ef   d.e*e,d,f   de*e$e*ed,f   e+e,ef   f   fd/Z5de#d0e&ddfd1Z6d2e&de&fd3Z7de&fd4Z8 G d5 d6e+      Z9y)8    N)OrderedDict)	GeneratorIterableSized)contextmanager)partial)AnyCallableOptionalUnion)get_all_subclasses)BatchSampler
DataLoaderIterableDatasetSampler)	TypeGuard)LightningEnum)MisconfigurationException)rank_zero_warn)pl_worker_init_functionc                   $    e Zd ZdZdZdeddfdZy)_WrapAttrTagsetdelargsreturnNc                 B    | | j                   k(  rt        nt        } || S N)SETsetattrdelattr)selfr   fns      t/Volumes/fast/ai/experiments/voice-extract-mac/.venv/lib/python3.12/site-packages/lightning_fabric/utilities/data.py__call__z_WrapAttrTag.__call__&   s    (Wg4y    )__name__
__module____qualname__r   DELr	   r%    r&   r$   r   r   "   s    
C
Cc d r&   r   
dataloaderr   c                 R    t        | d      xr t        | j                  t              S )Ndataset)hasattr
isinstancer.   r   )r,   s    r$   has_iterable_datasetr1   ,   s!    :y)]j9K9K_.]]r&   c                 N    	 t        |       }|S # t        t        f$ r d}Y |S w xY w)z>Try to get the length of an object, return ``None`` otherwise.N)len	TypeErrorNotImplementedErrorr,   lengths     r$   	sized_lenr8   0   s8    Z M *+ Ms    $$c                     t        |       }|dk(  r#t        d| j                  j                   d       |t	        |       rt        d       |duS )z<Checks if a given object has ``__len__`` method implemented.r   `z>` returned 0 length. Please make sure this was your intention.NzYour `IterableDataset` has `__len__` defined. In combination with multi-process data loading (when num_workers > 1), `__len__` could be inaccurate if each worker is not configured independently to avoid having duplicate data.)r8   r   	__class__r'   r1   r6   s     r$   has_lenr<   :   s_    z"F{
$$--..lm	
 2:>/	
 r&   samplerc                 >    t        | |      \  }}t        | g|i |S r   )$_get_dataloader_init_args_and_kwargs_reinstantiate_wrapped_cls)r,   r=   dl_args	dl_kwargss       r$   _update_dataloaderrC   K   s(    =j'RGY%jH7HiHHr&   c                    t        | t              st        d|  d      t        | d      }|r1| j                  }| j
                  }| j                  }| j                  }nQt        |       j                         D ci c]  \  }}|j                  d      r|| }	}}d }| j                  |	d<   d}t        t        j                  | j                        j                         }
t#        d |
j%                         D              }|r|rx|
j'                  t        j                  t        j                        j                   j                         D ci c]!  \  }}|j(                  |j*                  us||# c}}       nN|
j'                  t        j                  t        j                        j                          |
j-                  dd        |st|
j                         D ch c]  \  }}|	v s|j(                  |	|   us|  }}}|j/                  d	       	j                         D ci c]  \  }}||v s|| }}}d}j1                  d	|      }t        |t2              rd |d
<   d |d<   n|j'                  t5        | |             |
j%                         D ch c]f  }|j6                  |j8                  |j:                  fv r@|j(                  |j*                  u r(|j<                  |vr|j<                  |vr|j<                  h }}|rQt?        |      }| j@                  jB                  }djE                  d |D              }tG        d| d| d| d| d	      |s`tI        |      tI        |      z  |
jK                         z
  }|r6t?        |      }| j@                  jB                  }tM        d| d| d| d      |fS c c}}w c c}}w c c}}w c c}}w c c}w )NzThe dataloader z0 needs to subclass `torch.utils.data.DataLoader`__pl_saved_args_multiprocessing_contextr+   c              3   L   K   | ]  }|j                   |j                  u   y wr   )kindVAR_KEYWORD).0ps     r$   	<genexpr>z7_get_dataloader_init_args_and_kwargs.<locals>.<genexpr>i   s     O!aff5s   "$r"   r.   batch_samplerr=   z, c              3   (   K   | ]
  }d | d  yw)z`self.r:   Nr+   )rK   arg_names     r$   rM   z7_get_dataloader_init_args_and_kwargs.<locals>.<genexpr>   s     (cNb(6(1)=Nbs   z,Trying to inject custom `Sampler` into the `z` instance. This would fail as some of the `__init__` arguments are not available as instance attributes. The missing attributes are z. If you instantiate your `zZ` inside a `*_dataloader` hook of your module, we will do this for you. Otherwise, define z inside your `__init__`.z&Trying to inject parameters into the `z{` instance. This would fail as it doesn't expose all its attributes in the `__init__` signature. The missing arguments are z. HINT: If you wrote the `zA` class, add the `__init__` arguments or allow passing `**kwargs`)'r0   r   
ValueErrorr/   rE   __pl_saved_kwargs__pl_saved_arg_names	__datasetvarsitems
startswithrG   dictinspect	signature__init__
parametersanyvaluesupdatedefaultemptypopaddgetr   '_dataloader_init_kwargs_resolve_samplerrI   POSITIONAL_ONLYPOSITIONAL_OR_KEYWORDnamesortedr;   r'   joinr   r   keysr4   )r,   r=   was_wrappedrA   rB   	arg_namesoriginal_datasetkvattrsparamshas_variadic_kwargsrh   rL   non_defaultsr.   required_argssorted_required_argsdataloader_cls_namemissing_args_messagemissing_kwargssorted_missing_kwargss                         r$   r?   r?   P   s    j*-?:,6fghh*&78K,,00	33	%// #'z"2"8"8":T":$!Q!,,sBSA":T  +5+M+M'(	 '##J$7$78CCDFOv}}OO  MM!(!2!2:3F3F!G!R!R!X!X!Z!ZA^_^g^gopovov^v1!Z  MM'++J,?,?@KKLJJvt$,2LLNmNqdemPQPYPYafgkalPlNm 	#&+kkmImdaqL7HQTm	ImmI'78G'?+%)	/"#	)@WUV  A66a'')@)@AAII FF)#FF)# 	
    %m4(22;;#yy(cNb(cc':;N:O P**>)??Z[nZo p""6!77O	Q
 	
 i.3y>9V[[]J$*>$:!","6"6"?"?89L8M N--B,CC]^q]r sRR  IW U" n
 Js=   ;OO O
0O
!O.O O+O8OA+Oc                 n   t        | d      }|t        |      t        urt        |      }t        |d      ro|j                  }|j
                  }|j                  }|j                  }t        d|||||      \  }}}|st        d|j                   d      t        |g|i |}nDt        |d      r-t        |d      r!	  |||j                  |j                  	      }nt        d      dd|dddS |dddS # t        $ r3}	d
dl}
|
j                  dt!        |	            }|s t        d      |	d}	~	ww xY w)zThis function is used to handle the sampler, batch_sampler arguments associated within a DataLoader for its re-
    instantiation.rN   NrE   r=   zYTrying to inject a modified sampler into the batch sampler; however, it seems the class `z` does not have an argument called `sampler.` To mitigate this, expose an argument `sampler` in the `__init__` method of your custom class.
batch_size	drop_last)r|   r}   r   z:.*__init__\(\) (got multiple values)|(missing \d required)ak   Lightning can't inject a (distributed) sampler into your batch sampler, because it doesn't subclass PyTorch's `BatchSampler`. To mitigate this, either follow the API of `BatchSampler` or set`.setup_dataloaders(..., use_distributed_sampler=False)`. If you choose the latter, you will be responsible for handling the distributed sampling within your batch sampler.F   )r=   shufflerN   r|   r}   )r=   r   rN   )getattrtyper   r/   rE   rR   __pl_saved_default_kwargsrS   _replace_value_in_saved_argsr4   r)   r@   r|   r}   rematchstr)r,   r=   rN   batch_sampler_clsr   kwargsdefault_kwargsrm   successexr   r   s               r$   re   re      s    J8M T-%8%L /="34 00D"44F*DDN%::I$@7D&.)%!GT6 )667 8hh  7}VtVvVM]L1gm[6Y 1,77+55!. h  *
 	
 54HHC  !^`cdf`gh  l
 s   ?C8 8	D4.D//D4rankc                     t        | d      sy t        t        j                  j	                  dd            r$| j
                  t        t        |      | _        y y y )Nworker_init_fnPL_SEED_WORKERSr   )r   )r/   intosenvironrd   r   r   r   )r,   r   s     r$   _auto_add_worker_init_fnr      sL    :/0
2::>>+Q/0Z5N5N5V$+,C$$O
! 6W0r&   )explicit_clsorig_objectr   r   r   c          
      L   |t        |       n|}	  ||i |}t        | dg       }|D ]  \  }} ||g|   |S # t        $ r_}dd l}|j                  dt	        |            }|s |j                         d   }	d|j                   d|	 d|	 d|	 d	}
t        |
      |d }~ww xY w)	Nr   z-.*__init__\(\) got multiple values .* '(\w+)'zThe zd implementation has an error where more than one `__init__` argument can be passed to its parent's `zr=...` `__init__` argument. This is likely caused by allowing passing both a custom argument that will map to the `zc` argument as well as `**kwargs`. `kwargs` should be filtered to make sure they don't contain the `zR` key. This argument was automatically passed to your object by PyTorch Lightning.__pl_attrs_record)	r   r4   r   r   r   groupsr'   r   r   )r   r   r   r   constructorresultr   r   r   argumentmessageattrs_recordr#   s                r$   r@   r@      s    '3';${#K9d-f-( ;(;R@L b
6D ! M/  9 	I3r7S<<>!$;''( )//7j 9EEMJ OQQYPZ [[[ 	 (0b8#9s   ; 	B#ABB#initstore_explicit_argc           	      p     t        j                         dt        dt        dt        ddf fd       }|S )zWraps the ``__init__`` method of classes (currently :class:`~torch.utils.data.DataLoader` and
    :class:`~torch.utils.data.BatchSampler`) in order to enable re-instantiation of custom subclasses.objr   r   r   Nc                 T   t        | dd      }t        j                  | dd       t        j                  
      j
                  }t        d |j                         D              }t        |      d t        |       }|j                         D ci c]-  \  }}||vr$||vr |t        j                  j                  k7  r||/ }	}}t        | d      s\t        j                  | d|       t        j                  | d|       t        j                  | d|       t        j                  | d|	       R|v r-t        j                  | d	 ||j                                  n!|v rt        j                  | d	 |           
| g|i | t        j                  | d|       y c c}}w )
N__pl_inside_initFTc              3      K   | ]O  }|j                   d k7  r>|j                  |j                  |j                  fvr|j                   |j                  f Q yw)r"   N)rh   rI   VAR_POSITIONALrJ   r`   )rK   params     r$   rM   z5_wrap_init_method.<locals>.wrapper.<locals>.<genexpr>(  sN      *
(zzV#

5;O;OQVQbQb:c(c ZZ'(s   AArE   rR   rS   r   __)r   object__setattr__rY   rZ   r\   r   r^   tupler3   rV   	Parameterra   r/   index)r   r   r   old_inside_initrr   parameters_defaultsparam_namesrh   valuer   r   r   s             r$   wrapperz"_wrap_init_method.<locals>.wrapper   s    "#'95A3 2D9""4(33) *
*
 
 /03t9=  388:
:e6!d+&=%7K\K\KbKbBb %K: 	 
 s-.s$5t<s$7@s$:KHs$?P
 )![0""3"-?,@(A4HYHYZlHmCno#v-""3"-?,@(A6J\C]^S"4"6"3 2OD-
s   2F$	functoolswrapsr	   )r   r   r   s   `` r$   _wrap_init_methodr     sJ     __T%ES %E %E %E %E %EN Nr&   methodtagc                 d     t        j                         dt        dt        ddf fd       }|S )zWraps the ``__setattr__`` or ``__delattr__`` method of classes (currently :class:`~torch.utils.data.DataLoader`
    and :class:`~torch.utils.data.BatchSampler`) in order to enable re- instantiation of custom subclasses.r   r   r   Nc                 J   |^}}t        | dd      \  }}||k(  xr |	k(   }t        j                  | d|	f        | g|  |rDt        | dd      s7t        | dg       }|j                  |	f       t        j                  | d|       t        j                  | d||f       y )N__pl_current_call)Nr   r   Tr   )r   r   r   append)
r   r   rh   rF   prev_call_nameprev_call_method
first_callr   r   r   s
           r$   r   z"_wrap_attr_method.<locals>.wrapperO  s     q+238KM]+^(((D0L5E5LM
 	3 3dC[A 	sTgc+=tD #3(;R@Ls,s$7F3 3nFV5WXr&   r   )r   r   r   s   `` r$   _wrap_attr_methodr   K  sA     __VYS Y Y Y Y& Nr&   base_cls)NNNc              #   >  K   t        |       | hz  }|D ]  }d|j                  v r,|j                  |_        t	        |j                  |      |_        dt
        j                  fdt
        j                  ffD ]U  \  }}||j                  v s|| u sd| }t        ||t        ||             t        ||t        t        ||      |             W  d |D ]D  }dD ]=  }d| |j                  v st        ||t        |d|              t        |d|        ? F yw)zThis context manager is used to add support for re-instantiation of custom (subclasses) of `base_cls`.

    It patches the ``__init__``, ``__setattr__`` and ``__delattr__`` methods.

    r[   r   __delattr____oldN)r   r   r[   )r   __dict__r[   __old__init__r   r   r   r*   r    r   r   r!   )r   r   classesclspatch_fn_namer   
saved_namepatched_names           r$   _replace_dunder_methodsr   f  s%     !*hZ7G % #C,S\\;MNCL %2<3C3C#D}VbVfVfFg"hM3,x$]O4
Zm)DE],=gc=>Y[^,_`	 #i  
FL |n%5\73%~8N+OPu\N34 G s   BDA D/.Dreplace_keyreplace_value.r   rm   c                     | |v r(|j                  |       }|d| |fz   ||dz   d z   }d||fS | |v s| |v r
||| <   d||fS d||fS )zTries to replace an argument value in a saved list of args and kwargs.

    Returns a tuple indicating success of the operation and modified saved args and kwargs

    Nr~   TF)r   )r   r   r   r   r   rm   replace_indexs          r$   r   r     s     i!4N]#}&66ma>O>Q9RRT6!!f~ =+{T6!!$r&   epochc                    i }t        | dd      x}||t        |      <   t        | dd      x}t        |dd      x}	 ||t        |      <   |j                         D ]#  }t        |dd      }t        |      s ||       % y)a  Calls the ``set_epoch`` method on either the sampler of the given dataloader.

    Every PyTorch dataloader has either a sampler or a batch sampler. If the sampler is wrapped by a
    :class:`~torch.utils.data.distributed.DistributedSampler`, ``set_epoch`` must be called at the beginning
    of every epoch to ensure shuffling applies a new ordering. This has no effect if shuffling is off.

    r=   NrN   	set_epoch)r   idr^   callable)r,   r   objectsr=   rN   r   r   s          r$   _set_sampler_epochr     s     !G:y$77D&7 _dCCP=)T::V  '7~~Cd3	Ie  r&   local_world_sizec                 b    | dk  rt        d|  d      t               }t        d|| z  dz
        S )a  Suggests an upper bound of ``num_workers`` to use in a PyTorch :class:`~torch.utils.data.DataLoader` based on
    the number of CPU cores available on the system and the number of distributed processes in the current machine.

    Args:
        local_world_size: The number of distributed processes running on the current machine. Set this to the number
            of devices configured in Fabric/Trainer.

    r~   z'`local_world_size` should be >= 1, got .)rQ   _num_cpus_availablemax)r   	cpu_counts     r$   suggested_max_num_workersr     sD     !BCSBTTUVWW#%Iq)//!344r&   c                      t        t        d      rt        t        j                  d            S t        j                         } | dS | S )Nsched_getaffinityr   r~   )r/   r   r3   r   r   )r   s    r$   r   r     s>    r&'2''*++I!10y0r&   c                   P    e Zd ZdZdedefdZdededdfdZdeddfd	Zdefd
Z	y)AttributeDicta  A container to store state variables of your program.

    This is a drop-in replacement for a Python dictionary, with the additional functionality to access and modify keys
    through attribute lookup for convenience.

    Use this to define the state of your program, then pass it to
    :meth:`~lightning_fabric.fabric.Fabric.save` and :meth:`~lightning_fabric.fabric.Fabric.load`.

    Example:
        >>> import torch
        >>> model = torch.nn.Linear(2, 2)
        >>> state = AttributeDict(model=model, iter_num=0)
        >>> state.model
        Linear(in_features=2, out_features=2, bias=True)
        >>> state.iter_num += 1
        >>> state.iter_num
        1
        >>> state
        "iter_num": 1
        "model":    Linear(in_features=2, out_features=2, bias=True)

    keyr   c                 |    	 | |   S # t         $ r+}t        dt        |       j                   d| d      |d }~ww xY w)N'z' object has no attribute ')KeyErrorAttributeErrorr   r'   )r"   r   es      r$   __getattr__zAttributeDict.__getattr__  sP    	d9 	d 1T$Z%8%8$99TUXTYYZ![\bcc	ds    	;&6;valNc                     || |<   y r   r+   )r"   r   r   s      r$   r   zAttributeDict.__setattr__  s    S	r&   itemc                 (    || vrt        |      | |= y r   )r   )r"   r   s     r$   r   zAttributeDict.__delattr__  s    t4. Jr&   c                    t        |       syt        d | D              }dt        |dz         z   dz   }t        | j	                               D cg c]  }|j                  d| d| |          }}dj                  |      S c c}w )	N c              3   D   K   | ]  }t        t        |              y wr   )r3   r   )rK   ro   s     r$   rM   z)AttributeDict.__repr__.<locals>.<genexpr>  s     7$QSQ[$s    z{:   zs} {}"z":
)r3   r   r   ri   rk   formatrj   )r"   max_key_lengthtmp_namenrowss        r$   __repr__zAttributeDict.__repr__  s    4y7$77#nq011G;=CDIIK=PQ=P!A3b	473=PQyy Rs    B)
r'   r(   r)   __doc__r   r	   r   r   r   r   r+   r&   r$   r   r     sV    .ds ds ds     
# r&   r   r   ):r   rY   r   collectionsr   collections.abcr   r   r   
contextlibr   r   typingr	   r
   r   r   $lightning_utilities.core.inheritancer   torch.utils.datar   r   r   r   typing_extensionsr    lightning_fabric.utilities.enumsr   %lightning_fabric.utilities.exceptionsr   $lightning_fabric.utilities.rank_zeror   lightning_fabric.utilities.seedr   r   r   boolr1   r   r8   r<   rC   r   rX   r   r?   re   r   r   r@   r   r   r   r   r   r   r   r   r+   r&   r$   <module>r     s     	 # 6 6 %  1 1 C O O ' : K ? C= ^V ^ ^& Xc]  9U#3 "I: Igx>O8P IU_ I
ZZ7H$%Z 5:tCH~%&ZzFIFI7H$%FI 
#s(^FIRP Ps Pt P ]a C  8TX> lo tw >,H ,(3- ,S[ ,^h \ h 6 5d 5 5YbcsYt 5 5> S/ cN	
 cN S#X 4sCx$sCx.0126 # $ 05 5 51S 1,D ,r&   