We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Seed in sampler
https://github.com/open-mmlab/mmdetection/pull/4665

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `mmaction/datasets/builder.py`
Content:
```
1 import platform
2 import random
3 from functools import partial
4 
5 import numpy as np
6 from mmcv.parallel import collate
7 from mmcv.runner import get_dist_info
8 from mmcv.utils import build_from_cfg
9 from torch.utils.data import DataLoader
10 
11 from .dataset_wrappers import RepeatDataset
12 from .registry import DATASETS
13 from .samplers import DistributedPowerSampler, DistributedSampler
14 
15 if platform.system() != 'Windows':
16     # https://github.com/pytorch/pytorch/issues/973
17     import resource
18     rlimit = resource.getrlimit(resource.RLIMIT_NOFILE)
19     hard_limit = rlimit[1]
20     soft_limit = min(4096, hard_limit)
21     resource.setrlimit(resource.RLIMIT_NOFILE, (soft_limit, hard_limit))
22 
23 
24 def build_dataset(cfg, default_args=None):
25     """Build a dataset from config dict.
26 
27     Args:
28         cfg (dict): Config dict. It should at least contain the key "type".
29         default_args (dict | None, optional): Default initialization arguments.
30             Default: None.
31 
32     Returns:
33         Dataset: The constructed dataset.
34     """
35     if cfg['type'] == 'RepeatDataset':
36         dataset = RepeatDataset(
37             build_dataset(cfg['dataset'], default_args), cfg['times'])
38     else:
39         dataset = build_from_cfg(cfg, DATASETS, default_args)
40     return dataset
41 
42 
43 def build_dataloader(dataset,
44                      videos_per_gpu,
45                      workers_per_gpu,
46                      num_gpus=1,
47                      dist=True,
48                      shuffle=True,
49                      seed=None,
50                      drop_last=False,
51                      pin_memory=True,
52                      **kwargs):
53     """Build PyTorch DataLoader.
54 
55     In distributed training, each GPU/process has a dataloader.
56     In non-distributed training, there is only one dataloader for all GPUs.
57 
58     Args:
59         dataset (:obj:`Dataset`): A PyTorch dataset.
60         videos_per_gpu (int): Number of videos on each GPU, i.e.,
61             batch size of each GPU.
62         workers_per_gpu (int): How many subprocesses to use for data
63             loading for each GPU.
64         num_gpus (int): Number of GPUs. Only used in non-distributed
65             training. Default: 1.
66         dist (bool): Distributed training/test or not. Default: True.
67         shuffle (bool): Whether to shuffle the data at every epoch.
68             Default: True.
69         seed (int | None): Seed to be used. Default: None.
70         drop_last (bool): Whether to drop the last incomplete batch in epoch.
71             Default: False
72         pin_memory (bool): Whether to use pin_memory in DataLoader.
73             Default: True
74         kwargs (dict, optional): Any keyword argument to be used to initialize
75             DataLoader.
76 
77     Returns:
78         DataLoader: A PyTorch dataloader.
79     """
80     rank, world_size = get_dist_info()
81     sample_by_class = getattr(dataset, 'sample_by_class', False)
82     power = getattr(dataset, 'power', None)
83 
84     if dist:
85         if sample_by_class:
86             assert power is not None
87             sampler = DistributedPowerSampler(dataset, world_size, rank, power)
88         else:
89             sampler = DistributedSampler(
90                 dataset, world_size, rank, shuffle=shuffle)
91         shuffle = False
92         batch_size = videos_per_gpu
93         num_workers = workers_per_gpu
94     else:
95         sampler = None
96         batch_size = num_gpus * videos_per_gpu
97         num_workers = num_gpus * workers_per_gpu
98 
99     init_fn = partial(
100         worker_init_fn, num_workers=num_workers, rank=rank,
101         seed=seed) if seed is not None else None
102 
103     data_loader = DataLoader(
104         dataset,
105         batch_size=batch_size,
106         sampler=sampler,
107         num_workers=num_workers,
108         collate_fn=partial(collate, samples_per_gpu=videos_per_gpu),
109         pin_memory=pin_memory,
110         shuffle=shuffle,
111         worker_init_fn=init_fn,
112         drop_last=drop_last,
113         **kwargs)
114 
115     return data_loader
116 
117 
118 def worker_init_fn(worker_id, num_workers, rank, seed):
119     """Init the random seed for various workers."""
120     # The seed of each worker equals to
121     # num_worker * rank + worker_id + user_seed
122     worker_seed = num_workers * rank + worker_id + seed
123     np.random.seed(worker_seed)
124     random.seed(worker_seed)
125
```

Path: `mmaction/datasets/samplers/distributed_sampler.py`
Content:
```
1 import torch
2 from torch.utils.data import DistributedSampler as _DistributedSampler
3 
4 
5 class DistributedSampler(_DistributedSampler):
6     """DistributedSampler inheriting from
7     ``torch.utils.data.DistributedSampler``.
8 
9     In pytorch of lower versions, there is no ``shuffle`` argument. This child
10     class will port one to DistributedSampler.
11     """
12 
13     def __init__(self, dataset, num_replicas=None, rank=None, shuffle=True):
14         super().__init__(dataset, num_replicas=num_replicas, rank=rank)
15         self.shuffle = shuffle
16 
17     def __iter__(self):
18         # deterministically shuffle based on epoch
19         if self.shuffle:
20             g = torch.Generator()
21             g.manual_seed(self.epoch)
22             indices = torch.randperm(len(self.dataset), generator=g).tolist()
23         else:
24             indices = torch.arange(len(self.dataset)).tolist()
25 
26         # add extra samples to make it evenly divisible
27         indices += indices[:(self.total_size - len(indices))]
28         assert len(indices) == self.total_size
29 
30         # subsample
31         indices = indices[self.rank:self.total_size:self.num_replicas]
32         assert len(indices) == self.num_samples
33         return iter(indices)
34 
35 
36 class DistributedPowerSampler(_DistributedSampler):
37     """DistributedPowerSampler inheriting from
38     ``torch.utils.data.DistributedSampler``.
39 
40     Samples are sampled with the probability that is proportional to the power
41     of label frequency (freq ^ power). The sampler only applies to single class
42     recognition dataset.
43 
44     The default value of power is 1, which is equivalent to bootstrap sampling
45     from the entire dataset.
46     """
47 
48     def __init__(self, dataset, num_replicas=None, rank=None, power=1):
49         super().__init__(dataset, num_replicas=num_replicas, rank=rank)
50         self.power = power
51 
52     def __iter__(self):
53         # deterministically shuffle based on epoch
54         g = torch.Generator()
55         g.manual_seed(self.epoch)
56         video_infos_by_class = self.dataset.video_infos_by_class
57         num_classes = self.dataset.num_classes
58         # For simplicity, discontinuous labels are not permitted
59         assert set(video_infos_by_class) == set(range(num_classes))
60         counts = [len(video_infos_by_class[i]) for i in range(num_classes)]
61         counts = [cnt**self.power for cnt in counts]
62 
63         indices = torch.multinomial(
64             torch.Tensor(counts),
65             self.total_size,
66             replacement=True,
67             generator=g)
68         indices = indices.data.numpy().tolist()
69         assert len(indices) == self.total_size
70 
71         indices = indices[self.rank:self.total_size:self.num_replicas]
72         assert len(indices) == self.num_samples
73 
74         return iter(indices)
75
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/mmaction/datasets/builder.py b/mmaction/datasets/builder.py
--- a/mmaction/datasets/builder.py
+++ b/mmaction/datasets/builder.py
@@ -84,10 +84,11 @@
     if dist:
         if sample_by_class:
             assert power is not None
-            sampler = DistributedPowerSampler(dataset, world_size, rank, power)
+            sampler = DistributedPowerSampler(
+                dataset, world_size, rank, power, seed=seed)
         else:
             sampler = DistributedSampler(
-                dataset, world_size, rank, shuffle=shuffle)
+                dataset, world_size, rank, shuffle=shuffle, seed=seed)
         shuffle = False
         batch_size = videos_per_gpu
         num_workers = workers_per_gpu
diff --git a/mmaction/datasets/samplers/distributed_sampler.py b/mmaction/datasets/samplers/distributed_sampler.py
--- a/mmaction/datasets/samplers/distributed_sampler.py
+++ b/mmaction/datasets/samplers/distributed_sampler.py
@@ -10,15 +10,22 @@
     class will port one to DistributedSampler.
     """
 
-    def __init__(self, dataset, num_replicas=None, rank=None, shuffle=True):
-        super().__init__(dataset, num_replicas=num_replicas, rank=rank)
-        self.shuffle = shuffle
+    def __init__(self,
+                 dataset,
+                 num_replicas=None,
+                 rank=None,
+                 shuffle=True,
+                 seed=0):
+        super().__init__(
+            dataset, num_replicas=num_replicas, rank=rank, shuffle=shuffle)
+        # for the compatibility from PyTorch 1.3+
+        self.seed = seed if seed is not None else 0
 
     def __iter__(self):
         # deterministically shuffle based on epoch
         if self.shuffle:
             g = torch.Generator()
-            g.manual_seed(self.epoch)
+            g.manual_seed(self.epoch + self.seed)
             indices = torch.randperm(len(self.dataset), generator=g).tolist()
         else:
             indices = torch.arange(len(self.dataset)).tolist()
@@ -45,14 +52,15 @@
     from the entire dataset.
     """
 
-    def __init__(self, dataset, num_replicas=None, rank=None, power=1):
+    def __init__(self, dataset, num_replicas=None, rank=None, power=1, seed=0):
         super().__init__(dataset, num_replicas=num_replicas, rank=rank)
         self.power = power
+        self.seed = seed if seed is not None else 0
 
     def __iter__(self):
         # deterministically shuffle based on epoch
         g = torch.Generator()
-        g.manual_seed(self.epoch)
+        g.manual_seed(self.epoch + self.seed)
         video_infos_by_class = self.dataset.video_infos_by_class
         num_classes = self.dataset.num_classes
         # For simplicity, discontinuous labels are not permitted

{"golden_diff": "diff --git a/mmaction/datasets/builder.py b/mmaction/datasets/builder.py\n--- a/mmaction/datasets/builder.py\n+++ b/mmaction/datasets/builder.py\n@@ -84,10 +84,11 @@\n     if dist:\n         if sample_by_class:\n             assert power is not None\n-            sampler = DistributedPowerSampler(dataset, world_size, rank, power)\n+            sampler = DistributedPowerSampler(\n+                dataset, world_size, rank, power, seed=seed)\n         else:\n             sampler = DistributedSampler(\n-                dataset, world_size, rank, shuffle=shuffle)\n+                dataset, world_size, rank, shuffle=shuffle, seed=seed)\n         shuffle = False\n         batch_size = videos_per_gpu\n         num_workers = workers_per_gpu\ndiff --git a/mmaction/datasets/samplers/distributed_sampler.py b/mmaction/datasets/samplers/distributed_sampler.py\n--- a/mmaction/datasets/samplers/distributed_sampler.py\n+++ b/mmaction/datasets/samplers/distributed_sampler.py\n@@ -10,15 +10,22 @@\n     class will port one to DistributedSampler.\n     \"\"\"\n \n-    def __init__(self, dataset, num_replicas=None, rank=None, shuffle=True):\n-        super().__init__(dataset, num_replicas=num_replicas, rank=rank)\n-        self.shuffle = shuffle\n+    def __init__(self,\n+                 dataset,\n+                 num_replicas=None,\n+                 rank=None,\n+                 shuffle=True,\n+                 seed=0):\n+        super().__init__(\n+            dataset, num_replicas=num_replicas, rank=rank, shuffle=shuffle)\n+        # for the compatibility from PyTorch 1.3+\n+        self.seed = seed if seed is not None else 0\n \n     def __iter__(self):\n         # deterministically shuffle based on epoch\n         if self.shuffle:\n             g = torch.Generator()\n-            g.manual_seed(self.epoch)\n+            g.manual_seed(self.epoch + self.seed)\n             indices = torch.randperm(len(self.dataset), generator=g).tolist()\n         else:\n             indices = torch.arange(len(self.dataset)).tolist()\n@@ -45,14 +52,15 @@\n     from the entire dataset.\n     \"\"\"\n \n-    def __init__(self, dataset, num_replicas=None, rank=None, power=1):\n+    def __init__(self, dataset, num_replicas=None, rank=None, power=1, seed=0):\n         super().__init__(dataset, num_replicas=num_replicas, rank=rank)\n         self.power = power\n+        self.seed = seed if seed is not None else 0\n \n     def __iter__(self):\n         # deterministically shuffle based on epoch\n         g = torch.Generator()\n-        g.manual_seed(self.epoch)\n+        g.manual_seed(self.epoch + self.seed)\n         video_infos_by_class = self.dataset.video_infos_by_class\n         num_classes = self.dataset.num_classes\n         # For simplicity, discontinuous labels are not permitted\n", "issue": "Seed in sampler\nhttps://github.com/open-mmlab/mmdetection/pull/4665\n", "before_files": [{"content": "import platform\nimport random\nfrom functools import partial\n\nimport numpy as np\nfrom mmcv.parallel import collate\nfrom mmcv.runner import get_dist_info\nfrom mmcv.utils import build_from_cfg\nfrom torch.utils.data import DataLoader\n\nfrom .dataset_wrappers import RepeatDataset\nfrom .registry import DATASETS\nfrom .samplers import DistributedPowerSampler, DistributedSampler\n\nif platform.system() != 'Windows':\n    # https://github.com/pytorch/pytorch/issues/973\n    import resource\n    rlimit = resource.getrlimit(resource.RLIMIT_NOFILE)\n    hard_limit = rlimit[1]\n    soft_limit = min(4096, hard_limit)\n    resource.setrlimit(resource.RLIMIT_NOFILE, (soft_limit, hard_limit))\n\n\ndef build_dataset(cfg, default_args=None):\n    \"\"\"Build a dataset from config dict.\n\n    Args:\n        cfg (dict): Config dict. It should at least contain the key \"type\".\n        default_args (dict | None, optional): Default initialization arguments.\n            Default: None.\n\n    Returns:\n        Dataset: The constructed dataset.\n    \"\"\"\n    if cfg['type'] == 'RepeatDataset':\n        dataset = RepeatDataset(\n            build_dataset(cfg['dataset'], default_args), cfg['times'])\n    else:\n        dataset = build_from_cfg(cfg, DATASETS, default_args)\n    return dataset\n\n\ndef build_dataloader(dataset,\n                     videos_per_gpu,\n                     workers_per_gpu,\n                     num_gpus=1,\n                     dist=True,\n                     shuffle=True,\n                     seed=None,\n                     drop_last=False,\n                     pin_memory=True,\n                     **kwargs):\n    \"\"\"Build PyTorch DataLoader.\n\n    In distributed training, each GPU/process has a dataloader.\n    In non-distributed training, there is only one dataloader for all GPUs.\n\n    Args:\n        dataset (:obj:`Dataset`): A PyTorch dataset.\n        videos_per_gpu (int): Number of videos on each GPU, i.e.,\n            batch size of each GPU.\n        workers_per_gpu (int): How many subprocesses to use for data\n            loading for each GPU.\n        num_gpus (int): Number of GPUs. Only used in non-distributed\n            training. Default: 1.\n        dist (bool): Distributed training/test or not. Default: True.\n        shuffle (bool): Whether to shuffle the data at every epoch.\n            Default: True.\n        seed (int | None): Seed to be used. Default: None.\n        drop_last (bool): Whether to drop the last incomplete batch in epoch.\n            Default: False\n        pin_memory (bool): Whether to use pin_memory in DataLoader.\n            Default: True\n        kwargs (dict, optional): Any keyword argument to be used to initialize\n            DataLoader.\n\n    Returns:\n        DataLoader: A PyTorch dataloader.\n    \"\"\"\n    rank, world_size = get_dist_info()\n    sample_by_class = getattr(dataset, 'sample_by_class', False)\n    power = getattr(dataset, 'power', None)\n\n    if dist:\n        if sample_by_class:\n            assert power is not None\n            sampler = DistributedPowerSampler(dataset, world_size, rank, power)\n        else:\n            sampler = DistributedSampler(\n                dataset, world_size, rank, shuffle=shuffle)\n        shuffle = False\n        batch_size = videos_per_gpu\n        num_workers = workers_per_gpu\n    else:\n        sampler = None\n        batch_size = num_gpus * videos_per_gpu\n        num_workers = num_gpus * workers_per_gpu\n\n    init_fn = partial(\n        worker_init_fn, num_workers=num_workers, rank=rank,\n        seed=seed) if seed is not None else None\n\n    data_loader = DataLoader(\n        dataset,\n        batch_size=batch_size,\n        sampler=sampler,\n        num_workers=num_workers,\n        collate_fn=partial(collate, samples_per_gpu=videos_per_gpu),\n        pin_memory=pin_memory,\n        shuffle=shuffle,\n        worker_init_fn=init_fn,\n        drop_last=drop_last,\n        **kwargs)\n\n    return data_loader\n\n\ndef worker_init_fn(worker_id, num_workers, rank, seed):\n    \"\"\"Init the random seed for various workers.\"\"\"\n    # The seed of each worker equals to\n    # num_worker * rank + worker_id + user_seed\n    worker_seed = num_workers * rank + worker_id + seed\n    np.random.seed(worker_seed)\n    random.seed(worker_seed)\n", "path": "mmaction/datasets/builder.py"}, {"content": "import torch\nfrom torch.utils.data import DistributedSampler as _DistributedSampler\n\n\nclass DistributedSampler(_DistributedSampler):\n    \"\"\"DistributedSampler inheriting from\n    ``torch.utils.data.DistributedSampler``.\n\n    In pytorch of lower versions, there is no ``shuffle`` argument. This child\n    class will port one to DistributedSampler.\n    \"\"\"\n\n    def __init__(self, dataset, num_replicas=None, rank=None, shuffle=True):\n        super().__init__(dataset, num_replicas=num_replicas, rank=rank)\n        self.shuffle = shuffle\n\n    def __iter__(self):\n        # deterministically shuffle based on epoch\n        if self.shuffle:\n            g = torch.Generator()\n            g.manual_seed(self.epoch)\n            indices = torch.randperm(len(self.dataset), generator=g).tolist()\n        else:\n            indices = torch.arange(len(self.dataset)).tolist()\n\n        # add extra samples to make it evenly divisible\n        indices += indices[:(self.total_size - len(indices))]\n        assert len(indices) == self.total_size\n\n        # subsample\n        indices = indices[self.rank:self.total_size:self.num_replicas]\n        assert len(indices) == self.num_samples\n        return iter(indices)\n\n\nclass DistributedPowerSampler(_DistributedSampler):\n    \"\"\"DistributedPowerSampler inheriting from\n    ``torch.utils.data.DistributedSampler``.\n\n    Samples are sampled with the probability that is proportional to the power\n    of label frequency (freq ^ power). The sampler only applies to single class\n    recognition dataset.\n\n    The default value of power is 1, which is equivalent to bootstrap sampling\n    from the entire dataset.\n    \"\"\"\n\n    def __init__(self, dataset, num_replicas=None, rank=None, power=1):\n        super().__init__(dataset, num_replicas=num_replicas, rank=rank)\n        self.power = power\n\n    def __iter__(self):\n        # deterministically shuffle based on epoch\n        g = torch.Generator()\n        g.manual_seed(self.epoch)\n        video_infos_by_class = self.dataset.video_infos_by_class\n        num_classes = self.dataset.num_classes\n        # For simplicity, discontinuous labels are not permitted\n        assert set(video_infos_by_class) == set(range(num_classes))\n        counts = [len(video_infos_by_class[i]) for i in range(num_classes)]\n        counts = [cnt**self.power for cnt in counts]\n\n        indices = torch.multinomial(\n            torch.Tensor(counts),\n            self.total_size,\n            replacement=True,\n            generator=g)\n        indices = indices.data.numpy().tolist()\n        assert len(indices) == self.total_size\n\n        indices = indices[self.rank:self.total_size:self.num_replicas]\n        assert len(indices) == self.num_samples\n\n        return iter(indices)\n", "path": "mmaction/datasets/samplers/distributed_sampler.py"}], "after_files": [{"content": "import platform\nimport random\nfrom functools import partial\n\nimport numpy as np\nfrom mmcv.parallel import collate\nfrom mmcv.runner import get_dist_info\nfrom mmcv.utils import build_from_cfg\nfrom torch.utils.data import DataLoader\n\nfrom .dataset_wrappers import RepeatDataset\nfrom .registry import DATASETS\nfrom .samplers import DistributedPowerSampler, DistributedSampler\n\nif platform.system() != 'Windows':\n    # https://github.com/pytorch/pytorch/issues/973\n    import resource\n    rlimit = resource.getrlimit(resource.RLIMIT_NOFILE)\n    hard_limit = rlimit[1]\n    soft_limit = min(4096, hard_limit)\n    resource.setrlimit(resource.RLIMIT_NOFILE, (soft_limit, hard_limit))\n\n\ndef build_dataset(cfg, default_args=None):\n    \"\"\"Build a dataset from config dict.\n\n    Args:\n        cfg (dict): Config dict. It should at least contain the key \"type\".\n        default_args (dict | None, optional): Default initialization arguments.\n            Default: None.\n\n    Returns:\n        Dataset: The constructed dataset.\n    \"\"\"\n    if cfg['type'] == 'RepeatDataset':\n        dataset = RepeatDataset(\n            build_dataset(cfg['dataset'], default_args), cfg['times'])\n    else:\n        dataset = build_from_cfg(cfg, DATASETS, default_args)\n    return dataset\n\n\ndef build_dataloader(dataset,\n                     videos_per_gpu,\n                     workers_per_gpu,\n                     num_gpus=1,\n                     dist=True,\n                     shuffle=True,\n                     seed=None,\n                     drop_last=False,\n                     pin_memory=True,\n                     **kwargs):\n    \"\"\"Build PyTorch DataLoader.\n\n    In distributed training, each GPU/process has a dataloader.\n    In non-distributed training, there is only one dataloader for all GPUs.\n\n    Args:\n        dataset (:obj:`Dataset`): A PyTorch dataset.\n        videos_per_gpu (int): Number of videos on each GPU, i.e.,\n            batch size of each GPU.\n        workers_per_gpu (int): How many subprocesses to use for data\n            loading for each GPU.\n        num_gpus (int): Number of GPUs. Only used in non-distributed\n            training. Default: 1.\n        dist (bool): Distributed training/test or not. Default: True.\n        shuffle (bool): Whether to shuffle the data at every epoch.\n            Default: True.\n        seed (int | None): Seed to be used. Default: None.\n        drop_last (bool): Whether to drop the last incomplete batch in epoch.\n            Default: False\n        pin_memory (bool): Whether to use pin_memory in DataLoader.\n            Default: True\n        kwargs (dict, optional): Any keyword argument to be used to initialize\n            DataLoader.\n\n    Returns:\n        DataLoader: A PyTorch dataloader.\n    \"\"\"\n    rank, world_size = get_dist_info()\n    sample_by_class = getattr(dataset, 'sample_by_class', False)\n    power = getattr(dataset, 'power', None)\n\n    if dist:\n        if sample_by_class:\n            assert power is not None\n            sampler = DistributedPowerSampler(\n                dataset, world_size, rank, power, seed=seed)\n        else:\n            sampler = DistributedSampler(\n                dataset, world_size, rank, shuffle=shuffle, seed=seed)\n        shuffle = False\n        batch_size = videos_per_gpu\n        num_workers = workers_per_gpu\n    else:\n        sampler = None\n        batch_size = num_gpus * videos_per_gpu\n        num_workers = num_gpus * workers_per_gpu\n\n    init_fn = partial(\n        worker_init_fn, num_workers=num_workers, rank=rank,\n        seed=seed) if seed is not None else None\n\n    data_loader = DataLoader(\n        dataset,\n        batch_size=batch_size,\n        sampler=sampler,\n        num_workers=num_workers,\n        collate_fn=partial(collate, samples_per_gpu=videos_per_gpu),\n        pin_memory=pin_memory,\n        shuffle=shuffle,\n        worker_init_fn=init_fn,\n        drop_last=drop_last,\n        **kwargs)\n\n    return data_loader\n\n\ndef worker_init_fn(worker_id, num_workers, rank, seed):\n    \"\"\"Init the random seed for various workers.\"\"\"\n    # The seed of each worker equals to\n    # num_worker * rank + worker_id + user_seed\n    worker_seed = num_workers * rank + worker_id + seed\n    np.random.seed(worker_seed)\n    random.seed(worker_seed)\n", "path": "mmaction/datasets/builder.py"}, {"content": "import torch\nfrom torch.utils.data import DistributedSampler as _DistributedSampler\n\n\nclass DistributedSampler(_DistributedSampler):\n    \"\"\"DistributedSampler inheriting from\n    ``torch.utils.data.DistributedSampler``.\n\n    In pytorch of lower versions, there is no ``shuffle`` argument. This child\n    class will port one to DistributedSampler.\n    \"\"\"\n\n    def __init__(self,\n                 dataset,\n                 num_replicas=None,\n                 rank=None,\n                 shuffle=True,\n                 seed=0):\n        super().__init__(\n            dataset, num_replicas=num_replicas, rank=rank, shuffle=shuffle)\n        # for the compatibility from PyTorch 1.3+\n        self.seed = seed if seed is not None else 0\n\n    def __iter__(self):\n        # deterministically shuffle based on epoch\n        if self.shuffle:\n            g = torch.Generator()\n            g.manual_seed(self.epoch + self.seed)\n            indices = torch.randperm(len(self.dataset), generator=g).tolist()\n        else:\n            indices = torch.arange(len(self.dataset)).tolist()\n\n        # add extra samples to make it evenly divisible\n        indices += indices[:(self.total_size - len(indices))]\n        assert len(indices) == self.total_size\n\n        # subsample\n        indices = indices[self.rank:self.total_size:self.num_replicas]\n        assert len(indices) == self.num_samples\n        return iter(indices)\n\n\nclass DistributedPowerSampler(_DistributedSampler):\n    \"\"\"DistributedPowerSampler inheriting from\n    ``torch.utils.data.DistributedSampler``.\n\n    Samples are sampled with the probability that is proportional to the power\n    of label frequency (freq ^ power). The sampler only applies to single class\n    recognition dataset.\n\n    The default value of power is 1, which is equivalent to bootstrap sampling\n    from the entire dataset.\n    \"\"\"\n\n    def __init__(self, dataset, num_replicas=None, rank=None, power=1, seed=0):\n        super().__init__(dataset, num_replicas=num_replicas, rank=rank)\n        self.power = power\n        self.seed = seed if seed is not None else 0\n\n    def __iter__(self):\n        # deterministically shuffle based on epoch\n        g = torch.Generator()\n        g.manual_seed(self.epoch + self.seed)\n        video_infos_by_class = self.dataset.video_infos_by_class\n        num_classes = self.dataset.num_classes\n        # For simplicity, discontinuous labels are not permitted\n        assert set(video_infos_by_class) == set(range(num_classes))\n        counts = [len(video_infos_by_class[i]) for i in range(num_classes)]\n        counts = [cnt**self.power for cnt in counts]\n\n        indices = torch.multinomial(\n            torch.Tensor(counts),\n            self.total_size,\n            replacement=True,\n            generator=g)\n        indices = indices.data.numpy().tolist()\n        assert len(indices) == self.total_size\n\n        indices = indices[self.rank:self.total_size:self.num_replicas]\n        assert len(indices) == self.num_samples\n\n        return iter(indices)\n", "path": "mmaction/datasets/samplers/distributed_sampler.py"}]}