a
    hy                     @   s   d dl Z d dlmZmZ d dl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 G dd deZG dd	 d	eZG d
d deZdS )    N)IteratorSized)castOptionalUnion)Sampler)
VideoClipsc                   @   sb   e Zd ZdZdeee ee eeddddZe	e dd	d
Z
edddZeddddZdS )DistributedSamplera  
    Extension of DistributedSampler, as discussed in
    https://github.com/pytorch/pytorch/issues/23430

    Example:
        dataset: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
        num_replicas: 4
        shuffle: False

    when group_size = 1
            RANK    |  shard_dataset
            =========================
            rank_0  |  [0, 4, 8, 12]
            rank_1  |  [1, 5, 9, 13]
            rank_2  |  [2, 6, 10, 0]
            rank_3  |  [3, 7, 11, 1]

    when group_size = 2

            RANK    |  shard_dataset
            =========================
            rank_0  |  [0, 1, 8, 9]
            rank_1  |  [2, 3, 10, 11]
            rank_2  |  [4, 5, 12, 13]
            rank_3  |  [6, 7, 0, 1]

    NF   )datasetnum_replicasrankshuffle
group_sizereturnc                 C   s   |d u r t  stdt  }|d u r@t  s8tdt  }t|| dkrhtdt| d| || _|| _|| _	|| _
d| _t|| }tt|d | j	 | _| j| | _| j| j	 | _|| _d S )Nz,Requires distributed package to be availabler   zBdataset length must be a multiplier of group size dataset length: z, group size: g      ?)distZis_availableRuntimeErrorZget_world_sizeZget_ranklen
ValueErrorr   r   r   r   epochintmathceilZnum_group_samplesnum_samples
total_sizer   )selfr   r   r   r   r   Zdataset_group_length r   X/var/www/auris/lib/python3.9/site-packages/torchvision/datasets/samplers/clip_sampler.py__init__(   s,    zDistributedSampler.__init__r   c                    s  t  }|| j | jr4t jt| j|d }nt	t
t| j}||d | jt|  7 }t|| jksrJ | j| j }t t ||| jf}|| j|| jd d f }t |d }t|| jksJ t| jtrt	t| j  fdd|D }t|S )N)	generator)c                    s   g | ]} | qS r   r   ).0iZorig_indicesr   r   
<listcomp>_       z/DistributedSampler.__iter__.<locals>.<listcomp>)torch	GeneratorZmanual_seedr   r   randpermr   r   tolistlistranger   r   ZreshapeZ
LongTensorr   r   r   
isinstancer   iter)r   gindicesZtotal_group_sizer   r$   r   __iter__G   s     zDistributedSampler.__iter__c                 C   s   | j S N)r   r   r   r   r   __len__c   s    zDistributedSampler.__len__)r   r   c                 C   s
   || _ d S r2   )r   )r   r   r   r   r   	set_epochf   s    zDistributedSampler.set_epoch)NNFr
   )__name__
__module____qualname____doc__r   r   r   boolr   r   r1   r4   r5   r   r   r   r   r	      s        r	   c                   @   sB   e Zd ZdZeeddddZee dddZedd	d
Z	dS )UniformClipSamplera  
    Sample `num_video_clips_per_video` clips for each video, equally spaced.
    When number of unique clips in the video is fewer than num_video_clips_per_video,
    repeat the clips until `num_video_clips_per_video` clips are collected

    Args:
        video_clips (VideoClips): video clips to sample from
        num_clips_per_video (int): number of clips to be sampled per video
    N)video_clipsnum_clips_per_videor   c                 C   s,   t |tstdt| || _|| _d S Nz:Expected video_clips to be an instance of VideoClips, got )r-   r   	TypeErrortyper<   r=   )r   r<   r=   r   r   r   r   u   s    
zUniformClipSampler.__init__r   c                 C   s|   g }d}| j jD ]N}t|}|dkr&qtj||| d | jd tj}||7 }|	| qt
ttt t| S )Nr   r
   )Zsteps)r<   clipsr   r'   Zlinspacer=   floortoint64appendr.   r   r+   r   catr*   )r   idxssclengthsampledr   r   r   r1   {   s    &zUniformClipSampler.__iter__c                    s   t  fdd jjD S )Nc                 3   s    | ]}t |d kr jV  qdS )r   N)r   r=   r"   rI   r3   r   r   	<genexpr>   r&   z-UniformClipSampler.__len__.<locals>.<genexpr>sumr<   rA   r3   r   r3   r   r4      s    zUniformClipSampler.__len__
r6   r7   r8   r9   r   r   r   r   r1   r4   r   r   r   r   r;   j   s   
r;   c                   @   sB   e Zd ZdZeeddddZee dddZedd	d
Z	dS )RandomClipSamplerz
    Samples at most `max_video_clips_per_video` clips for each video randomly

    Args:
        video_clips (VideoClips): video clips to sample from
        max_clips_per_video (int): maximum number of clips to be sampled per video
    N)r<   max_clips_per_videor   c                 C   s,   t |tstdt| || _|| _d S r>   )r-   r   r?   r@   r<   rR   )r   r<   rR   r   r   r   r      s    
zRandomClipSampler.__init__r   c           	      C   sz   g }d}| j jD ]@}t|}t|| j}t|d | | }||7 }|| qt|}tt|}t	|| 
 S )Nr   )r<   rA   r   minrR   r'   r)   rE   rF   r.   r*   )	r   rG   rH   rI   rJ   sizerK   Zidxs_permr   r   r   r1      s    
zRandomClipSampler.__iter__c                    s   t  fdd jjD S )Nc                 3   s   | ]}t t| jV  qd S r2   )rS   r   rR   rL   r3   r   r   rM      r&   z,RandomClipSampler.__len__.<locals>.<genexpr>rN   r3   r   r3   r   r4      s    zRandomClipSampler.__len__rP   r   r   r   r   rQ      s   rQ   )r   collections.abcr   r   typingr   r   r   r'   Ztorch.distributedZdistributedr   Ztorch.utils.datar   Z torchvision.datasets.video_utilsr   r	   r;   rQ   r   r   r   r   <module>   s   _$