Distributed Sampler that subsamples indicies sequentially, making it easier to collate all results at the end. Even though we only use this sampler for eval and predict (no training), which means that the model params won't have to be synced (i.e. will not hang for synchronizat
| 88 | |
| 89 | |
| 90 | class SequentialDistributedSampler(Sampler): |
| 91 | """ |
| 92 | Distributed Sampler that subsamples indicies sequentially, |
| 93 | making it easier to collate all results at the end. |
| 94 | |
| 95 | Even though we only use this sampler for eval and predict (no training), |
| 96 | which means that the model params won't have to be synced (i.e. will not hang |
| 97 | for synchronization even if varied number of forward passes), we still add extra |
| 98 | samples to the sampler to make it evenly divisible (like in `DistributedSampler`) |
| 99 | to make it easy to `gather` or `reduce` resulting tensors at the end of the loop. |
| 100 | """ |
| 101 | |
| 102 | def __init__(self, dataset, num_replicas=None, rank=None): |
| 103 | if num_replicas is None: |
| 104 | if not torch.distributed.is_available(): |
| 105 | raise RuntimeError("Requires distributed package to be available") |
| 106 | num_replicas = torch.distributed.get_world_size() |
| 107 | if rank is None: |
| 108 | if not torch.distributed.is_available(): |
| 109 | raise RuntimeError("Requires distributed package to be available") |
| 110 | rank = torch.distributed.get_rank() |
| 111 | self.dataset = dataset |
| 112 | self.num_replicas = num_replicas |
| 113 | self.rank = rank |
| 114 | self.num_samples = int(math.ceil(len(self.dataset) * 1.0 / self.num_replicas)) |
| 115 | self.total_size = self.num_samples * self.num_replicas |
| 116 | |
| 117 | def __iter__(self): |
| 118 | indices = list(range(len(self.dataset))) |
| 119 | |
| 120 | # add extra samples to make it evenly divisible |
| 121 | indices += indices[: (self.total_size - len(indices))] |
| 122 | assert len(indices) == self.total_size |
| 123 | |
| 124 | # subsample |
| 125 | indices = indices[self.rank * self.num_samples : (self.rank + 1) * self.num_samples] |
| 126 | assert len(indices) == self.num_samples |
| 127 | |
| 128 | return iter(indices) |
| 129 | |
| 130 | def __len__(self): |
| 131 | return self.num_samples |
| 132 | |
| 133 | |
| 134 | def get_tpu_sampler(dataset: Dataset): |
no outgoing calls
no test coverage detected