File size: 1,858 Bytes
3b2d368
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import math
import torch
from torch.utils.data import DistributedSampler

# WARNING: Do NOT change your GPU count when using this sampler- it will not resume properly
class ResumableSampler(DistributedSampler):
    def __init__(self, dataset, num_replicas=None, rank=None, shuffle=True, seed=0, drop_last=False):
        super().__init__(dataset, num_replicas, rank, shuffle, seed, drop_last)
        self.start_index = 0
        self.batch_size = 0

    # Follows the default DistributedSampler exactly, but with the addition of the start_index term
    def __iter__(self):
        if self.shuffle:
            g = torch.Generator()
            g.manual_seed(self.seed + self.epoch)
            indices = torch.randperm(len(self.dataset), generator=g).tolist()
        else:
            indices = list(range(len(self.dataset)))

        if not self.drop_last:
            padding_size = self.total_size - len(indices)
            if padding_size <= len(indices):
                indices += indices[:padding_size]
            else:
                indices += (indices * math.ceil(padding_size / len(indices)))[:padding_size]
        else:
            indices = indices[:self.total_size]

        assert len(indices) == self.total_size

        indices = indices[self.rank:self.total_size:self.num_replicas]
        assert len(indices) == self.num_samples

        skip = self.start_index * self.batch_size
        
        self.start_index = 0 # Reset for future epochs
        
        if skip >= len(indices):
            return iter([])
        indices = indices[skip:]

        return iter(indices)

    # Make sure this is per-rank-step (do NOT multiply by worldsize, but DO include gradient acumulations when necessary)
    def set_start_index(self, start_index, batch_size):
        self.start_index = start_index
        self.batch_size = batch_size