| 3 | |
| 4 | |
| 5 | class DistributedSampler(_DistributedSampler): |
| 6 | |
| 7 | def __init__(self, |
| 8 | dataset, |
| 9 | num_replicas=None, |
| 10 | rank=None, |
| 11 | shuffle=True, |
| 12 | round_up=True): |
| 13 | super().__init__(dataset, num_replicas=num_replicas, rank=rank) |
| 14 | self.shuffle = shuffle |
| 15 | self.round_up = round_up |
| 16 | if self.round_up: |
| 17 | self.total_size = self.num_samples * self.num_replicas |
| 18 | else: |
| 19 | self.total_size = len(self.dataset) |
| 20 | |
| 21 | def __iter__(self): |
| 22 | # deterministically shuffle based on epoch |
| 23 | if self.shuffle: |
| 24 | g = torch.Generator() |
| 25 | g.manual_seed(self.epoch) |
| 26 | indices = torch.randperm(len(self.dataset), generator=g).tolist() |
| 27 | else: |
| 28 | indices = torch.arange(len(self.dataset)).tolist() |
| 29 | |
| 30 | # add extra samples to make it evenly divisible |
| 31 | if self.round_up: |
| 32 | indices = ( |
| 33 | indices * |
| 34 | int(self.total_size / len(indices) + 1))[:self.total_size] |
| 35 | assert len(indices) == self.total_size |
| 36 | |
| 37 | # subsample |
| 38 | indices = indices[self.rank:self.total_size:self.num_replicas] |
| 39 | if self.round_up: |
| 40 | assert len(indices) == self.num_samples |
| 41 | |
| 42 | return iter(indices) |