prompt: 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: `mmpose/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
  ```
  
  Path: `mmpose/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 mmcv.utils.parrots_wrapper import _get_dataloader
  10 
  11 from .dataset_wrappers import RepeatDataset
  12 from .registry import DATASETS
  13 from .samplers import 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, 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                      samples_per_gpu,
  45                      workers_per_gpu,
  46                      num_gpus=1,
  47                      dist=True,
  48                      shuffle=True,
  49                      seed=None,
  50                      drop_last=True,
  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 (Dataset): A PyTorch dataset.
  60         samples_per_gpu (int): Number of training samples on each GPU, i.e.,
  61             batch size of each GPU.
  62         workers_per_gpu (int): How many subprocesses to use for data loading
  63             for each GPU.
  64         num_gpus (int): Number of GPUs. Only used in non-distributed training.
  65         dist (bool): Distributed training/test or not. Default: True.
  66         shuffle (bool): Whether to shuffle the data at every epoch.
  67             Default: True.
  68         drop_last (bool): Whether to drop the last incomplete batch in epoch.
  69             Default: True
  70         pin_memory (bool): Whether to use pin_memory in DataLoader.
  71             Default: True
  72         kwargs: any keyword argument to be used to initialize DataLoader
  73 
  74     Returns:
  75         DataLoader: A PyTorch dataloader.
  76     """
  77     rank, world_size = get_dist_info()
  78     if dist:
  79         sampler = DistributedSampler(
  80             dataset, world_size, rank, shuffle=shuffle)
  81         shuffle = False
  82         batch_size = samples_per_gpu
  83         num_workers = workers_per_gpu
  84     else:
  85         sampler = None
  86         batch_size = num_gpus * samples_per_gpu
  87         num_workers = num_gpus * workers_per_gpu
  88 
  89     init_fn = partial(
  90         worker_init_fn, num_workers=num_workers, rank=rank,
  91         seed=seed) if seed is not None else None
  92 
  93     _, DataLoader = _get_dataloader()
  94     data_loader = DataLoader(
  95         dataset,
  96         batch_size=batch_size,
  97         sampler=sampler,
  98         num_workers=num_workers,
  99         collate_fn=partial(collate, samples_per_gpu=samples_per_gpu),
  100         pin_memory=pin_memory,
  101         shuffle=shuffle,
  102         worker_init_fn=init_fn,
  103         drop_last=drop_last,
  104         **kwargs)
  105 
  106     return data_loader
  107 
  108 
  109 def worker_init_fn(worker_id, num_workers, rank, seed):
  110     """Init the random seed for various workers."""
  111     # The seed of each worker equals to
  112     # num_worker * rank + worker_id + user_seed
  113     worker_seed = num_workers * rank + worker_id + seed
  114     np.random.seed(worker_seed)
  115     random.seed(worker_seed)
  116
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/mmpose/datasets/builder.py b/mmpose/datasets/builder.py
  --- a/mmpose/datasets/builder.py
  +++ b/mmpose/datasets/builder.py
  @@ -77,7 +77,7 @@
       rank, world_size = get_dist_info()
       if dist:
           sampler = DistributedSampler(
  -            dataset, world_size, rank, shuffle=shuffle)
  +            dataset, world_size, rank, shuffle=shuffle, seed=seed)
           shuffle = False
           batch_size = samples_per_gpu
           num_workers = workers_per_gpu
  diff --git a/mmpose/datasets/samplers/distributed_sampler.py b/mmpose/datasets/samplers/distributed_sampler.py
  --- a/mmpose/datasets/samplers/distributed_sampler.py
  +++ b/mmpose/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()
  
verification_info: {"golden_diff": "diff --git a/mmpose/datasets/builder.py b/mmpose/datasets/builder.py\n--- a/mmpose/datasets/builder.py\n+++ b/mmpose/datasets/builder.py\n@@ -77,7 +77,7 @@\n     rank, world_size = get_dist_info()\n     if dist:\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 = samples_per_gpu\n         num_workers = workers_per_gpu\ndiff --git a/mmpose/datasets/samplers/distributed_sampler.py b/mmpose/datasets/samplers/distributed_sampler.py\n--- a/mmpose/datasets/samplers/distributed_sampler.py\n+++ b/mmpose/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", "issue": "Seed in sampler\nhttps://github.com/open-mmlab/mmdetection/pull/4665\n", "before_files": [{"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", "path": "mmpose/datasets/samplers/distributed_sampler.py"}, {"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 mmcv.utils.parrots_wrapper import _get_dataloader\n\nfrom .dataset_wrappers import RepeatDataset\nfrom .registry import DATASETS\nfrom .samplers import 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, 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                     samples_per_gpu,\n                     workers_per_gpu,\n                     num_gpus=1,\n                     dist=True,\n                     shuffle=True,\n                     seed=None,\n                     drop_last=True,\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 (Dataset): A PyTorch dataset.\n        samples_per_gpu (int): Number of training samples on each GPU, i.e.,\n            batch size of each GPU.\n        workers_per_gpu (int): How many subprocesses to use for data loading\n            for each GPU.\n        num_gpus (int): Number of GPUs. Only used in non-distributed training.\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        drop_last (bool): Whether to drop the last incomplete batch in epoch.\n            Default: True\n        pin_memory (bool): Whether to use pin_memory in DataLoader.\n            Default: True\n        kwargs: any keyword argument to be used to initialize DataLoader\n\n    Returns:\n        DataLoader: A PyTorch dataloader.\n    \"\"\"\n    rank, world_size = get_dist_info()\n    if dist:\n        sampler = DistributedSampler(\n            dataset, world_size, rank, shuffle=shuffle)\n        shuffle = False\n        batch_size = samples_per_gpu\n        num_workers = workers_per_gpu\n    else:\n        sampler = None\n        batch_size = num_gpus * samples_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    _, DataLoader = _get_dataloader()\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=samples_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": "mmpose/datasets/builder.py"}], "after_files": [{"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", "path": "mmpose/datasets/samplers/distributed_sampler.py"}, {"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 mmcv.utils.parrots_wrapper import _get_dataloader\n\nfrom .dataset_wrappers import RepeatDataset\nfrom .registry import DATASETS\nfrom .samplers import 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, 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                     samples_per_gpu,\n                     workers_per_gpu,\n                     num_gpus=1,\n                     dist=True,\n                     shuffle=True,\n                     seed=None,\n                     drop_last=True,\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 (Dataset): A PyTorch dataset.\n        samples_per_gpu (int): Number of training samples on each GPU, i.e.,\n            batch size of each GPU.\n        workers_per_gpu (int): How many subprocesses to use for data loading\n            for each GPU.\n        num_gpus (int): Number of GPUs. Only used in non-distributed training.\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        drop_last (bool): Whether to drop the last incomplete batch in epoch.\n            Default: True\n        pin_memory (bool): Whether to use pin_memory in DataLoader.\n            Default: True\n        kwargs: any keyword argument to be used to initialize DataLoader\n\n    Returns:\n        DataLoader: A PyTorch dataloader.\n    \"\"\"\n    rank, world_size = get_dist_info()\n    if dist:\n        sampler = DistributedSampler(\n            dataset, world_size, rank, shuffle=shuffle, seed=seed)\n        shuffle = False\n        batch_size = samples_per_gpu\n        num_workers = workers_per_gpu\n    else:\n        sampler = None\n        batch_size = num_gpus * samples_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    _, DataLoader = _get_dataloader()\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=samples_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": "mmpose/datasets/builder.py"}]}