We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
extensions.ParameterStatistics cannot work with default parameter in GPU mode
`extensions.ParameterStatistics` raise error in GPU mode at `numpy.count_nonzero` or `numpy.percentile` at https://github.com/chainer/chainer/blob/master/chainer/training/extensions/parameter_statistics.py#L106

The type of `link.param` is cupy.ndarray but these functions cannot take this type.
Other functions (like numpy.mean) use the instance method (like hoge.mean).

--- 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/training/extensions/parameter_statistics.py`
Content:
```
1 import numpy
2 import six
3 
4 from chainer import reporter
5 from chainer.training import extension
6 from chainer.training import trigger as trigger_module
7 
8 
9 class ParameterStatistics(extension.Extension):
10     """Trainer extension to report parameter statistics.
11 
12     Statistics are collected and reported for a given :class:`~chainer.Link`
13     or an iterable of :class:`~chainer.Link`\\ s. If a link contains child
14     links, the statistics are reported separately for each child.
15 
16     Any function that takes a one-dimensional :class:`numpy.ndarray` or a
17     :class:`cupy.ndarray` and outputs a single or multiple real numbers can be
18     registered to handle the collection of statistics, e.g.
19     :meth:`numpy.ndarray.mean`.
20 
21     The keys of reported statistics follow the convention of link name
22     followed by parameter name, attribute name and function name, e.g.
23     ``VGG16Layers/conv1_1/W/data/mean``. They are prepended with an optional
24     prefix and appended with integer indices if the statistics generating
25     function return multiple values.
26 
27     Args:
28         links (~chainer.Link or iterable of ~chainer.Link): Link(s) containing
29             the parameters to observe. The link is expected to have a ``name``
30             attribute which is used as a part of the report key.
31         statistics (dict): Dictionary with function name to function mappings.
32             The name is a string and is used as a part of the report key. The
33             function is responsible for generating the statistics.
34         report_params (bool): If ``True``, report statistics for parameter
35             values such as weights and biases.
36         report_grads (bool): If ``True``, report statistics for parameter
37             gradients.
38         prefix (str): Optional prefix to prepend to the report keys.
39         trigger: Trigger that decides when to aggregate the results and report
40             the values.
41     """
42     default_name = 'parameter_statistics'
43     priority = extension.PRIORITY_WRITER
44 
45     # prefix ends with a '/' and param_name is preceded by a '/'
46     report_key_template = ('{prefix}{link_name}{param_name}/{attr_name}/'
47                            '{function_name}')
48 
49     default_statistics = {
50         'mean': numpy.mean,
51         'std': numpy.std,
52         'min': numpy.min,
53         'max': numpy.max,
54         'zeros': lambda x: numpy.count_nonzero(x == 0),
55         'percentile': lambda x: numpy.percentile(x, (0.13, 2.28, 15.87,
56                                                      50, 84.13, 97.72,
57                                                      99.87))
58     }
59 
60     def __init__(self, links, statistics=default_statistics,
61                  report_params=True, report_grads=True, prefix=None,
62                  trigger=(1, 'epoch')):
63 
64         if not isinstance(links, (list, tuple)):
65             links = links,
66         self._links = links
67 
68         self._statistics = statistics
69 
70         attrs = []
71         if report_params:
72             attrs.append('data')
73         if report_grads:
74             attrs.append('grad')
75         self._attrs = attrs
76 
77         self._prefix = prefix
78         self._trigger = trigger_module.get_trigger(trigger)
79         self._summary = reporter.DictSummary()
80 
81     def __call__(self, trainer):
82         """Execute the statistics extension.
83 
84         Collect statistics for the current state of parameters.
85 
86         Note that this method will merely update its statistic summary, unless
87         the internal trigger is fired. If the trigger is fired, the summary
88         will also be reported and then reset for the next accumulation.
89 
90         Args:
91             trainer (~chainer.training.Trainer): Associated trainer that
92                 invoked this extension.
93         """
94         statistics = {}
95 
96         for link in self._links:
97             link_name = getattr(link, 'name', 'None')
98             for param_name, param in link.namedparams():
99                 for attr_name in self._attrs:
100                     for function_name, function in \
101                             six.iteritems(self._statistics):
102                         # Get parameters as a flattend one-dimensional array
103                         # since the statistics function should make no
104                         # assumption about the axes
105                         params = getattr(param, attr_name).ravel()
106                         value = function(params)
107                         key = self.report_key_template.format(
108                             prefix=self._prefix + '/' if self._prefix else '',
109                             link_name=link_name,
110                             param_name=param_name,
111                             attr_name=attr_name,
112                             function_name=function_name
113                         )
114                         if hasattr(value, '__iter__'):
115                             # Append integer indices to the keys if the
116                             # statistic function return multiple values
117                             statistics.update({'{}/{}'.format(key, i): v for
118                                                i, v in enumerate(value)})
119                         else:
120                             statistics[key] = value
121 
122         self._summary.add(statistics)
123 
124         if self._trigger(trainer):
125             reporter.report(self._summary.compute_mean())
126             self._summary = reporter.DictSummary()  # Clear summary
127 
128     def register_statistics(self, name, function):
129         """Register a function to compute a certain statistic.
130 
131         The registered function will be called each time the extension runs and
132         the results will be included in the report.
133 
134         Args:
135             name (str): Name of the statistic.
136             function: Function to generate the statistic. Any function that
137                 takes a one-dimensional :class:`numpy.ndarray` or a
138                 :class:`cupy.ndarray` and outputs a single or multiple real
139                 numbers is allowed.
140         """
141         self._statistics[name] = function
142
```
--- 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/training/extensions/parameter_statistics.py b/chainer/training/extensions/parameter_statistics.py
--- a/chainer/training/extensions/parameter_statistics.py
+++ b/chainer/training/extensions/parameter_statistics.py
@@ -1,6 +1,8 @@
 import numpy
 import six
 
+import chainer
+from chainer.backends import cuda
 from chainer import reporter
 from chainer.training import extension
 from chainer.training import trigger as trigger_module
@@ -38,6 +40,10 @@
         prefix (str): Optional prefix to prepend to the report keys.
         trigger: Trigger that decides when to aggregate the results and report
             the values.
+        skip_nan_params (bool): If ``True``, statistics are not computed for
+            parameters including NaNs and a single NaN value is immediately
+            reported instead. Otherwise, this extension will simply try to
+            compute the statistics without performing any checks for NaNs.
     """
     default_name = 'parameter_statistics'
     priority = extension.PRIORITY_WRITER
@@ -47,24 +53,25 @@
                            '{function_name}')
 
     default_statistics = {
-        'mean': numpy.mean,
-        'std': numpy.std,
-        'min': numpy.min,
-        'max': numpy.max,
-        'zeros': lambda x: numpy.count_nonzero(x == 0),
-        'percentile': lambda x: numpy.percentile(x, (0.13, 2.28, 15.87,
-                                                     50, 84.13, 97.72,
-                                                     99.87))
+        'mean': lambda x: cuda.get_array_module(x).mean(x),
+        'std': lambda x: cuda.get_array_module(x).std(x),
+        'min': lambda x: cuda.get_array_module(x).min(x),
+        'max': lambda x: cuda.get_array_module(x).max(x),
+        'zeros': lambda x: cuda.get_array_module(x).count_nonzero(x == 0),
+        'percentile': lambda x: cuda.get_array_module(x).percentile(
+            x, (0.13, 2.28, 15.87, 50, 84.13, 97.72, 99.87))
     }
 
     def __init__(self, links, statistics=default_statistics,
                  report_params=True, report_grads=True, prefix=None,
-                 trigger=(1, 'epoch')):
+                 trigger=(1, 'epoch'), skip_nan_params=False):
 
         if not isinstance(links, (list, tuple)):
             links = links,
         self._links = links
 
+        if statistics is None:
+            statistics = {}
         self._statistics = statistics
 
         attrs = []
@@ -77,6 +84,7 @@
         self._prefix = prefix
         self._trigger = trigger_module.get_trigger(trigger)
         self._summary = reporter.DictSummary()
+        self._skip_nan_params = skip_nan_params
 
     def __call__(self, trainer):
         """Execute the statistics extension.
@@ -103,7 +111,12 @@
                         # since the statistics function should make no
                         # assumption about the axes
                         params = getattr(param, attr_name).ravel()
-                        value = function(params)
+                        if (self._skip_nan_params
+                            and (cuda.get_array_module(params).isnan(params)
+                                 .any())):
+                            value = numpy.nan
+                        else:
+                            value = function(params)
                         key = self.report_key_template.format(
                             prefix=self._prefix + '/' if self._prefix else '',
                             link_name=link_name,
@@ -111,7 +124,8 @@
                             attr_name=attr_name,
                             function_name=function_name
                         )
-                        if hasattr(value, '__iter__'):
+                        if (isinstance(value, chainer.get_array_types())
+                                and value.size > 1):
                             # Append integer indices to the keys if the
                             # statistic function return multiple values
                             statistics.update({'{}/{}'.format(key, i): v for

{"golden_diff": "diff --git a/chainer/training/extensions/parameter_statistics.py b/chainer/training/extensions/parameter_statistics.py\n--- a/chainer/training/extensions/parameter_statistics.py\n+++ b/chainer/training/extensions/parameter_statistics.py\n@@ -1,6 +1,8 @@\n import numpy\n import six\n \n+import chainer\n+from chainer.backends import cuda\n from chainer import reporter\n from chainer.training import extension\n from chainer.training import trigger as trigger_module\n@@ -38,6 +40,10 @@\n         prefix (str): Optional prefix to prepend to the report keys.\n         trigger: Trigger that decides when to aggregate the results and report\n             the values.\n+        skip_nan_params (bool): If ``True``, statistics are not computed for\n+            parameters including NaNs and a single NaN value is immediately\n+            reported instead. Otherwise, this extension will simply try to\n+            compute the statistics without performing any checks for NaNs.\n     \"\"\"\n     default_name = 'parameter_statistics'\n     priority = extension.PRIORITY_WRITER\n@@ -47,24 +53,25 @@\n                            '{function_name}')\n \n     default_statistics = {\n-        'mean': numpy.mean,\n-        'std': numpy.std,\n-        'min': numpy.min,\n-        'max': numpy.max,\n-        'zeros': lambda x: numpy.count_nonzero(x == 0),\n-        'percentile': lambda x: numpy.percentile(x, (0.13, 2.28, 15.87,\n-                                                     50, 84.13, 97.72,\n-                                                     99.87))\n+        'mean': lambda x: cuda.get_array_module(x).mean(x),\n+        'std': lambda x: cuda.get_array_module(x).std(x),\n+        'min': lambda x: cuda.get_array_module(x).min(x),\n+        'max': lambda x: cuda.get_array_module(x).max(x),\n+        'zeros': lambda x: cuda.get_array_module(x).count_nonzero(x == 0),\n+        'percentile': lambda x: cuda.get_array_module(x).percentile(\n+            x, (0.13, 2.28, 15.87, 50, 84.13, 97.72, 99.87))\n     }\n \n     def __init__(self, links, statistics=default_statistics,\n                  report_params=True, report_grads=True, prefix=None,\n-                 trigger=(1, 'epoch')):\n+                 trigger=(1, 'epoch'), skip_nan_params=False):\n \n         if not isinstance(links, (list, tuple)):\n             links = links,\n         self._links = links\n \n+        if statistics is None:\n+            statistics = {}\n         self._statistics = statistics\n \n         attrs = []\n@@ -77,6 +84,7 @@\n         self._prefix = prefix\n         self._trigger = trigger_module.get_trigger(trigger)\n         self._summary = reporter.DictSummary()\n+        self._skip_nan_params = skip_nan_params\n \n     def __call__(self, trainer):\n         \"\"\"Execute the statistics extension.\n@@ -103,7 +111,12 @@\n                         # since the statistics function should make no\n                         # assumption about the axes\n                         params = getattr(param, attr_name).ravel()\n-                        value = function(params)\n+                        if (self._skip_nan_params\n+                            and (cuda.get_array_module(params).isnan(params)\n+                                 .any())):\n+                            value = numpy.nan\n+                        else:\n+                            value = function(params)\n                         key = self.report_key_template.format(\n                             prefix=self._prefix + '/' if self._prefix else '',\n                             link_name=link_name,\n@@ -111,7 +124,8 @@\n                             attr_name=attr_name,\n                             function_name=function_name\n                         )\n-                        if hasattr(value, '__iter__'):\n+                        if (isinstance(value, chainer.get_array_types())\n+                                and value.size > 1):\n                             # Append integer indices to the keys if the\n                             # statistic function return multiple values\n                             statistics.update({'{}/{}'.format(key, i): v for\n", "issue": "extensions.ParameterStatistics cannot work with default parameter in GPU mode\n`extensions.ParameterStatistics` raise error in GPU mode at `numpy.count_nonzero` or `numpy.percentile` at https://github.com/chainer/chainer/blob/master/chainer/training/extensions/parameter_statistics.py#L106\r\n\r\nThe type of `link.param` is cupy.ndarray but these functions cannot take this type.\r\nOther functions (like numpy.mean) use the instance method (like hoge.mean).\n", "before_files": [{"content": "import numpy\nimport six\n\nfrom chainer import reporter\nfrom chainer.training import extension\nfrom chainer.training import trigger as trigger_module\n\n\nclass ParameterStatistics(extension.Extension):\n    \"\"\"Trainer extension to report parameter statistics.\n\n    Statistics are collected and reported for a given :class:`~chainer.Link`\n    or an iterable of :class:`~chainer.Link`\\\\ s. If a link contains child\n    links, the statistics are reported separately for each child.\n\n    Any function that takes a one-dimensional :class:`numpy.ndarray` or a\n    :class:`cupy.ndarray` and outputs a single or multiple real numbers can be\n    registered to handle the collection of statistics, e.g.\n    :meth:`numpy.ndarray.mean`.\n\n    The keys of reported statistics follow the convention of link name\n    followed by parameter name, attribute name and function name, e.g.\n    ``VGG16Layers/conv1_1/W/data/mean``. They are prepended with an optional\n    prefix and appended with integer indices if the statistics generating\n    function return multiple values.\n\n    Args:\n        links (~chainer.Link or iterable of ~chainer.Link): Link(s) containing\n            the parameters to observe. The link is expected to have a ``name``\n            attribute which is used as a part of the report key.\n        statistics (dict): Dictionary with function name to function mappings.\n            The name is a string and is used as a part of the report key. The\n            function is responsible for generating the statistics.\n        report_params (bool): If ``True``, report statistics for parameter\n            values such as weights and biases.\n        report_grads (bool): If ``True``, report statistics for parameter\n            gradients.\n        prefix (str): Optional prefix to prepend to the report keys.\n        trigger: Trigger that decides when to aggregate the results and report\n            the values.\n    \"\"\"\n    default_name = 'parameter_statistics'\n    priority = extension.PRIORITY_WRITER\n\n    # prefix ends with a '/' and param_name is preceded by a '/'\n    report_key_template = ('{prefix}{link_name}{param_name}/{attr_name}/'\n                           '{function_name}')\n\n    default_statistics = {\n        'mean': numpy.mean,\n        'std': numpy.std,\n        'min': numpy.min,\n        'max': numpy.max,\n        'zeros': lambda x: numpy.count_nonzero(x == 0),\n        'percentile': lambda x: numpy.percentile(x, (0.13, 2.28, 15.87,\n                                                     50, 84.13, 97.72,\n                                                     99.87))\n    }\n\n    def __init__(self, links, statistics=default_statistics,\n                 report_params=True, report_grads=True, prefix=None,\n                 trigger=(1, 'epoch')):\n\n        if not isinstance(links, (list, tuple)):\n            links = links,\n        self._links = links\n\n        self._statistics = statistics\n\n        attrs = []\n        if report_params:\n            attrs.append('data')\n        if report_grads:\n            attrs.append('grad')\n        self._attrs = attrs\n\n        self._prefix = prefix\n        self._trigger = trigger_module.get_trigger(trigger)\n        self._summary = reporter.DictSummary()\n\n    def __call__(self, trainer):\n        \"\"\"Execute the statistics extension.\n\n        Collect statistics for the current state of parameters.\n\n        Note that this method will merely update its statistic summary, unless\n        the internal trigger is fired. If the trigger is fired, the summary\n        will also be reported and then reset for the next accumulation.\n\n        Args:\n            trainer (~chainer.training.Trainer): Associated trainer that\n                invoked this extension.\n        \"\"\"\n        statistics = {}\n\n        for link in self._links:\n            link_name = getattr(link, 'name', 'None')\n            for param_name, param in link.namedparams():\n                for attr_name in self._attrs:\n                    for function_name, function in \\\n                            six.iteritems(self._statistics):\n                        # Get parameters as a flattend one-dimensional array\n                        # since the statistics function should make no\n                        # assumption about the axes\n                        params = getattr(param, attr_name).ravel()\n                        value = function(params)\n                        key = self.report_key_template.format(\n                            prefix=self._prefix + '/' if self._prefix else '',\n                            link_name=link_name,\n                            param_name=param_name,\n                            attr_name=attr_name,\n                            function_name=function_name\n                        )\n                        if hasattr(value, '__iter__'):\n                            # Append integer indices to the keys if the\n                            # statistic function return multiple values\n                            statistics.update({'{}/{}'.format(key, i): v for\n                                               i, v in enumerate(value)})\n                        else:\n                            statistics[key] = value\n\n        self._summary.add(statistics)\n\n        if self._trigger(trainer):\n            reporter.report(self._summary.compute_mean())\n            self._summary = reporter.DictSummary()  # Clear summary\n\n    def register_statistics(self, name, function):\n        \"\"\"Register a function to compute a certain statistic.\n\n        The registered function will be called each time the extension runs and\n        the results will be included in the report.\n\n        Args:\n            name (str): Name of the statistic.\n            function: Function to generate the statistic. Any function that\n                takes a one-dimensional :class:`numpy.ndarray` or a\n                :class:`cupy.ndarray` and outputs a single or multiple real\n                numbers is allowed.\n        \"\"\"\n        self._statistics[name] = function\n", "path": "chainer/training/extensions/parameter_statistics.py"}], "after_files": [{"content": "import numpy\nimport six\n\nimport chainer\nfrom chainer.backends import cuda\nfrom chainer import reporter\nfrom chainer.training import extension\nfrom chainer.training import trigger as trigger_module\n\n\nclass ParameterStatistics(extension.Extension):\n    \"\"\"Trainer extension to report parameter statistics.\n\n    Statistics are collected and reported for a given :class:`~chainer.Link`\n    or an iterable of :class:`~chainer.Link`\\\\ s. If a link contains child\n    links, the statistics are reported separately for each child.\n\n    Any function that takes a one-dimensional :class:`numpy.ndarray` or a\n    :class:`cupy.ndarray` and outputs a single or multiple real numbers can be\n    registered to handle the collection of statistics, e.g.\n    :meth:`numpy.ndarray.mean`.\n\n    The keys of reported statistics follow the convention of link name\n    followed by parameter name, attribute name and function name, e.g.\n    ``VGG16Layers/conv1_1/W/data/mean``. They are prepended with an optional\n    prefix and appended with integer indices if the statistics generating\n    function return multiple values.\n\n    Args:\n        links (~chainer.Link or iterable of ~chainer.Link): Link(s) containing\n            the parameters to observe. The link is expected to have a ``name``\n            attribute which is used as a part of the report key.\n        statistics (dict): Dictionary with function name to function mappings.\n            The name is a string and is used as a part of the report key. The\n            function is responsible for generating the statistics.\n        report_params (bool): If ``True``, report statistics for parameter\n            values such as weights and biases.\n        report_grads (bool): If ``True``, report statistics for parameter\n            gradients.\n        prefix (str): Optional prefix to prepend to the report keys.\n        trigger: Trigger that decides when to aggregate the results and report\n            the values.\n        skip_nan_params (bool): If ``True``, statistics are not computed for\n            parameters including NaNs and a single NaN value is immediately\n            reported instead. Otherwise, this extension will simply try to\n            compute the statistics without performing any checks for NaNs.\n    \"\"\"\n    default_name = 'parameter_statistics'\n    priority = extension.PRIORITY_WRITER\n\n    # prefix ends with a '/' and param_name is preceded by a '/'\n    report_key_template = ('{prefix}{link_name}{param_name}/{attr_name}/'\n                           '{function_name}')\n\n    default_statistics = {\n        'mean': lambda x: cuda.get_array_module(x).mean(x),\n        'std': lambda x: cuda.get_array_module(x).std(x),\n        'min': lambda x: cuda.get_array_module(x).min(x),\n        'max': lambda x: cuda.get_array_module(x).max(x),\n        'zeros': lambda x: cuda.get_array_module(x).count_nonzero(x == 0),\n        'percentile': lambda x: cuda.get_array_module(x).percentile(\n            x, (0.13, 2.28, 15.87, 50, 84.13, 97.72, 99.87))\n    }\n\n    def __init__(self, links, statistics=default_statistics,\n                 report_params=True, report_grads=True, prefix=None,\n                 trigger=(1, 'epoch'), skip_nan_params=False):\n\n        if not isinstance(links, (list, tuple)):\n            links = links,\n        self._links = links\n\n        if statistics is None:\n            statistics = {}\n        self._statistics = statistics\n\n        attrs = []\n        if report_params:\n            attrs.append('data')\n        if report_grads:\n            attrs.append('grad')\n        self._attrs = attrs\n\n        self._prefix = prefix\n        self._trigger = trigger_module.get_trigger(trigger)\n        self._summary = reporter.DictSummary()\n        self._skip_nan_params = skip_nan_params\n\n    def __call__(self, trainer):\n        \"\"\"Execute the statistics extension.\n\n        Collect statistics for the current state of parameters.\n\n        Note that this method will merely update its statistic summary, unless\n        the internal trigger is fired. If the trigger is fired, the summary\n        will also be reported and then reset for the next accumulation.\n\n        Args:\n            trainer (~chainer.training.Trainer): Associated trainer that\n                invoked this extension.\n        \"\"\"\n        statistics = {}\n\n        for link in self._links:\n            link_name = getattr(link, 'name', 'None')\n            for param_name, param in link.namedparams():\n                for attr_name in self._attrs:\n                    for function_name, function in \\\n                            six.iteritems(self._statistics):\n                        # Get parameters as a flattend one-dimensional array\n                        # since the statistics function should make no\n                        # assumption about the axes\n                        params = getattr(param, attr_name).ravel()\n                        if (self._skip_nan_params\n                            and (cuda.get_array_module(params).isnan(params)\n                                 .any())):\n                            value = numpy.nan\n                        else:\n                            value = function(params)\n                        key = self.report_key_template.format(\n                            prefix=self._prefix + '/' if self._prefix else '',\n                            link_name=link_name,\n                            param_name=param_name,\n                            attr_name=attr_name,\n                            function_name=function_name\n                        )\n                        if (isinstance(value, chainer.get_array_types())\n                                and value.size > 1):\n                            # Append integer indices to the keys if the\n                            # statistic function return multiple values\n                            statistics.update({'{}/{}'.format(key, i): v for\n                                               i, v in enumerate(value)})\n                        else:\n                            statistics[key] = value\n\n        self._summary.add(statistics)\n\n        if self._trigger(trainer):\n            reporter.report(self._summary.compute_mean())\n            self._summary = reporter.DictSummary()  # Clear summary\n\n    def register_statistics(self, name, function):\n        \"\"\"Register a function to compute a certain statistic.\n\n        The registered function will be called each time the extension runs and\n        the results will be included in the report.\n\n        Args:\n            name (str): Name of the statistic.\n            function: Function to generate the statistic. Any function that\n                takes a one-dimensional :class:`numpy.ndarray` or a\n                :class:`cupy.ndarray` and outputs a single or multiple real\n                numbers is allowed.\n        \"\"\"\n        self._statistics[name] = function\n", "path": "chainer/training/extensions/parameter_statistics.py"}]}