We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Use "cpu" instead of None for representing device
I think using device value as `cpu` instead of `None` will make `Iterator` class compatible with PyTorch device types [1] i.e., "cpu" and "gpu". 

[1] https://pytorch.org/docs/stable/tensor_attributes.html 

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

{"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@@ -3,6 +3,7 @@\n \n import logging\n \n+import torch\n from .utils import RandomShuffler\n from .batch import Batch\n from .dataset import Dataset\n@@ -65,6 +66,12 @@\n                            + \" or passing a string as an argument. This behavior will be\"\n                            + \" deprecated soon and currently defaults to cpu.\")\n             device = None\n+\n+        if device is None:\n+            device = torch.device('cpu')\n+        elif isinstance(device, str):\n+            device = torch.device(device)\n+\n         self.device = device\n         self.random_shuffler = RandomShuffler()\n", "issue": "Use \"cpu\" instead of None for representing device\nI think using device value as `cpu` instead of `None` will make `Iterator` class compatible with PyTorch device types [1] i.e., \"cpu\" and \"gpu\". \r\n\r\n[1] https://pytorch.org/docs/stable/tensor_attributes.html \n", "before_files": [{"content": "import math\nimport random\n\nimport logging\n\nfrom .utils import RandomShuffler\nfrom .batch import Batch\nfrom .dataset import Dataset\n\nlogger = logging.getLogger(__name__)\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. Default: False.\n        shuffle: Whether to shuffle examples between epochs.\n        sort: Whether to sort examples according to self.sort_key.\n            Note that shuffle and sort default to train and (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 (str or `torch.device`): A string or instance of `torch.device`\n            specifying which device the Variables are going to be created on.\n            If left as default, the tensors will be created on cpu. Default: None.\n    \"\"\"\n\n    def __init__(self, dataset, batch_size, sort_key=None, device=None,\n                 batch_size_fn=None, train=True,\n                 repeat=False, 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 = repeat\n        self.shuffle = train if shuffle is None else shuffle\n        self.sort = not train if sort is None else sort\n\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\n        if isinstance(device, int):\n            logger.warning(\"The `device` argument should be set by using `torch.device`\"\n                           + \" or passing a string as an argument. This behavior will be\"\n                           + \" deprecated soon and currently defaults to cpu.\")\n            device = None\n        self.device = device\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 math.floor(self.iterations / len(self))\n\n    def __len__(self):\n        if self.batch_size_fn is not None:\n            raise NotImplementedError\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            if not self.repeat:\n                return\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. Default: False.\n        shuffle: Whether to shuffle examples between epochs.\n        sort: Whether to sort examples according to self.sort_key.\n            Note that shuffle and sort default to train and (not train).\n        device (str or torch.device): A string or instance of `torch.device`\n            specifying which device the Variables are going to be created on.\n            If left as default, the tensors will be created on cpu. Default: None.\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) / self.batch_size - 1)\n                         / 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)\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                self.iterations += 1\n                seq_len = min(self.bptt_len, len(data) - i - 1)\n                batch_text = data[i:i + seq_len]\n                batch_target = data[i + 1:i + 1 + seq_len]\n                if TEXT.batch_first:\n                    batch_text = batch_text.t().contiguous()\n                    batch_target = batch_target.t().contiguous()\n                yield Batch.fromvars(\n                    dataset, self.batch_size,\n                    text=batch_text,\n                    target=batch_target)\n            if not self.repeat:\n                return\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                                shuffle=self.shuffle,\n                                sort_within_batch=self.sort_within_batch)\n\n\ndef batch(data, batch_size, batch_size_fn=None):\n    \"\"\"Yield elements from data in chunks of batch_size.\"\"\"\n    if batch_size_fn is None:\n        def batch_size_fn(new, count, sofar):\n            return count\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, shuffle=False, sort_within_batch=False):\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            if sort_within_batch \\\n            else batch(p, batch_size, batch_size_fn)\n        if shuffle:\n            for b in random_shuffler(list(p_batch)):\n                yield b\n        else:\n            for b in list(p_batch):\n                yield b\n", "path": "torchtext/data/iterator.py"}], "after_files": [{"content": "import math\nimport random\n\nimport logging\n\nimport torch\nfrom .utils import RandomShuffler\nfrom .batch import Batch\nfrom .dataset import Dataset\n\nlogger = logging.getLogger(__name__)\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. Default: False.\n        shuffle: Whether to shuffle examples between epochs.\n        sort: Whether to sort examples according to self.sort_key.\n            Note that shuffle and sort default to train and (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 (str or `torch.device`): A string or instance of `torch.device`\n            specifying which device the Variables are going to be created on.\n            If left as default, the tensors will be created on cpu. Default: None.\n    \"\"\"\n\n    def __init__(self, dataset, batch_size, sort_key=None, device=None,\n                 batch_size_fn=None, train=True,\n                 repeat=False, 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 = repeat\n        self.shuffle = train if shuffle is None else shuffle\n        self.sort = not train if sort is None else sort\n\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\n        if isinstance(device, int):\n            logger.warning(\"The `device` argument should be set by using `torch.device`\"\n                           + \" or passing a string as an argument. This behavior will be\"\n                           + \" deprecated soon and currently defaults to cpu.\")\n            device = None\n\n        if device is None:\n            device = torch.device('cpu')\n        elif isinstance(device, str):\n            device = torch.device(device)\n\n        self.device = device\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 math.floor(self.iterations / len(self))\n\n    def __len__(self):\n        if self.batch_size_fn is not None:\n            raise NotImplementedError\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            if not self.repeat:\n                return\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. Default: False.\n        shuffle: Whether to shuffle examples between epochs.\n        sort: Whether to sort examples according to self.sort_key.\n            Note that shuffle and sort default to train and (not train).\n        device (str or torch.device): A string or instance of `torch.device`\n            specifying which device the Variables are going to be created on.\n            If left as default, the tensors will be created on cpu. Default: None.\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) / self.batch_size - 1)\n                         / 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)\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                self.iterations += 1\n                seq_len = min(self.bptt_len, len(data) - i - 1)\n                batch_text = data[i:i + seq_len]\n                batch_target = data[i + 1:i + 1 + seq_len]\n                if TEXT.batch_first:\n                    batch_text = batch_text.t().contiguous()\n                    batch_target = batch_target.t().contiguous()\n                yield Batch.fromvars(\n                    dataset, self.batch_size,\n                    text=batch_text,\n                    target=batch_target)\n            if not self.repeat:\n                return\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                                shuffle=self.shuffle,\n                                sort_within_batch=self.sort_within_batch)\n\n\ndef batch(data, batch_size, batch_size_fn=None):\n    \"\"\"Yield elements from data in chunks of batch_size.\"\"\"\n    if batch_size_fn is None:\n        def batch_size_fn(new, count, sofar):\n            return count\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, shuffle=False, sort_within_batch=False):\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            if sort_within_batch \\\n            else batch(p, batch_size, batch_size_fn)\n        if shuffle:\n            for b in random_shuffler(list(p_batch)):\n                yield b\n        else:\n            for b in list(p_batch):\n                yield b\n", "path": "torchtext/data/iterator.py"}]}