a
    d,\                     @   st  d dl mZ d dlmZmZ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mZ d dlm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# d dl$m%Z% d dl&m'Z' G dd dZ(eG dd dZ)G dd dZ*G dd dZ+G dd dZ,G dd dZ-eeef eeee.e/f  gee.e/f f ee.e/f dddZ0dS )    )Sized)asdict	dataclassfield)
AnyCallableDictIterableIteratorListMappingOptionalSequenceUnionN)apply_to_collectionapply_to_collections)Tensor)Dataset)_BaseDataLoaderIter_MultiProcessingDataLoaderIter
DataLoader)IterableDataset)_distributed_available)_reload_dataloader_state_dictMergedIteratorStatepatch_dataloader_iterator)MisconfigurationException)_fault_tolerant_trainingc                   @   s   e Zd ZdZedddZdee ddddZee d	d
dZ	eddddZ
ee d	ddZee d	ddZee d	ddZeee dddZdS )TensorRunningAccuma  Tracks a running accumulation values (min, max, mean) without graph references.

    Examples:
        >>> accum = TensorRunningAccum(5)
        >>> accum.last(), accum.mean()
        (None, None)
        >>> accum.append(torch.tensor(1.5))
        >>> accum.last(), accum.mean()
        (tensor(1.5000), tensor(1.5000))
        >>> accum.append(torch.tensor(2.5))
        >>> accum.last(), accum.mean()
        (tensor(2.5000), tensor(2.))
        >>> accum.reset()
        >>> _= [accum.append(torch.tensor(i)) for i in range(13)]
        >>> accum.last(), accum.mean(), accum.min(), accum.max()
        (tensor(12.), tensor(10.), tensor(8.), tensor(12.))
    )window_lengthc                 C   s   || _ | | d S N)r   resetselfr    r$   m/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/pytorch_lightning/trainer/supporters.py__init__7   s    zTensorRunningAccum.__init__N)r   returnc                 C   s*   |dur|| _ d| _d| _d| _d| _dS )zEmpty the accumulator.Nr   F)r   memorycurrent_idxlast_idxrotatedr"   r$   r$   r%   r!   ;   s    zTensorRunningAccum.resetr'   c                 C   s.   | j dur*t| jtsJ | j| j   S dS )zGet the last added element.N)r*   
isinstancer(   r   floatr#   r$   r$   r%   lastD   s    
zTensorRunningAccum.last)xr'   c                 C   s   | j du r.tj| jg|jR |j|jd| _ t $ || j | j< | j| _	W d   n1 s`0    Y  |  jd7  _| j| j | _| jdkrd| _
dS )z"Add an element to the accumulator.N)devicedtype   r   T)r(   torchzerosr   shaper2   r3   Zno_gradr)   r*   r+   )r#   r1   r$   r$   r%   appendJ   s    
$
&
zTensorRunningAccum.appendc                 C   s
   |  dS )z$Get mean value from stored elements.mean_agg_memoryr/   r$   r$   r%   r9   ]   s    zTensorRunningAccum.meanc                 C   s
   |  dS )z'Get maximal value from stored elements.maxr:   r/   r$   r$   r%   r<   a   s    zTensorRunningAccum.maxc                 C   s
   |  dS )z'Get minimal value from stored elements.minr:   r/   r$   r$   r%   r=   e   s    zTensorRunningAccum.min)howr'   c                 C   sR   | j d urNt| jtsJ | jr2t| j | S t| jd | j  | S d S r    )r*   r-   r(   r   r+   getattrr.   r)   )r#   r>   r$   r$   r%   r;   i   s
    
zTensorRunningAccum._agg_memory)N)__name__
__module____qualname____doc__intr&   r   r!   r   r0   r8   r9   r<   r=   strr;   r$   r$   r$   r%   r   $   s   	r   c                   @   s   e Zd ZU dZdZeed< edd dZe	e
 ed< edd dZeeef ed	< d
Zeed< ddddZeedddZdS )SharedCycleIteratorStateaz  A state shared between all CycleIterators in a CombinedLoader.

    With a shared state, the iterators can decide to terminate based on the state of all others. If the mode is
    *max_size_cycle*, all iterators need to have finished before the combined loading is considered finished, and
    otherwise any iterator finishing early will lead to all iterators ending early.
    max_size_cyclemodec                   C   s   g S r    r$   r$   r$   r$   r%   <lambda>{       z!SharedCycleIteratorState.<lambda>)default_factorydataloadersc                   C   s   i S r    r$   r$   r$   r$   r%   rI   |   rJ   has_finishedF	has_resetNr,   c                 C   s$   | j D ]}d| jt|< qd| _d S )NFT)rL   rM   idrN   )r#   
dataloaderr$   r$   r%   r!      s    
zSharedCycleIteratorState.resetc                 C   s@   | j stdt| jdkr dS | jdkr.tnt}|| j S )Nz7Please call reset once all dataloaders have been added.r4   FrG   )	rN   r   lenrL   rH   allanyrM   values)r#   Zdecision_fnr$   r$   r%   done   s    zSharedCycleIteratorState.done)r@   rA   rB   rC   rH   rE   __annotations__r   rL   r   r   rM   r   rD   boolrN   r!   propertyrU   r$   r$   r$   r%   rF   q   s   
rF   c                   @   sb   e Zd ZdZdeeeeef  e	dddZ
edddZedd	d
Zeeef dddZdS )CycleIteratorz?Iterator for restarting a dataloader if it runs out of samples.N)loaderlengthstatec                 C   sd   |du rt d}|s0t }|j| |  n|j| || _|| _|| _d| _d| _	|| _dS )a  
        Args:
            loader: the loader to restart for cyclic (and optionally infinite) sampling
            length: the number of batches to sample (with restarted loaders if necessary) before raising StopIteration
                if None: infinite
        Ninfr   )
r.   rF   rL   r8   r!   r\   r[   rZ   _loader_itercounter)r#   rZ   r[   r\   r$   r$   r%   r&      s    
zCycleIterator.__init__r,   c                 C   s    d| _ | j  t| j| _| S )zjCreates the internal iterator and returns self.

        Returns:
            CycleIterator: self
        r   )r_   r\   r!   iterrZ   r^   r/   r$   r$   r%   __iter__   s    
zCycleIterator.__iter__c              	   C   s   t | jtsJ | j|  ks&| jjr*tzzt| jW W |  jd7  _S  ty   d| jj	t
| j< | jjrttt| j| _t| jdd}|rt| j| j| t| j Y W |  jd7  _S 0 W |  jd7  _n|  jd7  _0 dS )z
        Fetches the next batch from internal dataloader and restarts
        it if necessary
        Returns:
            Any: the resulting batch
        Raises:
            StopIteration: if more then :attr:`length` batches have been returned
        r4   TZ_lightning_fetcherN)r-   r^   r
   r_   __len__r\   rU   StopIterationnextrM   rO   rZ   r`   r?   r   )r#   Zfetcherr$   r$   r%   __next__   s&    	zCycleIterator.__next__c                 C   s   | j S r    r[   r/   r$   r$   r%   rb      s    zCycleIterator.__len__)NN)r@   rA   rB   rC   r   r   r   rD   r.   rF   r&   ra   re   rb   r$   r$   r$   r%   rY      s
    'rY   c                   @   s   e Zd ZdZeedZdeee	f e
dddZeeeef ddd	Zeeeef dd
dZeee	f e
eeef dddZeeeeeef dddZeeeeef dddZeeef dddZdS )CombinedDatasetz7Combine multiple datasets and compute their statistics.min_sizerG   ri   )datasetsrH   c                 C   s>   || _ || j vr4td| dt| j  d|| _dS )a-  
        Args:
            datasets: a sequence/mapping datasets. Can be a collections of torch.utils.Dataset,
                Iterable or even None.
            mode: whether to use the minimum number of batches in all samples or the maximum
                number of batches in all samples.
        z$You have selected unsupported mode "z", please select one the: .N)rj   COMPUTE_FUNCSkeysr   listrH   )r#   rj   rH   r$   r$   r%   r&      s    zCombinedDataset.__init__r,   c                 C   s   |  | jdS )NrG   _calc_num_datarj   r/   r$   r$   r%   max_len   s    zCombinedDataset.max_lenc                 C   s   |  | jdS )Nri   ro   r/   r$   r$   r%   min_len   s    zCombinedDataset.min_len)rj   rH   r'   c                 C   sR   || j  vrtd| | |}| j | }t|ttfrD|}n
t||}|S )a  Compute the length of `CombinedDataset` according to the `mode`.

        Args:
            datasets: a sequence/mapping datasets. Can be a collections of torch.utils.data.Dataset,
                Iterable or even None.
            mode: Determine `CombinedDataset`'s length is the maximum or minimum of
                the datasets.

        Returns:
            length: the length of `CombinedDataset`
        Invalid Mode: )rl   rm   r   _get_len_recursiver-   rD   r.   _nested_calc_num_data)r#   rj   rH   all_lengthscompute_funcr[   r$   r$   r%   rp      s    


zCombinedDataset._calc_num_data)datar'   c                    s   t |tr t |tsJ t|S t |ttfr2|S t |trjtdd | D r fdd|	 D S n6t |t
rt|}tdd |D r fdd|D S  |S )Nc                 s   s    | ]}t |ttttfV  qd S r    r-   r   r   r   r	   .0vr$   r$   r%   	<genexpr>!  rJ   z5CombinedDataset._get_len_recursive.<locals>.<genexpr>c                    s   i | ]\}}|  |qS r$   rt   )r{   kr|   r/   r$   r%   
<dictcomp>"  rJ   z6CombinedDataset._get_len_recursive.<locals>.<dictcomp>c                 s   s    | ]}t |ttttfV  qd S r    ry   rz   r$   r$   r%   r}   %  rJ   c                    s   g | ]}  |qS r$   r~   rz   r/   r$   r%   
<listcomp>&  rJ   z6CombinedDataset._get_len_recursive.<locals>.<listcomp>)r-   r   r   rQ   r.   rD   r   rS   rT   itemsr   rn   _get_len)r#   rx   r$   r/   r%   rt     s    


z"CombinedDataset._get_len_recursive)datasetr'   c              	   C   s.   z
t | W S  ttfy(   td Y S 0 d S )Nr]   )rQ   	TypeErrorNotImplementedErrorr.   )r   r$   r$   r%   r   *  s    
zCombinedDataset._get_lenc                 C   s   |  | j| jS )z*Return the minimum length of the datasets.)rp   rj   rH   r/   r$   r$   r%   rb   1  s    zCombinedDataset.__len__N)ri   )r@   rA   rB   rC   r=   r<   rl   r   r   r   rE   r&   rX   rD   r.   rq   rr   rp   r   r   r   rt   staticmethodr   rb   r$   r$   r$   r%   rg      s   
"rg   c                   @   s,  e Zd ZdZdZd*eedddZee	e
 eeddd	Zd+eedddZeddddZe
ddddZeeeeef dddZeeeeef dddZedddZddddZedddZed,eeeeef d d!d"Zeeef dd#d$Zeedd%d&d'Z ddd(d)Z!dS )-CombinedLoadera  Combines different dataloaders and allows sampling in parallel. Supported modes are ``"min_size"``, which
    raises StopIteration after the shortest loader (the one with the lowest number of batches) is done, and
    ``"max_size_cycle"`` which raises StopIteration after the longest loader (the one with most batches) is done,
    while cycling through the shorter loaders.

    Examples:
        >>> loaders = {'a': torch.utils.data.DataLoader(range(6), batch_size=4),
        ...            'b': torch.utils.data.DataLoader(range(15), batch_size=5)}
        >>> combined_loader = CombinedLoader(loaders, 'max_size_cycle')
        >>> for item in combined_loader:
        ...     print(item)
        {'a': tensor([0, 1, 2, 3]), 'b': tensor([0, 1, 2, 3, 4])}
        {'a': tensor([4, 5]), 'b': tensor([5, 6, 7, 8, 9])}
        {'a': tensor([0, 1, 2, 3]), 'b': tensor([10, 11, 12, 13, 14])}
        >>> combined_loader = CombinedLoader(loaders, 'min_size')
        >>> for item in combined_loader:
        ...     print(item)
        {'a': tensor([0, 1, 2, 3]), 'b': tensor([0, 1, 2, 3, 4])}
        {'a': tensor([4, 5]), 'b': tensor([5, 6, 7, 8, 9])}
    rh   ri   )loadersrH   c                 C   sl   || j vrtd| || _t| jttddttfd}t||| _	|| _
| j
dkr\|   d| _d| _dS )aD  
        Args:
            loaders: the loaders to sample from. Can be all kind of collection
            mode: the mode. Supported are 'min_size' which stops if the shortest loader is exhausted and
                'max_size_cycle' which stops if the longest loader is exhausted and cycles through the smaller ones.
        rs   r   Nwrong_dtyperG   )SUPPORTED_MODESr   r   r   r	   r?   r   r   rg   r   rH   _wrap_loaders_max_size_cycle_loaders_iter_state_dict	_iterator)r#   r   rH   rj   r$   r$   r%   r&   N  s    

zCombinedLoader.__init__)iteratorhas_completedr'   c                 C   s8   t | tr| j} |rdnd}t| |d }|r4t|S i S )Nr\   previous_state)r-   rY   r^   r?   r   )r   r   Zstate_to_saver\   r$   r$   r%   _state_dict_fnh  s    
zCombinedLoader._state_dict_fnF)r   r'   c                 C   s*   t  r| jdu ri S t| jjt| j|dS )ax  The state dict includes all states from wrapped dataloaders and their samplers through the
        ``CaptureIterableDataset`` and fast-forward samplers.

        Args:
            has_completed: whether the current state of data fetching is considered completed or not. If it is, the
                current state gets returned, otherwise the previously cached state.
        N)r   )r   r   r   loader_itersr
   r   )r#   r   r$   r$   r%   
state_dictw  s    zCombinedLoader.state_dictN)r   r'   c                 C   s
   || _ d S r    )r   )r#   r   r$   r$   r%   load_state_dict  s    zCombinedLoader.load_state_dict)r   r'   c                 C   sV   | j s
d S tttddd}G dd dt}t| j| j t|f|tt	fd|_
d | _ d S )N)rP   r   r'   c                 S   sj   | }t | tr|j} t r$tj nd}|| }t| | t|}t	
|}t |tr`||j_n||_|S )zOFunction used to reload the iterator state before once the workers are created.r   )r-   rY   rZ   r   r5   ZdistributedZget_rankr   r`   r   Zfrom_state_dictr^   r\   )rP   r   Zdataloader_to_iter_onZrankitr\   r$   r$   r%   create_loader_iters  s    




z6CombinedLoader.on_restart.<locals>.create_loader_itersc                   @   s   e Zd ZdS )z1CombinedLoader.on_restart.<locals>.DataLoaderDictN)r@   rA   rB   r$   r$   r$   r%   DataLoaderDict  s   r   r   )r   r   r   r
   dictr   r   r	   r   r   _loader_iters)r#   r   r   r   r$   r$   r%   
on_restart  s    zCombinedLoader.on_restartr,   c                 C   s   t | jttftddS )z8Return a collections of samplers extracted from loaders.samplerNr   r   r   r   r?   r/   r$   r$   r%   r     s    zCombinedLoader.samplerc                 C   s   t | jttftddS )z>Return a collections of batch samplers extracted from loaders.batch_samplerNr   r/   r$   r$   r%   r     s    zCombinedLoader.batch_samplerc                 C   sj   ddl m} t| jt|ttfd}t|t}t	| jttfrft
 }t| jtt||ttfd| _|  dS )zWraps all loaders to make sure they are cycled until the longest loader is exhausted.

        Returns:
            the wrapped loaders
        r   get_lenr   )r[   r\   r   N) pytorch_lightning.utilities.datar   r   r   r	   r   r   ru   r<   r-   rF   rY   r!   )r#   r   rv   r[   r\   r$   r$   r%   r     s    
z+CombinedLoader._wrap_loaders_max_size_cyclec                    sb   ddl m  | jdkrdS ttdddd}t| jt fdd	}t|t}t| jt||d
 dS )zWhen the model is `max_size_cycle`, compute the length across all ``CycleIterator`` and re-assign it to
        all dataloaders.r   r   rG   N)cycle_iteratorr[   r'   c                 S   s
   || _ d S r    rf   )r   r[   r$   r$   r%   set_len  s    z<CombinedLoader._apply_cycle_iterator_length.<locals>.set_lenc                    s
    | j S r    )rZ   )cr   r$   r%   rI     rJ   z=CombinedLoader._apply_cycle_iterator_length.<locals>.<lambda>rf   )	r   r   rH   rY   rD   r   r   ru   r<   )r#   r   rv   
max_lengthr$   r   r%   _apply_cycle_iterator_length  s    

z+CombinedLoader._apply_cycle_iterator_lengthc                 C   s4   t tddd}|t_t| j}| | || _|S )zQCreate and return an iterator, `CombinedLoaderIterator`, for the combined loader.)_r'   c                  W   s   i S r    r$   )r   r$   r$   r%   __getstate__patch__  s    z4CombinedLoader.__iter__.<locals>.__getstate__patch__)r   r   r   __getstate__CombinedLoaderIteratorr   r   r   )r#   r   r   r$   r$   r%   ra     s    

zCombinedLoader.__iter__)r   rH   r'   c                 C   sH   ddl m} t| t|ttfd}t|ttfr2|S t	||dkrBt
ntS )a  Compute the length (aka the number of batches) of `CombinedLoader`.

        Args:
            loaders: a collections of loaders.
            mode: Mode used by the CombinedDataloader

        Returns:
            length: the minimum length of loaders
        r   r   r   rG   )r   r   r   r	   r   r   r-   rD   r.   ru   r<   r=   )r   rH   r   rv   r$   r$   r%   _calc_num_batches  s
    z CombinedLoader._calc_num_batchesc                 C   s   | j | j| jdS )N)rH   )r   r   rH   r/   r$   r$   r%   rb     s    zCombinedLoader.__len__)rP   r'   c                 C   s*   t | dr t| jtr | j  d | _d S )Nr   )hasattrr-   r   r   Z_shutdown_workers)rP   r$   r$   r%   $_shutdown_workers_and_reset_iterator  s    
z3CombinedLoader._shutdown_workers_and_reset_iteratorc                 C   s2   | j rd | j _| jd ur(t| jt| j d | _ d S r    )r   r   r   r   r   r   r/   r$   r$   r%   r!     s
    
zCombinedLoader.reset)ri   )F)ri   )"r@   rA   rB   rC   r   r   rE   r&   r   r   r
   rD   r   r   rW   r   r   r   rX   r   r	   r   r   r   r   r   r   ra   r.   r   rb   r   r   r!   r$   r$   r$   r%   r   6  s*   -r   c                   @   s   e Zd ZdZedddZeedddZeddd	Zedd
dZ	e
eeeef edddZe
eeeeef eeeeef dddZdS )r   zVCustom Iterator returning data from multiple loaders, and allows sampling in parallel.r   c                 C   s   || _ d| _dS )zf
        Args:
            loaders: the loaders to sample from. Can be all kind of collection
        N)r   r   )r#   r   r$   r$   r%   r&      s    zCombinedLoaderIterator.__init__r,   c                 C   s   | j du r| | j| _ | j S )z5Get the `_loader_iters` and create one if it is None.N)r   r   r   r/   r$   r$   r%   r   (  s    
z#CombinedLoaderIterator.loader_itersc                 C   s   | S r    r$   r/   r$   r$   r%   ra   0  s    zCombinedLoaderIterator.__iter__c                 C   s   |  | jS )zuFetches the next batch from multiple data loaders.

        Returns:
            a collections of batch data
        )request_next_batchr   r/   r$   r$   r%   re   3  s    zCombinedLoaderIterator.__next__)r   r'   c                 C   s   t | ttS )zReturn the batch of data from multiple iterators.

        Args:
            loader_iters: a collections of iterators

        Returns
            Any: a collections of batch data
        )r   r
   rd   )r   r$   r$   r%   r   ;  s    
z)CombinedLoaderIterator.request_next_batch)r   r'   c                 C   s   t | ttttfdS )zCreate and return a collection of iterators from loaders.

        Args:
            loaders: a collections of loaders

        Returns
            a collections of iterators
        r   )r   r	   r`   r   r   r   r$   r$   r%   r   G  s    z*CombinedLoaderIterator.create_loader_itersN)r@   rA   rB   rC   r   r&   rX   r   ra   re   r   r   r
   r   r   r   r   r$   r$   r$   r%   r     s   r   )rx   rw   r'   c                 C   s   t | ttfr| S t | tr(t|  } t | tsFtdt| j	 g }| D ].}t |ttfrr|
t|| qN|
| qN||S )Nz6Expected data to be int, Sequence or Mapping, but got )r-   r.   rD   r   rn   rT   r   r   typer@   r8   ru   )rx   rw   Znew_datar1   r$   r$   r%   ru   W  s    

ru   )1collections.abcr   Zdataclassesr   r   r   typingr   r   r   r	   r
   r   r   r   r   r   r5   Z#lightning_utilities.core.apply_funcr   r   r   Ztorch.utils.datar   Ztorch.utils.data.dataloaderr   r   r   Ztorch.utils.data.datasetr   Z&lightning_fabric.utilities.distributedr   Z(pytorch_lightning.utilities.auto_restartr   r   r   Z&pytorch_lightning.utilities.exceptionsr   Z#pytorch_lightning.utilities.importsr   r   rF   rY   rg   r   r   rD   r.   ru   r$   r$   r$   r%   <module>   s.   0MRV h;*
