We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Consistency with sorting: `sort=True`
**Problem:**
```
    train_iter, dev_iter, test_iter = data.BucketIterator.splits(
        (train, dev, test),
        batch_sizes=(32, 256, 256),
        sort_key=lambda x: len(x.input),
        sort=True,
        device=-1)  # Use CPU
```

If `sort=True` and `train=True`, then the `train_iter` batches are shuffled. This behavior is unexpected.

**Cause:**
Because by default `self.shuffle=True` is `train=True`. Then https://github.com/pytorch/text/blob/master/torchtext/data/iterator.py#L113 `shuffle` overrides `sort`.

**Possible Solution:**
`sort=True` should override `shuffle=None and train=True`.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `torchtext/data/iterator.py`
Content:
```
1 import math
2 import random
3 from contextlib import contextmanager
4 from copy import deepcopy
5 
6 from .batch import Batch
7 from .dataset import Dataset
8 
9 
10 class RandomShuffler(object):
11     """Use random functions while keeping track of the random state to make it
12     reproducible and deterministic."""
13 
14     def __init__(self, random_state=None):
15         self._random_state = random_state
16         if self._random_state is None:
17             self._random_state = random.getstate()
18 
19     @contextmanager
20     def use_internal_state(self):
21         """Use a specific RNG state."""
22         old_state = random.getstate()
23         random.setstate(self._random_state)
24         yield
25         self._random_state = random.getstate()
26         random.setstate(old_state)
27 
28     @property
29     def random_state(self):
30         return deepcopy(self._random_state)
31 
32     @random_state.setter
33     def random_state(self, s):
34         self._random_state = s
35 
36     def __call__(self, data):
37         """Shuffle and return a new list."""
38         with self.use_internal_state():
39             return random.sample(data, len(data))
40 
41 
42 class Iterator(object):
43     """Defines an iterator that loads batches of data from a Dataset.
44 
45     Attributes:
46         dataset: The Dataset object to load Examples from.
47         batch_size: Batch size.
48         batch_size_fn: Function of three arguments (new example to add, current
49             count of examples in the batch, and current effective batch size)
50             that returns the new effective batch size resulting from adding
51             that example to a batch. This is useful for dynamic batching, where
52             this function would add to the current effective batch size the
53             number of tokens in the new example.
54         sort_key: A key to use for sorting examples in order to batch together
55             examples with similar lengths and minimize padding. The sort_key
56             provided to the Iterator constructor overrides the sort_key
57             attribute of the Dataset, or defers to it if None.
58         train: Whether the iterator represents a train set.
59         repeat: Whether to repeat the iterator for multiple epochs.
60         shuffle: Whether to shuffle examples between epochs.
61         sort: Whether to sort examples according to self.sort_key.
62             Note that repeat, shuffle, and sort default to train, train, and
63             (not train).
64         device: Device to create batches on. Use -1 for CPU and None for the
65             currently active GPU device.
66     """
67 
68     def __init__(self, dataset, batch_size, sort_key=None, device=None,
69                  batch_size_fn=lambda new, count, sofar: count, train=True,
70                  repeat=None, shuffle=None, sort=None):
71         self.batch_size, self.train, self.dataset = batch_size, train, dataset
72         self.batch_size_fn = batch_size_fn
73         self.iterations = 0
74         self.repeat = train if repeat is None else repeat
75         self.shuffle = train if shuffle is None else shuffle
76         self.sort = not train if sort is None else sort
77         if sort_key is None:
78             self.sort_key = dataset.sort_key
79         else:
80             self.sort_key = sort_key
81         self.device = device
82 
83         self.random_shuffler = RandomShuffler()
84 
85         # For state loading/saving only
86         self._iterations_this_epoch = 0
87         self._random_state_this_epoch = None
88         self._restored_from_state = False
89 
90     @classmethod
91     def splits(cls, datasets, batch_sizes=None, **kwargs):
92         """Create Iterator objects for multiple splits of a dataset.
93 
94         Arguments:
95             datasets: Tuple of Dataset objects corresponding to the splits. The
96                 first such object should be the train set.
97             batch_sizes: Tuple of batch sizes to use for the different splits,
98                 or None to use the same batch_size for all splits.
99             Remaining keyword arguments: Passed to the constructor of the
100                 iterator class being used.
101         """
102         if batch_sizes is None:
103             batch_sizes = [kwargs.pop('batch_size')] * len(datasets)
104         ret = []
105         for i in range(len(datasets)):
106             train = i == 0
107             ret.append(cls(
108                 datasets[i], batch_size=batch_sizes[i], train=train, **kwargs))
109         return tuple(ret)
110 
111     def data(self):
112         """Return the examples in the dataset in order, sorted, or shuffled."""
113         if self.shuffle:
114             xs = [self.dataset[i] for i in self.random_shuffler(range(len(self.dataset)))]
115         elif self.sort:
116             xs = sorted(self.dataset, key=self.sort_key)
117         else:
118             xs = self.dataset
119         return xs
120 
121     def init_epoch(self):
122         """Set up the batch generator for a new epoch."""
123 
124         if self._restored_from_state:
125             self.random_shuffler.random_state = self._random_state_this_epoch
126         else:
127             self._random_state_this_epoch = self.random_shuffler.random_state
128 
129         self.create_batches()
130 
131         if self._restored_from_state:
132             self._restored_from_state = False
133         else:
134             self._iterations_this_epoch = 0
135 
136         if not self.repeat:
137             self.iterations = 0
138 
139     def create_batches(self):
140         self.batches = batch(self.data(), self.batch_size, self.batch_size_fn)
141 
142     @property
143     def epoch(self):
144         return self.iterations / len(self)
145 
146     def __len__(self):
147         return math.ceil(len(self.dataset) / self.batch_size)
148 
149     def __iter__(self):
150         while True:
151             self.init_epoch()
152             for idx, minibatch in enumerate(self.batches):
153                 # fast-forward if loaded from state
154                 if self._iterations_this_epoch > idx:
155                     continue
156                 self.iterations += 1
157                 self._iterations_this_epoch += 1
158                 yield Batch(minibatch, self.dataset, self.device,
159                             self.train)
160             if not self.repeat:
161                 raise StopIteration
162 
163     def state_dict(self):
164         return {
165             "iterations": self.iterations,
166             "iterations_this_epoch": self._iterations_this_epoch,
167             "random_state_this_epoch": self._random_state_this_epoch}
168 
169     def load_state_dict(self, state_dict):
170         self.iterations = state_dict["iterations"]
171         self._iterations_this_epoch = state_dict["iterations_this_epoch"]
172         self._random_state_this_epoch = state_dict["random_state_this_epoch"]
173         self._restored_from_state = True
174 
175 
176 class BPTTIterator(Iterator):
177     """Defines an iterator for language modeling tasks that use BPTT.
178 
179     Provides contiguous streams of examples together with targets that are
180     one timestep further forward, for language modeling training with
181     backpropagation through time (BPTT). Expects a Dataset with a single
182     example and a single field called 'text' and produces Batches with text and
183     target attributes.
184 
185     Attributes:
186         dataset: The Dataset object to load Examples from.
187         batch_size: Batch size.
188         bptt_len: Length of sequences for backpropagation through time.
189         sort_key: A key to use for sorting examples in order to batch together
190             examples with similar lengths and minimize padding. The sort_key
191             provided to the Iterator constructor overrides the sort_key
192             attribute of the Dataset, or defers to it if None.
193         train: Whether the iterator represents a train set.
194         repeat: Whether to repeat the iterator for multiple epochs.
195         shuffle: Whether to shuffle examples between epochs.
196         sort: Whether to sort examples according to self.sort_key.
197             Note that repeat, shuffle, and sort default to train, train, and
198             (not train).
199         device: Device to create batches on. Use -1 for CPU and None for the
200             currently active GPU device.
201     """
202 
203     def __init__(self, dataset, batch_size, bptt_len, **kwargs):
204         self.bptt_len = bptt_len
205         super(BPTTIterator, self).__init__(dataset, batch_size, **kwargs)
206 
207     def __len__(self):
208         return math.ceil(len(self.dataset[0].text) /
209                          (self.batch_size * self.bptt_len))
210 
211     def __iter__(self):
212         text = self.dataset[0].text
213         TEXT = self.dataset.fields['text']
214         TEXT.eos_token = None
215         text = text + ([TEXT.pad_token] * (math.ceil(len(text) / self.batch_size) *
216                                            self.batch_size - len(text)))
217         data = TEXT.numericalize(
218             [text], device=self.device, train=self.train)
219         data = data.view(self.batch_size, -1).t().contiguous()
220         dataset = Dataset(examples=self.dataset.examples, fields=[
221             ('text', TEXT), ('target', TEXT)])
222         while True:
223             for i in range(0, len(self) * self.bptt_len, self.bptt_len):
224                 seq_len = min(self.bptt_len, len(data) - 1 - i)
225                 yield Batch.fromvars(
226                     dataset, self.batch_size, train=self.train,
227                     text=data[i:i + seq_len],
228                     target=data[i + 1:i + 1 + seq_len])
229             if not self.repeat:
230                 raise StopIteration
231 
232 
233 class BucketIterator(Iterator):
234     """Defines an iterator that batches examples of similar lengths together.
235 
236     Minimizes amount of padding needed while producing freshly shuffled
237     batches for each new epoch. See pool for the bucketing procedure used.
238     """
239 
240     def create_batches(self):
241         if self.sort:
242             self.batches = batch(self.data(), self.batch_size,
243                                  self.batch_size_fn)
244         else:
245             self.batches = pool(self.data(), self.batch_size,
246                                 self.sort_key, self.batch_size_fn,
247                                 random_shuffler=self.random_shuffler)
248 
249 
250 def batch(data, batch_size, batch_size_fn=lambda new, count, sofar: count):
251     """Yield elements from data in chunks of batch_size."""
252     minibatch, size_so_far = [], 0
253     for ex in data:
254         minibatch.append(ex)
255         size_so_far = batch_size_fn(ex, len(minibatch), size_so_far)
256         if size_so_far == batch_size:
257             yield minibatch
258             minibatch, size_so_far = [], 0
259         elif size_so_far > batch_size:
260             yield minibatch[:-1]
261             minibatch, size_so_far = minibatch[:-1], batch_size_fn(ex, 1, 0)
262     if minibatch:
263         yield minibatch
264 
265 
266 def pool(data, batch_size, key, batch_size_fn=lambda new, count, sofar: count,
267          random_shuffler=None):
268     """Sort within buckets, then batch, then shuffle batches.
269 
270     Partitions data into chunks of size 100*batch_size, sorts examples within
271     each chunk using sort_key, then batch these examples and shuffle the
272     batches.
273     """
274     if random_shuffler is None:
275         random_shuffler = random.shuffle
276     for p in batch(data, batch_size * 100, batch_size_fn):
277         p_batch = batch(sorted(p, key=key), batch_size, batch_size_fn)
278         for b in random_shuffler(list(p_batch)):
279             yield b
280
```
--- 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/torchtext/data/iterator.py b/torchtext/data/iterator.py
--- a/torchtext/data/iterator.py
+++ b/torchtext/data/iterator.py
@@ -110,10 +110,10 @@
 
     def data(self):
         """Return the examples in the dataset in order, sorted, or shuffled."""
-        if self.shuffle:
-            xs = [self.dataset[i] for i in self.random_shuffler(range(len(self.dataset)))]
-        elif self.sort:
+        if self.sort:
             xs = sorted(self.dataset, key=self.sort_key)
+        elif self.shuffle:
+            xs = [self.dataset[i] for i in self.random_shuffler(range(len(self.dataset)))]
         else:
             xs = self.dataset
         return xs

{"golden_diff": "diff --git a/torchtext/data/iterator.py b/torchtext/data/iterator.py\n--- a/torchtext/data/iterator.py\n+++ b/torchtext/data/iterator.py\n@@ -110,10 +110,10 @@\n \n     def data(self):\n         \"\"\"Return the examples in the dataset in order, sorted, or shuffled.\"\"\"\n-        if self.shuffle:\n-            xs = [self.dataset[i] for i in self.random_shuffler(range(len(self.dataset)))]\n-        elif self.sort:\n+        if self.sort:\n             xs = sorted(self.dataset, key=self.sort_key)\n+        elif self.shuffle:\n+            xs = [self.dataset[i] for i in self.random_shuffler(range(len(self.dataset)))]\n         else:\n             xs = self.dataset\n         return xs\n", "issue": "Consistency with sorting: `sort=True`\n**Problem:**\r\n```\r\n    train_iter, dev_iter, test_iter = data.BucketIterator.splits(\r\n        (train, dev, test),\r\n        batch_sizes=(32, 256, 256),\r\n        sort_key=lambda x: len(x.input),\r\n        sort=True,\r\n        device=-1)  # Use CPU\r\n```\r\n\r\nIf `sort=True` and `train=True`, then the `train_iter` batches are shuffled. This behavior is unexpected.\r\n\r\n**Cause:**\r\nBecause by default `self.shuffle=True` is `train=True`. Then https://github.com/pytorch/text/blob/master/torchtext/data/iterator.py#L113 `shuffle` overrides `sort`.\r\n\r\n**Possible Solution:**\r\n`sort=True` should override `shuffle=None and train=True`.\n", "before_files": [{"content": "import math\nimport random\nfrom contextlib import contextmanager\nfrom copy import deepcopy\n\nfrom .batch import Batch\nfrom .dataset import Dataset\n\n\nclass RandomShuffler(object):\n    \"\"\"Use random functions while keeping track of the random state to make it\n    reproducible and deterministic.\"\"\"\n\n    def __init__(self, random_state=None):\n        self._random_state = random_state\n        if self._random_state is None:\n            self._random_state = random.getstate()\n\n    @contextmanager\n    def use_internal_state(self):\n        \"\"\"Use a specific RNG state.\"\"\"\n        old_state = random.getstate()\n        random.setstate(self._random_state)\n        yield\n        self._random_state = random.getstate()\n        random.setstate(old_state)\n\n    @property\n    def random_state(self):\n        return deepcopy(self._random_state)\n\n    @random_state.setter\n    def random_state(self, s):\n        self._random_state = s\n\n    def __call__(self, data):\n        \"\"\"Shuffle and return a new list.\"\"\"\n        with self.use_internal_state():\n            return random.sample(data, len(data))\n\n\nclass Iterator(object):\n    \"\"\"Defines an iterator that loads batches of data from a Dataset.\n\n    Attributes:\n        dataset: The Dataset object to load Examples from.\n        batch_size: Batch size.\n        batch_size_fn: Function of three arguments (new example to add, current\n            count of examples in the batch, and current effective batch size)\n            that returns the new effective batch size resulting from adding\n            that example to a batch. This is useful for dynamic batching, where\n            this function would add to the current effective batch size the\n            number of tokens in the new example.\n        sort_key: A key to use for sorting examples in order to batch together\n            examples with similar lengths and minimize padding. The sort_key\n            provided to the Iterator constructor overrides the sort_key\n            attribute of the Dataset, or defers to it if None.\n        train: Whether the iterator represents a train set.\n        repeat: Whether to repeat the iterator for multiple epochs.\n        shuffle: Whether to shuffle examples between epochs.\n        sort: Whether to sort examples according to self.sort_key.\n            Note that repeat, shuffle, and sort default to train, train, and\n            (not train).\n        device: Device to create batches on. Use -1 for CPU and None for the\n            currently active GPU device.\n    \"\"\"\n\n    def __init__(self, dataset, batch_size, sort_key=None, device=None,\n                 batch_size_fn=lambda new, count, sofar: count, train=True,\n                 repeat=None, shuffle=None, sort=None):\n        self.batch_size, self.train, self.dataset = batch_size, train, dataset\n        self.batch_size_fn = batch_size_fn\n        self.iterations = 0\n        self.repeat = train if repeat is None else repeat\n        self.shuffle = train if shuffle is None else shuffle\n        self.sort = not train if sort is None else sort\n        if sort_key is None:\n            self.sort_key = dataset.sort_key\n        else:\n            self.sort_key = sort_key\n        self.device = device\n\n        self.random_shuffler = RandomShuffler()\n\n        # For state loading/saving only\n        self._iterations_this_epoch = 0\n        self._random_state_this_epoch = None\n        self._restored_from_state = False\n\n    @classmethod\n    def splits(cls, datasets, batch_sizes=None, **kwargs):\n        \"\"\"Create Iterator objects for multiple splits of a dataset.\n\n        Arguments:\n            datasets: Tuple of Dataset objects corresponding to the splits. The\n                first such object should be the train set.\n            batch_sizes: Tuple of batch sizes to use for the different splits,\n                or None to use the same batch_size for all splits.\n            Remaining keyword arguments: Passed to the constructor of the\n                iterator class being used.\n        \"\"\"\n        if batch_sizes is None:\n            batch_sizes = [kwargs.pop('batch_size')] * len(datasets)\n        ret = []\n        for i in range(len(datasets)):\n            train = i == 0\n            ret.append(cls(\n                datasets[i], batch_size=batch_sizes[i], train=train, **kwargs))\n        return tuple(ret)\n\n    def data(self):\n        \"\"\"Return the examples in the dataset in order, sorted, or shuffled.\"\"\"\n        if self.shuffle:\n            xs = [self.dataset[i] for i in self.random_shuffler(range(len(self.dataset)))]\n        elif self.sort:\n            xs = sorted(self.dataset, key=self.sort_key)\n        else:\n            xs = self.dataset\n        return xs\n\n    def init_epoch(self):\n        \"\"\"Set up the batch generator for a new epoch.\"\"\"\n\n        if self._restored_from_state:\n            self.random_shuffler.random_state = self._random_state_this_epoch\n        else:\n            self._random_state_this_epoch = self.random_shuffler.random_state\n\n        self.create_batches()\n\n        if self._restored_from_state:\n            self._restored_from_state = False\n        else:\n            self._iterations_this_epoch = 0\n\n        if not self.repeat:\n            self.iterations = 0\n\n    def create_batches(self):\n        self.batches = batch(self.data(), self.batch_size, self.batch_size_fn)\n\n    @property\n    def epoch(self):\n        return self.iterations / len(self)\n\n    def __len__(self):\n        return math.ceil(len(self.dataset) / self.batch_size)\n\n    def __iter__(self):\n        while True:\n            self.init_epoch()\n            for idx, minibatch in enumerate(self.batches):\n                # fast-forward if loaded from state\n                if self._iterations_this_epoch > idx:\n                    continue\n                self.iterations += 1\n                self._iterations_this_epoch += 1\n                yield Batch(minibatch, self.dataset, self.device,\n                            self.train)\n            if not self.repeat:\n                raise StopIteration\n\n    def state_dict(self):\n        return {\n            \"iterations\": self.iterations,\n            \"iterations_this_epoch\": self._iterations_this_epoch,\n            \"random_state_this_epoch\": self._random_state_this_epoch}\n\n    def load_state_dict(self, state_dict):\n        self.iterations = state_dict[\"iterations\"]\n        self._iterations_this_epoch = state_dict[\"iterations_this_epoch\"]\n        self._random_state_this_epoch = state_dict[\"random_state_this_epoch\"]\n        self._restored_from_state = True\n\n\nclass BPTTIterator(Iterator):\n    \"\"\"Defines an iterator for language modeling tasks that use BPTT.\n\n    Provides contiguous streams of examples together with targets that are\n    one timestep further forward, for language modeling training with\n    backpropagation through time (BPTT). Expects a Dataset with a single\n    example and a single field called 'text' and produces Batches with text and\n    target attributes.\n\n    Attributes:\n        dataset: The Dataset object to load Examples from.\n        batch_size: Batch size.\n        bptt_len: Length of sequences for backpropagation through time.\n        sort_key: A key to use for sorting examples in order to batch together\n            examples with similar lengths and minimize padding. The sort_key\n            provided to the Iterator constructor overrides the sort_key\n            attribute of the Dataset, or defers to it if None.\n        train: Whether the iterator represents a train set.\n        repeat: Whether to repeat the iterator for multiple epochs.\n        shuffle: Whether to shuffle examples between epochs.\n        sort: Whether to sort examples according to self.sort_key.\n            Note that repeat, shuffle, and sort default to train, train, and\n            (not train).\n        device: Device to create batches on. Use -1 for CPU and None for the\n            currently active GPU device.\n    \"\"\"\n\n    def __init__(self, dataset, batch_size, bptt_len, **kwargs):\n        self.bptt_len = bptt_len\n        super(BPTTIterator, self).__init__(dataset, batch_size, **kwargs)\n\n    def __len__(self):\n        return math.ceil(len(self.dataset[0].text) /\n                         (self.batch_size * self.bptt_len))\n\n    def __iter__(self):\n        text = self.dataset[0].text\n        TEXT = self.dataset.fields['text']\n        TEXT.eos_token = None\n        text = text + ([TEXT.pad_token] * (math.ceil(len(text) / self.batch_size) *\n                                           self.batch_size - len(text)))\n        data = TEXT.numericalize(\n            [text], device=self.device, train=self.train)\n        data = data.view(self.batch_size, -1).t().contiguous()\n        dataset = Dataset(examples=self.dataset.examples, fields=[\n            ('text', TEXT), ('target', TEXT)])\n        while True:\n            for i in range(0, len(self) * self.bptt_len, self.bptt_len):\n                seq_len = min(self.bptt_len, len(data) - 1 - i)\n                yield Batch.fromvars(\n                    dataset, self.batch_size, train=self.train,\n                    text=data[i:i + seq_len],\n                    target=data[i + 1:i + 1 + seq_len])\n            if not self.repeat:\n                raise StopIteration\n\n\nclass BucketIterator(Iterator):\n    \"\"\"Defines an iterator that batches examples of similar lengths together.\n\n    Minimizes amount of padding needed while producing freshly shuffled\n    batches for each new epoch. See pool for the bucketing procedure used.\n    \"\"\"\n\n    def create_batches(self):\n        if self.sort:\n            self.batches = batch(self.data(), self.batch_size,\n                                 self.batch_size_fn)\n        else:\n            self.batches = pool(self.data(), self.batch_size,\n                                self.sort_key, self.batch_size_fn,\n                                random_shuffler=self.random_shuffler)\n\n\ndef batch(data, batch_size, batch_size_fn=lambda new, count, sofar: count):\n    \"\"\"Yield elements from data in chunks of batch_size.\"\"\"\n    minibatch, size_so_far = [], 0\n    for ex in data:\n        minibatch.append(ex)\n        size_so_far = batch_size_fn(ex, len(minibatch), size_so_far)\n        if size_so_far == batch_size:\n            yield minibatch\n            minibatch, size_so_far = [], 0\n        elif size_so_far > batch_size:\n            yield minibatch[:-1]\n            minibatch, size_so_far = minibatch[:-1], batch_size_fn(ex, 1, 0)\n    if minibatch:\n        yield minibatch\n\n\ndef pool(data, batch_size, key, batch_size_fn=lambda new, count, sofar: count,\n         random_shuffler=None):\n    \"\"\"Sort within buckets, then batch, then shuffle batches.\n\n    Partitions data into chunks of size 100*batch_size, sorts examples within\n    each chunk using sort_key, then batch these examples and shuffle the\n    batches.\n    \"\"\"\n    if random_shuffler is None:\n        random_shuffler = random.shuffle\n    for p in batch(data, batch_size * 100, batch_size_fn):\n        p_batch = batch(sorted(p, key=key), batch_size, batch_size_fn)\n        for b in random_shuffler(list(p_batch)):\n            yield b\n", "path": "torchtext/data/iterator.py"}], "after_files": [{"content": "import math\nimport random\nfrom contextlib import contextmanager\nfrom copy import deepcopy\n\nfrom .batch import Batch\nfrom .dataset import Dataset\n\n\nclass RandomShuffler(object):\n    \"\"\"Use random functions while keeping track of the random state to make it\n    reproducible and deterministic.\"\"\"\n\n    def __init__(self, random_state=None):\n        self._random_state = random_state\n        if self._random_state is None:\n            self._random_state = random.getstate()\n\n    @contextmanager\n    def use_internal_state(self):\n        \"\"\"Use a specific RNG state.\"\"\"\n        old_state = random.getstate()\n        random.setstate(self._random_state)\n        yield\n        self._random_state = random.getstate()\n        random.setstate(old_state)\n\n    @property\n    def random_state(self):\n        return deepcopy(self._random_state)\n\n    @random_state.setter\n    def random_state(self, s):\n        self._random_state = s\n\n    def __call__(self, data):\n        \"\"\"Shuffle and return a new list.\"\"\"\n        with self.use_internal_state():\n            return random.sample(data, len(data))\n\n\nclass Iterator(object):\n    \"\"\"Defines an iterator that loads batches of data from a Dataset.\n\n    Attributes:\n        dataset: The Dataset object to load Examples from.\n        batch_size: Batch size.\n        batch_size_fn: Function of three arguments (new example to add, current\n            count of examples in the batch, and current effective batch size)\n            that returns the new effective batch size resulting from adding\n            that example to a batch. This is useful for dynamic batching, where\n            this function would add to the current effective batch size the\n            number of tokens in the new example.\n        sort_key: A key to use for sorting examples in order to batch together\n            examples with similar lengths and minimize padding. The sort_key\n            provided to the Iterator constructor overrides the sort_key\n            attribute of the Dataset, or defers to it if None.\n        train: Whether the iterator represents a train set.\n        repeat: Whether to repeat the iterator for multiple epochs.\n        shuffle: Whether to shuffle examples between epochs.\n        sort: Whether to sort examples according to self.sort_key.\n            Note that repeat, shuffle, and sort default to train, train, and\n            (not train).\n        device: Device to create batches on. Use -1 for CPU and None for the\n            currently active GPU device.\n    \"\"\"\n\n    def __init__(self, dataset, batch_size, sort_key=None, device=None,\n                 batch_size_fn=lambda new, count, sofar: count, train=True,\n                 repeat=None, shuffle=None, sort=None):\n        self.batch_size, self.train, self.dataset = batch_size, train, dataset\n        self.batch_size_fn = batch_size_fn\n        self.iterations = 0\n        self.repeat = train if repeat is None else repeat\n        self.shuffle = train if shuffle is None else shuffle\n        self.sort = not train if sort is None else sort\n        if sort_key is None:\n            self.sort_key = dataset.sort_key\n        else:\n            self.sort_key = sort_key\n        self.device = device\n\n        self.random_shuffler = RandomShuffler()\n\n        # For state loading/saving only\n        self._iterations_this_epoch = 0\n        self._random_state_this_epoch = None\n        self._restored_from_state = False\n\n    @classmethod\n    def splits(cls, datasets, batch_sizes=None, **kwargs):\n        \"\"\"Create Iterator objects for multiple splits of a dataset.\n\n        Arguments:\n            datasets: Tuple of Dataset objects corresponding to the splits. The\n                first such object should be the train set.\n            batch_sizes: Tuple of batch sizes to use for the different splits,\n                or None to use the same batch_size for all splits.\n            Remaining keyword arguments: Passed to the constructor of the\n                iterator class being used.\n        \"\"\"\n        if batch_sizes is None:\n            batch_sizes = [kwargs.pop('batch_size')] * len(datasets)\n        ret = []\n        for i in range(len(datasets)):\n            train = i == 0\n            ret.append(cls(\n                datasets[i], batch_size=batch_sizes[i], train=train, **kwargs))\n        return tuple(ret)\n\n    def data(self):\n        \"\"\"Return the examples in the dataset in order, sorted, or shuffled.\"\"\"\n        if self.sort:\n            xs = sorted(self.dataset, key=self.sort_key)\n        elif self.shuffle:\n            xs = [self.dataset[i] for i in self.random_shuffler(range(len(self.dataset)))]\n        else:\n            xs = self.dataset\n        return xs\n\n    def init_epoch(self):\n        \"\"\"Set up the batch generator for a new epoch.\"\"\"\n\n        if self._restored_from_state:\n            self.random_shuffler.random_state = self._random_state_this_epoch\n        else:\n            self._random_state_this_epoch = self.random_shuffler.random_state\n\n        self.create_batches()\n\n        if self._restored_from_state:\n            self._restored_from_state = False\n        else:\n            self._iterations_this_epoch = 0\n\n        if not self.repeat:\n            self.iterations = 0\n\n    def create_batches(self):\n        self.batches = batch(self.data(), self.batch_size, self.batch_size_fn)\n\n    @property\n    def epoch(self):\n        return self.iterations / len(self)\n\n    def __len__(self):\n        return math.ceil(len(self.dataset) / self.batch_size)\n\n    def __iter__(self):\n        while True:\n            self.init_epoch()\n            for idx, minibatch in enumerate(self.batches):\n                # fast-forward if loaded from state\n                if self._iterations_this_epoch > idx:\n                    continue\n                self.iterations += 1\n                self._iterations_this_epoch += 1\n                yield Batch(minibatch, self.dataset, self.device,\n                            self.train)\n            if not self.repeat:\n                raise StopIteration\n\n    def state_dict(self):\n        return {\n            \"iterations\": self.iterations,\n            \"iterations_this_epoch\": self._iterations_this_epoch,\n            \"random_state_this_epoch\": self._random_state_this_epoch}\n\n    def load_state_dict(self, state_dict):\n        self.iterations = state_dict[\"iterations\"]\n        self._iterations_this_epoch = state_dict[\"iterations_this_epoch\"]\n        self._random_state_this_epoch = state_dict[\"random_state_this_epoch\"]\n        self._restored_from_state = True\n\n\nclass BPTTIterator(Iterator):\n    \"\"\"Defines an iterator for language modeling tasks that use BPTT.\n\n    Provides contiguous streams of examples together with targets that are\n    one timestep further forward, for language modeling training with\n    backpropagation through time (BPTT). Expects a Dataset with a single\n    example and a single field called 'text' and produces Batches with text and\n    target attributes.\n\n    Attributes:\n        dataset: The Dataset object to load Examples from.\n        batch_size: Batch size.\n        bptt_len: Length of sequences for backpropagation through time.\n        sort_key: A key to use for sorting examples in order to batch together\n            examples with similar lengths and minimize padding. The sort_key\n            provided to the Iterator constructor overrides the sort_key\n            attribute of the Dataset, or defers to it if None.\n        train: Whether the iterator represents a train set.\n        repeat: Whether to repeat the iterator for multiple epochs.\n        shuffle: Whether to shuffle examples between epochs.\n        sort: Whether to sort examples according to self.sort_key.\n            Note that repeat, shuffle, and sort default to train, train, and\n            (not train).\n        device: Device to create batches on. Use -1 for CPU and None for the\n            currently active GPU device.\n    \"\"\"\n\n    def __init__(self, dataset, batch_size, bptt_len, **kwargs):\n        self.bptt_len = bptt_len\n        super(BPTTIterator, self).__init__(dataset, batch_size, **kwargs)\n\n    def __len__(self):\n        return math.ceil(len(self.dataset[0].text) /\n                         (self.batch_size * self.bptt_len))\n\n    def __iter__(self):\n        text = self.dataset[0].text\n        TEXT = self.dataset.fields['text']\n        TEXT.eos_token = None\n        text = text + ([TEXT.pad_token] * (math.ceil(len(text) / self.batch_size) *\n                                           self.batch_size - len(text)))\n        data = TEXT.numericalize(\n            [text], device=self.device, train=self.train)\n        data = data.view(self.batch_size, -1).t().contiguous()\n        dataset = Dataset(examples=self.dataset.examples, fields=[\n            ('text', TEXT), ('target', TEXT)])\n        while True:\n            for i in range(0, len(self) * self.bptt_len, self.bptt_len):\n                seq_len = min(self.bptt_len, len(data) - 1 - i)\n                yield Batch.fromvars(\n                    dataset, self.batch_size, train=self.train,\n                    text=data[i:i + seq_len],\n                    target=data[i + 1:i + 1 + seq_len])\n            if not self.repeat:\n                raise StopIteration\n\n\nclass BucketIterator(Iterator):\n    \"\"\"Defines an iterator that batches examples of similar lengths together.\n\n    Minimizes amount of padding needed while producing freshly shuffled\n    batches for each new epoch. See pool for the bucketing procedure used.\n    \"\"\"\n\n    def create_batches(self):\n        if self.sort:\n            self.batches = batch(self.data(), self.batch_size,\n                                 self.batch_size_fn)\n        else:\n            self.batches = pool(self.data(), self.batch_size,\n                                self.sort_key, self.batch_size_fn,\n                                random_shuffler=self.random_shuffler)\n\n\ndef batch(data, batch_size, batch_size_fn=lambda new, count, sofar: count):\n    \"\"\"Yield elements from data in chunks of batch_size.\"\"\"\n    minibatch, size_so_far = [], 0\n    for ex in data:\n        minibatch.append(ex)\n        size_so_far = batch_size_fn(ex, len(minibatch), size_so_far)\n        if size_so_far == batch_size:\n            yield minibatch\n            minibatch, size_so_far = [], 0\n        elif size_so_far > batch_size:\n            yield minibatch[:-1]\n            minibatch, size_so_far = minibatch[:-1], batch_size_fn(ex, 1, 0)\n    if minibatch:\n        yield minibatch\n\n\ndef pool(data, batch_size, key, batch_size_fn=lambda new, count, sofar: count,\n         random_shuffler=None):\n    \"\"\"Sort within buckets, then batch, then shuffle batches.\n\n    Partitions data into chunks of size 100*batch_size, sorts examples within\n    each chunk using sort_key, then batch these examples and shuffle the\n    batches.\n    \"\"\"\n    if random_shuffler is None:\n        random_shuffler = random.shuffle\n    for p in batch(data, batch_size * 100, batch_size_fn):\n        p_batch = batch(sorted(p, key=key), batch_size, batch_size_fn)\n        for b in random_shuffler(list(p_batch)):\n            yield b\n", "path": "torchtext/data/iterator.py"}]}