o
    
jz                     @   s   d dl Z d dlZd dlmZmZmZ d dlmZmZm	Z	 G dd deZ
G dd deZdd	 ZG d
d deZG dd deZdS )    N)CallableListUnion)BatchSamplerSamplerSubsetRandomSamplerc                       s0   e Zd ZdZ fddZdd Zdd Z  ZS )SubsetSamplerz~
    Samples elements sequentially from a given list of indices.

    Args:
        indices (list): a sequence of indices
    c                    s   t  | || _d S N)super__init__indices)selfr   	__class__ E/home/kuhnn/.local/lib/python3.10/site-packages/TTS/utils/samplers.pyr      s   
zSubsetSampler.__init__c                    s    fddt t jD S )Nc                 3   s    | ]} j | V  qd S r	   )r   .0ir   r   r   	<genexpr>   s    z)SubsetSampler.__iter__.<locals>.<genexpr>)rangelenr   r   r   r   r   __iter__   s   zSubsetSampler.__iter__c                 C   
   t | jS r	   )r   r   r   r   r   r   __len__      
zSubsetSampler.__len____name__
__module____qualname____doc__r   r   r   __classcell__r   r   r   r   r      s
    r   c                       s:   e Zd ZdZ				d fdd	Zdd	 Zd
d Z  ZS )PerfectBatchSamplera  
    Samples a mini-batch of indices for a balanced class batching

    Args:
        dataset_items(list): dataset items to sample from.
        classes (list): list of classes of dataset_items to sample from.
        batch_size (int): total number of samples to be sampled in a mini-batch.
        num_gpus (int): number of GPU in the data parallel mode.
        shuffle (bool): if True, samples randomly, otherwise samples sequentially.
        drop_last (bool): if True, drops last incomplete batch.
       TF
class_namec	                    s   t  | |||  dksJ di  t|D ]\}	}
|
| }|  vr,|	g |< q | |	 q|rA fdd|D | _n
 fdd|D | _|| _|| _|| _|| _	d S )Nr   ziBatch size must be divisible by number of classes times the number of data parallel devices (if enabled).c                       g | ]}t  | qS r   )r   r   keylabel_indicesr   r   
<listcomp>A       z0PerfectBatchSampler.__init__.<locals>.<listcomp>c                    r&   r   )r   r'   r)   r   r   r+   C   r,   )
r
   r   	enumeratekeysappend	_samplers_batch_size
_drop_last_dp_devices_num_classes_in_batch)r   dataset_itemsclasses
batch_sizenum_classes_in_batchnum_gpusshuffle	drop_last	label_keyidxitemlabelr   r)   r   r   (   s"   
zPerfectBatchSampler.__init__c           
      c   sV   g }| j t| jkrttt| j| j }nd }dd | jD }d}	 g }t|D ]\}}|d ur8||vr8q+t|d }|d u rEd} n|| q+|rNn!||7 }t|| j	krn|V  g }|d urnttt| j| j }q%| j
st|dkrt|| j  }	|	| j dkr|V  d S |d |	| j | j | j   }t|dkr|V  d S d S d S d S )Nc                 S   s   g | ]}t |qS r   )iterr   sr   r   r   r+   Q       z0PerfectBatchSampler.__iter__.<locals>.<listcomp>FTr   )r4   r   r0   randomsampler   r-   nextr/   r1   r2   r3   )
r   batchvalid_samplers_idxitersdonebr   itr=   groupsr   r   r   r   J   sJ   


zPerfectBatchSampler.__iter__c                    s$   | j | j  t fdd| jD S )Nc                 3   s$    | ]}t |  d    V  qdS )r$   N)r   rA   class_batch_sizer   r   r   s   s   " z.PerfectBatchSampler.__len__.<locals>.<genexpr>)r1   r4   minr0   r   r   rN   r   r   q   s   zPerfectBatchSampler.__len__)r$   TFr%   r   r   r   r   r   r#      s    "'r#   c                 C   s   | S r	   r   )xr   r   r   identityv   s   rR   c                       s:   e Zd ZdZefdef fddZdd Zdd Z  Z	S )	SortedSamplera  Samples elements sequentially, always in the same order.

    Taken from https://github.com/PetrochukM/PyTorch-NLP

    Args:
        data (iterable): Iterable data.
        sort_key (callable): Specifies a function of one argument that is used to extract a
            numerical comparison key from each list element.

    Example:
        >>> list(SortedSampler(range(10), sort_key=lambda i: -i))
        [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

    sort_keyc                    sT   t  | | _| _ fddt jD }t|dd d}dd |D  _d S )Nc                    s   g | ]\}}|  |fqS r   )rT   )r   r   rowr   r   r   r+      s    z*SortedSampler.__init__.<locals>.<listcomp>c                 S   s   | d S )Nr$   r   )rr   r   r   <lambda>   s    z(SortedSampler.__init__.<locals>.<lambda>)r(   c                 S   s   g | ]}|d  qS )r   r   )r   r>   r   r   r   r+      rC   )r
   r   datarT   r-   sortedsorted_indexes)r   rX   rT   zip_r   r   r   r      s   zSortedSampler.__init__c                 C   r   r	   )r@   rZ   r   r   r   r   r      r   zSortedSampler.__iter__c                 C   r   r	   )r   rX   r   r   r   r   r      r   zSortedSampler.__len__)
r   r   r    r!   rR   r   r   r   r   r"   r   r   r   r   rS   z   s
    rS   c                       sD   e Zd ZdZedfdeeef f fddZdd Z	dd	 Z
  ZS )
BucketBatchSamplera  Bucket batch sampler

    Adapted from https://github.com/PetrochukM/PyTorch-NLP

    Args:
        sampler (torch.data.utils.sampler.Sampler):
        batch_size (int): Size of mini-batch.
        drop_last (bool): If `True` the sampler will drop the last batch if its size would be less
            than `batch_size`.
        data (list): List of data samples.
        sort_key (callable, optional): Callable to specify a comparison key for sorting.
        bucket_size_multiplier (int, optional): Buckets are of size
            `batch_size * bucket_size_multiplier`.

    Example:
        >>> sampler = WeightedRandomSampler(weights, len(weights))
        >>> sampler = BucketBatchSampler(sampler, data=data_items, batch_size=32, drop_last=True)
    d   rT   c                    sN   t  ||| || _|| _|| }t|drt|t|}t||d| _d S )Nr   F)	r
   r   rX   rT   hasattrrP   r   r   bucket_sampler)r   samplerrX   r7   r;   rT   bucket_size_multiplier_bucket_sizer   r   r   r      s   	
zBucketBatchSampler.__init__c                 #   sf    j D ], fdd D }t|j}ttt|jjD ]} fdd|D }|V  q!qd S )Nc                    s   g | ]} j | qS r   )rX   )r   r=   r   r   r   r+      s    z/BucketBatchSampler.__iter__.<locals>.<listcomp>c                    s   g | ]} | qS r   r   r   )idxsr   r   r+      rC   )r_   rS   rT   r   listr   r7   r;   )r   bucket_datasorted_sampler	batch_idxsorted_idxsr   )rc   r   r   r      s   
zBucketBatchSampler.__iter__c                 C   s,   | j rt| j| j S tt| j| j S r	   )r;   r   r`   r7   mathceilr   r   r   r   r      s   zBucketBatchSampler.__len__)r   r   r    r!   rR   r   r   r   r   r   r   r"   r   r   r   r   r\      s    
r\   )ri   rD   typingr   r   r   torch.utils.data.samplerr   r   r   r   r#   rR   rS   r\   r   r   r   r   <module>   s    [