We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Unintuitive behavior of Iterator when sort is False
Currently, the following line is executed regardless of `sort` value.
https://github.com/pytorch/text/blob/2980f1bc39ba6af332c5c2783da8bee109796d4c/torchtext/data/iterator.py#L162

It could result in a counter-intuitive behavior when `sort is False`, since one would probably expect that the order of data is kept intact when `sort` is `False`.

I think this should be executed only when `sort` is `True`.
Is it by design, or a bug?

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

{"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@@ -63,19 +63,28 @@\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+        sort_within_batch: Whether to sort (in descending order according to\n+            self.sort_key) within each batch. If None, defaults to self.sort.\n+            If self.sort is True and this is False, the batch is left in the\n+            original (ascending) sorted order.\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+                 repeat=None, shuffle=None, sort=None,\n+                 sort_within_batch=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_within_batch is None:\n+            self.sort_within_batch = self.sort\n+        else:\n+            self.sort_within_batch = sort_within_batch\n         if sort_key is None:\n             self.sort_key = dataset.sort_key\n         else:\n@@ -157,9 +166,14 @@\n                     continue\n                 self.iterations += 1\n                 self._iterations_this_epoch += 1\n-                # NOTE: `rnn.pack_padded_sequence` requires that a minibatch be sorted by\n-                # decreasing order, which requires reversing relative to typical sort keys\n-                minibatch.reverse()\n+                if self.sort_within_batch:\n+                    # NOTE: `rnn.pack_padded_sequence` requires that a minibatch\n+                    # be sorted by decreasing order, which requires reversing\n+                    # relative to typical sort keys\n+                    if self.sort:\n+                        minibatch.reverse()\n+                    else:\n+                        minibatch.sort(key=self.sort_key, reverse=True)\n                 yield Batch(minibatch, self.dataset, self.device,\n                             self.train)\n             if not self.repeat:\n", "issue": "Unintuitive behavior of Iterator when sort is False\nCurrently, the following line is executed regardless of `sort` value.\r\nhttps://github.com/pytorch/text/blob/2980f1bc39ba6af332c5c2783da8bee109796d4c/torchtext/data/iterator.py#L162\r\n\r\nIt could result in a counter-intuitive behavior when `sort is False`, since one would probably expect that the order of data is kept intact when `sort` is `False`.\r\n\r\nI think this should be executed only when `sort` is `True`.\r\nIs it by design, or a bug?\n", "before_files": [{"content": "from __future__ import division\n\nimport 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                # NOTE: `rnn.pack_padded_sequence` requires that a minibatch be sorted by\n                # decreasing order, which requires reversing relative to typical sort keys\n                minibatch.reverse()\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] * int(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": "from __future__ import division\n\nimport 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        sort_within_batch: Whether to sort (in descending order according to\n            self.sort_key) within each batch. If None, defaults to self.sort.\n            If self.sort is True and this is False, the batch is left in the\n            original (ascending) sorted order.\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                 sort_within_batch=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_within_batch is None:\n            self.sort_within_batch = self.sort\n        else:\n            self.sort_within_batch = sort_within_batch\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                if self.sort_within_batch:\n                    # NOTE: `rnn.pack_padded_sequence` requires that a minibatch\n                    # be sorted by decreasing order, which requires reversing\n                    # relative to typical sort keys\n                    if self.sort:\n                        minibatch.reverse()\n                    else:\n                        minibatch.sort(key=self.sort_key, reverse=True)\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] * int(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"}]}