We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
SerialIterator's shuffle does not work under certain batch sizes
When we give `shuffle=True` to `SerialIterator`, re-shuffling after an epoch is skipped if `len(dataset)` is divisible by `batch_size`.

![image](https://cloud.githubusercontent.com/assets/469803/17083083/f55bbc30-51ce-11e6-86e7-66853674b898.png)

https://github.com/pfnet/chainer/blob/master/chainer/iterators/serial_iterator.py#L65

Variable `_order` is never re-shuffled if `rest` > 0 (i.e., `len(dataset)` is divisible by `batch_size`).

(If it is okay, I'm interested in working on this issue at the development meeting tomorrow.)


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `chainer/iterators/serial_iterator.py`
Content:
```
1 from __future__ import division
2 
3 import numpy
4 
5 from chainer.dataset import iterator
6 
7 
8 class SerialIterator(iterator.Iterator):
9 
10     """Dataset iterator that serially reads the examples.
11 
12     This is a simple implementation of :class:`~chainer.dataset.Iterator`
13     that just visits each example in either the order of indexes or a shuffled
14     order.
15 
16     To avoid unintentional performance degradation, the ``shuffle`` option is
17     set to ``True`` by default. For validation, it is better to set it to
18     ``False`` when the underlying dataset supports fast slicing. If the
19     order of examples has an important meaning and the updater depends on the
20     original order, this option should be set to ``False``.
21 
22     Args:
23         dataset: Dataset to iterate.
24         batch_size (int): Number of examples within each batch.
25         repeat (bool): If ``True``, it infinitely loops over the dataset.
26             Otherwise, it stops iteration at the end of the first epoch.
27         shuffle (bool): If ``True``, the order of examples is shuffled at the
28             beginning of each epoch. Otherwise, examples are extracted in the
29             order of indexes.
30 
31     """
32     def __init__(self, dataset, batch_size, repeat=True, shuffle=True):
33         self.dataset = dataset
34         self.batch_size = batch_size
35         self._repeat = repeat
36         if shuffle:
37             self._order = numpy.random.permutation(len(dataset))
38         else:
39             self._order = None
40 
41         self.current_position = 0
42         self.epoch = 0
43         self.is_new_epoch = False
44 
45     def __next__(self):
46         if not self._repeat and self.epoch > 0:
47             raise StopIteration
48 
49         i = self.current_position
50         i_end = i + self.batch_size
51         N = len(self.dataset)
52 
53         if self._order is None:
54             batch = self.dataset[i:i_end]
55         else:
56             batch = [self.dataset[index] for index in self._order[i:i_end]]
57 
58         if i_end >= N:
59             if self._repeat:
60                 rest = i_end - N
61                 if rest > 0:
62                     if self._order is None:
63                         batch += list(self.dataset[:rest])
64                     else:
65                         numpy.random.shuffle(self._order)
66                         batch += [self.dataset[index]
67                                   for index in self._order[:rest]]
68                 self.current_position = rest
69             else:
70                 self.current_position = N
71 
72             self.epoch += 1
73             self.is_new_epoch = True
74         else:
75             self.is_new_epoch = False
76             self.current_position = i_end
77 
78         return batch
79 
80     next = __next__
81 
82     @property
83     def epoch_detail(self):
84         return self.epoch + self.current_position / len(self.dataset)
85 
86     def serialize(self, serializer):
87         self.current_position = serializer('current_position',
88                                            self.current_position)
89         self.epoch = serializer('epoch', self.epoch)
90         self.is_new_epoch = serializer('is_new_epoch', self.is_new_epoch)
91         if self._order is not None:
92             serializer('_order', self._order)
93
```
--- 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/chainer/iterators/serial_iterator.py b/chainer/iterators/serial_iterator.py
--- a/chainer/iterators/serial_iterator.py
+++ b/chainer/iterators/serial_iterator.py
@@ -58,11 +58,12 @@
         if i_end >= N:
             if self._repeat:
                 rest = i_end - N
+                if self._order is not None:
+                    numpy.random.shuffle(self._order)
                 if rest > 0:
                     if self._order is None:
                         batch += list(self.dataset[:rest])
                     else:
-                        numpy.random.shuffle(self._order)
                         batch += [self.dataset[index]
                                   for index in self._order[:rest]]
                 self.current_position = rest

{"golden_diff": "diff --git a/chainer/iterators/serial_iterator.py b/chainer/iterators/serial_iterator.py\n--- a/chainer/iterators/serial_iterator.py\n+++ b/chainer/iterators/serial_iterator.py\n@@ -58,11 +58,12 @@\n         if i_end >= N:\n             if self._repeat:\n                 rest = i_end - N\n+                if self._order is not None:\n+                    numpy.random.shuffle(self._order)\n                 if rest > 0:\n                     if self._order is None:\n                         batch += list(self.dataset[:rest])\n                     else:\n-                        numpy.random.shuffle(self._order)\n                         batch += [self.dataset[index]\n                                   for index in self._order[:rest]]\n                 self.current_position = rest\n", "issue": "SerialIterator's shuffle does not work under certain batch sizes\nWhen we give `shuffle=True` to `SerialIterator`, re-shuffling after an epoch is skipped if `len(dataset)` is divisible by `batch_size`.\n\n![image](https://cloud.githubusercontent.com/assets/469803/17083083/f55bbc30-51ce-11e6-86e7-66853674b898.png)\n\nhttps://github.com/pfnet/chainer/blob/master/chainer/iterators/serial_iterator.py#L65\n\nVariable `_order` is never re-shuffled if `rest` > 0 (i.e., `len(dataset)` is divisible by `batch_size`).\n\n(If it is okay, I'm interested in working on this issue at the development meeting tomorrow.)\n\n", "before_files": [{"content": "from __future__ import division\n\nimport numpy\n\nfrom chainer.dataset import iterator\n\n\nclass SerialIterator(iterator.Iterator):\n\n    \"\"\"Dataset iterator that serially reads the examples.\n\n    This is a simple implementation of :class:`~chainer.dataset.Iterator`\n    that just visits each example in either the order of indexes or a shuffled\n    order.\n\n    To avoid unintentional performance degradation, the ``shuffle`` option is\n    set to ``True`` by default. For validation, it is better to set it to\n    ``False`` when the underlying dataset supports fast slicing. If the\n    order of examples has an important meaning and the updater depends on the\n    original order, this option should be set to ``False``.\n\n    Args:\n        dataset: Dataset to iterate.\n        batch_size (int): Number of examples within each batch.\n        repeat (bool): If ``True``, it infinitely loops over the dataset.\n            Otherwise, it stops iteration at the end of the first epoch.\n        shuffle (bool): If ``True``, the order of examples is shuffled at the\n            beginning of each epoch. Otherwise, examples are extracted in the\n            order of indexes.\n\n    \"\"\"\n    def __init__(self, dataset, batch_size, repeat=True, shuffle=True):\n        self.dataset = dataset\n        self.batch_size = batch_size\n        self._repeat = repeat\n        if shuffle:\n            self._order = numpy.random.permutation(len(dataset))\n        else:\n            self._order = None\n\n        self.current_position = 0\n        self.epoch = 0\n        self.is_new_epoch = False\n\n    def __next__(self):\n        if not self._repeat and self.epoch > 0:\n            raise StopIteration\n\n        i = self.current_position\n        i_end = i + self.batch_size\n        N = len(self.dataset)\n\n        if self._order is None:\n            batch = self.dataset[i:i_end]\n        else:\n            batch = [self.dataset[index] for index in self._order[i:i_end]]\n\n        if i_end >= N:\n            if self._repeat:\n                rest = i_end - N\n                if rest > 0:\n                    if self._order is None:\n                        batch += list(self.dataset[:rest])\n                    else:\n                        numpy.random.shuffle(self._order)\n                        batch += [self.dataset[index]\n                                  for index in self._order[:rest]]\n                self.current_position = rest\n            else:\n                self.current_position = N\n\n            self.epoch += 1\n            self.is_new_epoch = True\n        else:\n            self.is_new_epoch = False\n            self.current_position = i_end\n\n        return batch\n\n    next = __next__\n\n    @property\n    def epoch_detail(self):\n        return self.epoch + self.current_position / len(self.dataset)\n\n    def serialize(self, serializer):\n        self.current_position = serializer('current_position',\n                                           self.current_position)\n        self.epoch = serializer('epoch', self.epoch)\n        self.is_new_epoch = serializer('is_new_epoch', self.is_new_epoch)\n        if self._order is not None:\n            serializer('_order', self._order)\n", "path": "chainer/iterators/serial_iterator.py"}], "after_files": [{"content": "from __future__ import division\n\nimport numpy\n\nfrom chainer.dataset import iterator\n\n\nclass SerialIterator(iterator.Iterator):\n\n    \"\"\"Dataset iterator that serially reads the examples.\n\n    This is a simple implementation of :class:`~chainer.dataset.Iterator`\n    that just visits each example in either the order of indexes or a shuffled\n    order.\n\n    To avoid unintentional performance degradation, the ``shuffle`` option is\n    set to ``True`` by default. For validation, it is better to set it to\n    ``False`` when the underlying dataset supports fast slicing. If the\n    order of examples has an important meaning and the updater depends on the\n    original order, this option should be set to ``False``.\n\n    Args:\n        dataset: Dataset to iterate.\n        batch_size (int): Number of examples within each batch.\n        repeat (bool): If ``True``, it infinitely loops over the dataset.\n            Otherwise, it stops iteration at the end of the first epoch.\n        shuffle (bool): If ``True``, the order of examples is shuffled at the\n            beginning of each epoch. Otherwise, examples are extracted in the\n            order of indexes.\n\n    \"\"\"\n    def __init__(self, dataset, batch_size, repeat=True, shuffle=True):\n        self.dataset = dataset\n        self.batch_size = batch_size\n        self._repeat = repeat\n        if shuffle:\n            self._order = numpy.random.permutation(len(dataset))\n        else:\n            self._order = None\n\n        self.current_position = 0\n        self.epoch = 0\n        self.is_new_epoch = False\n\n    def __next__(self):\n        if not self._repeat and self.epoch > 0:\n            raise StopIteration\n\n        i = self.current_position\n        i_end = i + self.batch_size\n        N = len(self.dataset)\n\n        if self._order is None:\n            batch = self.dataset[i:i_end]\n        else:\n            batch = [self.dataset[index] for index in self._order[i:i_end]]\n\n        if i_end >= N:\n            if self._repeat:\n                rest = i_end - N\n                if self._order is not None:\n                    numpy.random.shuffle(self._order)\n                if rest > 0:\n                    if self._order is None:\n                        batch += list(self.dataset[:rest])\n                    else:\n                        batch += [self.dataset[index]\n                                  for index in self._order[:rest]]\n                self.current_position = rest\n            else:\n                self.current_position = N\n\n            self.epoch += 1\n            self.is_new_epoch = True\n        else:\n            self.is_new_epoch = False\n            self.current_position = i_end\n\n        return batch\n\n    next = __next__\n\n    @property\n    def epoch_detail(self):\n        return self.epoch + self.current_position / len(self.dataset)\n\n    def serialize(self, serializer):\n        self.current_position = serializer('current_position',\n                                           self.current_position)\n        self.epoch = serializer('epoch', self.epoch)\n        self.is_new_epoch = serializer('is_new_epoch', self.is_new_epoch)\n        if self._order is not None:\n            serializer('_order', self._order)\n", "path": "chainer/iterators/serial_iterator.py"}]}