We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`chainer.backend.copyto` cannot copy chainerx array to cupy
* Code to reproduce
```python
import chainer
import numpy

for dst_device in ['@numpy', '@cupy:0', '@intel64']:
    for src_device in ['native', 'cuda:0']:
        print((dst_device, src_device))
        dst = chainer.get_device(dst_device).send(
            numpy.array([1, 2], numpy.float32))
        src = chainer.get_device(src_device).send(
            numpy.array([3, 4], numpy.float32))
        try:
            chainer.backend.copyto(dst, src)
        except Exception as e:
            print(repr(e))
        else:
            print('ok')
```

* Error messages, stack traces, or logs
```
('@numpy', 'native')
ok
('@numpy', 'cuda:0')
ok
('@cupy:0', 'native')
TypeError('object array cannot be set to float32 array')
('@cupy:0', 'cuda:0')
TypeError('object array cannot be set to float32 array')
('@intel64', 'native')
ok
('@intel64', 'cuda:0')
ok
```


--- 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/backend.py`
Content:
```
1 import numpy
2 import six
3 
4 import chainer
5 from chainer.backends import _chainerx
6 from chainer.backends import _cpu
7 from chainer.backends import cuda
8 from chainer.backends import intel64
9 import chainerx
10 
11 # Aliases
12 from chainer._backend import Device
13 from chainer.backends._chainerx import ChainerxDevice
14 from chainer.backends._chainerx import from_chx  # NOQA
15 from chainer.backends._chainerx import to_chx  # NOQA
16 from chainer.backends._cpu import CpuDevice
17 from chainer.backends.cuda import GpuDevice
18 from chainer.backends.intel64 import Intel64Device
19 from chainer import types  # NOQA
20 
21 
22 def _contains_nan(x):
23     """Returns whether the input array has NaN values.
24 
25     Args:
26         x (numpy.ndarray or cupy.ndarray): Array to be checked.
27 
28     Returns:
29         bool: True if the input has NaN values.
30 
31     """
32     if x.dtype.kind in ('f', 'c'):
33         device = get_device_from_array(x)
34         with chainer.using_device(device):
35             return device.xp.isnan(x).any()
36     else:
37         return False
38 
39 
40 def copyto(dst, src):
41     """Copies the elements of an ndarray to those of another one.
42 
43     This function can copy the CPU/GPU arrays to the destination arrays on
44     another device.
45 
46     Args:
47         dst (`numpy.ndarray`, `cupy.ndarray` or `ideep4py.mdarray`):
48             Destination array.
49         src (`numpy.ndarray`, `cupy.ndarray` or `ideep4py.mdarray`):
50             Source array.
51 
52     """
53     if isinstance(dst, chainerx.ndarray):
54         dst[...] = _chainerx._array_to_chainerx(src, dst.device)
55     elif isinstance(dst, numpy.ndarray):
56         numpy.copyto(dst, _cpu._to_cpu(src))
57     elif isinstance(dst, intel64.mdarray):
58         intel64.ideep.basic_copyto(
59             dst, _cpu._to_cpu(src))
60     elif isinstance(dst, cuda.ndarray):
61         if isinstance(src, chainer.get_cpu_array_types()):
62             src = numpy.asarray(src)
63             if dst.flags.c_contiguous or dst.flags.f_contiguous:
64                 dst.set(src)
65             else:
66                 cuda.cupy.copyto(dst, cuda.to_gpu(src, device=dst.device))
67         elif isinstance(src, cuda.ndarray):
68             cuda.cupy.copyto(dst, src)
69         else:
70             raise TypeError('cannot copy from non-array object of type {}'
71                             .format(type(src)))
72     else:
73         raise TypeError('cannot copy to non-array object of type {}'.format(
74             type(dst)))
75 
76 
77 def _guess_device_from_array_module(xp):
78     """Returns a plausible device from array module
79 
80     .. warning::
81 
82         There can be multiple devices for a module
83 
84     """
85     if xp is cuda.cupy:
86         return cuda.GpuDevice(cuda.Device())
87     elif xp is chainerx:
88         return _chainerx.ChainerxDevice(chainerx.get_default_device())
89     else:
90         # Cannot detect intel64, because xp of intel64 is numpy.
91         return _cpu.CpuDevice()
92 
93 
94 def get_device(device_spec):
95     # type: (types.DeviceSpec) -> Device
96     """Returns a device object.
97 
98     Args:
99         device_spec (object): Device specifier.
100             If a :class:`chainer.backend.Device` instance is given, it is
101             returned intact. Otherwise the following values are supported:
102 
103             * ChainerX devices
104 
105               * A string representing a device.
106                 (ex. ``'native:0'``, ``'native'``)
107               * A :class:`chainerx.Device` object.
108 
109             * CuPy
110 
111               * A string starts with ``'@cupy:'``.
112                 (ex. ``'@cupy:0'``)
113               * A :class:`cupy.cuda.Device` object.
114 
115             * NumPy
116 
117               * The string ``'@numpy'``.
118 
119             * NumPy with Intel Architecture
120 
121               * The string ``'@intel64'``.
122     """
123     if isinstance(device_spec, Device):
124         return device_spec
125 
126     if isinstance(device_spec, cuda._integer_types):
127         return _get_device_cupy_or_numpy(device_spec)
128 
129     if chainerx.is_available() and isinstance(device_spec, chainerx.Device):
130         return _chainerx.ChainerxDevice(device_spec)
131 
132     if cuda.available and isinstance(device_spec, cuda.Device):
133         return cuda.GpuDevice(device_spec)
134 
135     if isinstance(device_spec, six.string_types):
136         # '-1', '0', '1', ...
137         try:
138             int_device_spec = int(device_spec)
139         except ValueError:
140             pass
141         else:
142             return _get_device_cupy_or_numpy(int_device_spec)
143 
144         if device_spec.startswith('@'):
145             # '@module:...'
146             mod_name, colon, precise_spec = device_spec[1:].partition(':')
147             if mod_name == 'numpy':
148                 if not colon:
149                     return _cpu.CpuDevice()
150             elif mod_name == 'cupy':
151                 if colon:
152                     return cuda.GpuDevice.from_device_id(int(precise_spec))
153             elif mod_name == 'intel64':
154                 if not colon:
155                     return intel64.Intel64Device()
156             raise ValueError(
157                 'Device specifiers starting with \'@\' must be followed by'
158                 ' a module name and depending on the module, module specific'
159                 ' precise device specifiers. Actual: {}'.format(device_spec))
160         else:
161             # String device specifier without '@' prefix is assumed to be a
162             # ChainerX device.
163             if not chainerx.is_available():
164                 raise RuntimeError(
165                     'Tried to parse ChainerX device specifier \'{}\', '
166                     'but ChainerX is not available. '
167                     'Note that device specifiers without \'@\' prefix are '
168                     'assumed to be ChainerX device '
169                     'specifiers.'.format(device_spec))
170             return _chainerx.ChainerxDevice(chainerx.get_device(device_spec))
171 
172     raise TypeError(
173         'Device specifier must be a backend.Device, cuda.Device,'
174         ' chainerx.Device, integer or a string. Actual: {}'.format(
175             type(device_spec)))
176 
177 
178 def _get_device_cupy_or_numpy(device_spec):
179     # legacy spec of (gpu) device
180     if device_spec >= 0:
181         return cuda.GpuDevice.from_device_id(device_spec)
182     else:
183         return _cpu.CpuDevice()
184 
185 
186 def using_device(device_spec):
187     """Context manager to apply the thread-local device state.
188 
189     Args:
190         device_spec (object): Device specifier. See :func:`chainer.get_device`
191             for details.
192 
193     .. admonition:: Example
194 
195         .. testcode::
196            :skipif: doctest_helper.skipif_not_enough_cuda_devices(2)
197 
198            with chainer.using_device('@cupy:1'):
199                a = cupy.empty((3, 2))
200 
201            assert a.device.id == 1
202 
203     """
204 
205     # TODO(niboshi): Set default device (once this concept is introduced in
206     # Chainer).
207     device = get_device(device_spec)
208     return device.create_context()
209 
210 
211 def get_array_module(*args):
212     """Gets an appropriate NumPy-compatible module to process arguments
213 
214     This function will return their data arrays' array module for
215     :class:`~chainer.Variable` arguments.
216 
217     Args:
218         args: Values to determine whether NumPy, CuPy, or ChainerX should be
219             used.
220 
221     Returns:
222         module: :mod:`numpy`, :mod:`cupy`, or :mod:`chainerx` is returned based
223         on the types of the arguments.
224 
225     """
226     is_chainerx_available = chainerx.is_available()
227     if is_chainerx_available or cuda.available:
228         arrays = []
229         for arg in args:
230             # Unwrap arrays
231             if isinstance(arg, chainer.variable.Variable):
232                 array = arg.data
233             else:
234                 array = arg
235             if is_chainerx_available and isinstance(array, chainerx.ndarray):
236                 return chainerx
237             arrays.append(array)
238         if cuda.available:
239             return cuda.cupy.get_array_module(*arrays)
240     return numpy
241 
242 
243 def get_device_from_array(*arrays):
244     """Gets the device from arrays.
245 
246     The device on which the given array reside is returned.
247 
248     .. note::
249 
250         Unlike :func:`get_array_module`, this method does not recognize
251         :class:`~chainer.Variable` objects.
252         If you need to get device from the :class:`~chainer.Variable` instance
253         ``v``, you need to use ``get_device_from_array(v.array)``.
254 
255     Args:
256         arrays (array or list of arrays):
257             Arrays to determine the device. If multiple arrays are given, the
258             device correspoinding to the first array which is not NumPy array
259             is returned.
260 
261     Returns:
262         chainer.backend.Device: Device instance.
263     """
264     for array in arrays:
265         device = GpuDevice.from_array(array)
266         if device is not None:
267             return device
268 
269         if isinstance(array, chainerx.ndarray):
270             return ChainerxDevice(array.device)
271 
272         device = Intel64Device.from_array(array)
273         if device is not None:
274             return device
275 
276     return CpuDevice()
277
```
--- 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/backend.py b/chainer/backend.py
--- a/chainer/backend.py
+++ b/chainer/backend.py
@@ -52,7 +52,12 @@
     """
     if isinstance(dst, chainerx.ndarray):
         dst[...] = _chainerx._array_to_chainerx(src, dst.device)
-    elif isinstance(dst, numpy.ndarray):
+        return
+
+    if isinstance(src, chainerx.ndarray):
+        src = from_chx(src)
+
+    if isinstance(dst, numpy.ndarray):
         numpy.copyto(dst, _cpu._to_cpu(src))
     elif isinstance(dst, intel64.mdarray):
         intel64.ideep.basic_copyto(

{"golden_diff": "diff --git a/chainer/backend.py b/chainer/backend.py\n--- a/chainer/backend.py\n+++ b/chainer/backend.py\n@@ -52,7 +52,12 @@\n     \"\"\"\n     if isinstance(dst, chainerx.ndarray):\n         dst[...] = _chainerx._array_to_chainerx(src, dst.device)\n-    elif isinstance(dst, numpy.ndarray):\n+        return\n+\n+    if isinstance(src, chainerx.ndarray):\n+        src = from_chx(src)\n+\n+    if isinstance(dst, numpy.ndarray):\n         numpy.copyto(dst, _cpu._to_cpu(src))\n     elif isinstance(dst, intel64.mdarray):\n         intel64.ideep.basic_copyto(\n", "issue": "`chainer.backend.copyto` cannot copy chainerx array to cupy\n* Code to reproduce\r\n```python\r\nimport chainer\r\nimport numpy\r\n\r\nfor dst_device in ['@numpy', '@cupy:0', '@intel64']:\r\n    for src_device in ['native', 'cuda:0']:\r\n        print((dst_device, src_device))\r\n        dst = chainer.get_device(dst_device).send(\r\n            numpy.array([1, 2], numpy.float32))\r\n        src = chainer.get_device(src_device).send(\r\n            numpy.array([3, 4], numpy.float32))\r\n        try:\r\n            chainer.backend.copyto(dst, src)\r\n        except Exception as e:\r\n            print(repr(e))\r\n        else:\r\n            print('ok')\r\n```\r\n\r\n* Error messages, stack traces, or logs\r\n```\r\n('@numpy', 'native')\r\nok\r\n('@numpy', 'cuda:0')\r\nok\r\n('@cupy:0', 'native')\r\nTypeError('object array cannot be set to float32 array')\r\n('@cupy:0', 'cuda:0')\r\nTypeError('object array cannot be set to float32 array')\r\n('@intel64', 'native')\r\nok\r\n('@intel64', 'cuda:0')\r\nok\r\n```\r\n\n", "before_files": [{"content": "import numpy\nimport six\n\nimport chainer\nfrom chainer.backends import _chainerx\nfrom chainer.backends import _cpu\nfrom chainer.backends import cuda\nfrom chainer.backends import intel64\nimport chainerx\n\n# Aliases\nfrom chainer._backend import Device\nfrom chainer.backends._chainerx import ChainerxDevice\nfrom chainer.backends._chainerx import from_chx  # NOQA\nfrom chainer.backends._chainerx import to_chx  # NOQA\nfrom chainer.backends._cpu import CpuDevice\nfrom chainer.backends.cuda import GpuDevice\nfrom chainer.backends.intel64 import Intel64Device\nfrom chainer import types  # NOQA\n\n\ndef _contains_nan(x):\n    \"\"\"Returns whether the input array has NaN values.\n\n    Args:\n        x (numpy.ndarray or cupy.ndarray): Array to be checked.\n\n    Returns:\n        bool: True if the input has NaN values.\n\n    \"\"\"\n    if x.dtype.kind in ('f', 'c'):\n        device = get_device_from_array(x)\n        with chainer.using_device(device):\n            return device.xp.isnan(x).any()\n    else:\n        return False\n\n\ndef copyto(dst, src):\n    \"\"\"Copies the elements of an ndarray to those of another one.\n\n    This function can copy the CPU/GPU arrays to the destination arrays on\n    another device.\n\n    Args:\n        dst (`numpy.ndarray`, `cupy.ndarray` or `ideep4py.mdarray`):\n            Destination array.\n        src (`numpy.ndarray`, `cupy.ndarray` or `ideep4py.mdarray`):\n            Source array.\n\n    \"\"\"\n    if isinstance(dst, chainerx.ndarray):\n        dst[...] = _chainerx._array_to_chainerx(src, dst.device)\n    elif isinstance(dst, numpy.ndarray):\n        numpy.copyto(dst, _cpu._to_cpu(src))\n    elif isinstance(dst, intel64.mdarray):\n        intel64.ideep.basic_copyto(\n            dst, _cpu._to_cpu(src))\n    elif isinstance(dst, cuda.ndarray):\n        if isinstance(src, chainer.get_cpu_array_types()):\n            src = numpy.asarray(src)\n            if dst.flags.c_contiguous or dst.flags.f_contiguous:\n                dst.set(src)\n            else:\n                cuda.cupy.copyto(dst, cuda.to_gpu(src, device=dst.device))\n        elif isinstance(src, cuda.ndarray):\n            cuda.cupy.copyto(dst, src)\n        else:\n            raise TypeError('cannot copy from non-array object of type {}'\n                            .format(type(src)))\n    else:\n        raise TypeError('cannot copy to non-array object of type {}'.format(\n            type(dst)))\n\n\ndef _guess_device_from_array_module(xp):\n    \"\"\"Returns a plausible device from array module\n\n    .. warning::\n\n        There can be multiple devices for a module\n\n    \"\"\"\n    if xp is cuda.cupy:\n        return cuda.GpuDevice(cuda.Device())\n    elif xp is chainerx:\n        return _chainerx.ChainerxDevice(chainerx.get_default_device())\n    else:\n        # Cannot detect intel64, because xp of intel64 is numpy.\n        return _cpu.CpuDevice()\n\n\ndef get_device(device_spec):\n    # type: (types.DeviceSpec) -> Device\n    \"\"\"Returns a device object.\n\n    Args:\n        device_spec (object): Device specifier.\n            If a :class:`chainer.backend.Device` instance is given, it is\n            returned intact. Otherwise the following values are supported:\n\n            * ChainerX devices\n\n              * A string representing a device.\n                (ex. ``'native:0'``, ``'native'``)\n              * A :class:`chainerx.Device` object.\n\n            * CuPy\n\n              * A string starts with ``'@cupy:'``.\n                (ex. ``'@cupy:0'``)\n              * A :class:`cupy.cuda.Device` object.\n\n            * NumPy\n\n              * The string ``'@numpy'``.\n\n            * NumPy with Intel Architecture\n\n              * The string ``'@intel64'``.\n    \"\"\"\n    if isinstance(device_spec, Device):\n        return device_spec\n\n    if isinstance(device_spec, cuda._integer_types):\n        return _get_device_cupy_or_numpy(device_spec)\n\n    if chainerx.is_available() and isinstance(device_spec, chainerx.Device):\n        return _chainerx.ChainerxDevice(device_spec)\n\n    if cuda.available and isinstance(device_spec, cuda.Device):\n        return cuda.GpuDevice(device_spec)\n\n    if isinstance(device_spec, six.string_types):\n        # '-1', '0', '1', ...\n        try:\n            int_device_spec = int(device_spec)\n        except ValueError:\n            pass\n        else:\n            return _get_device_cupy_or_numpy(int_device_spec)\n\n        if device_spec.startswith('@'):\n            # '@module:...'\n            mod_name, colon, precise_spec = device_spec[1:].partition(':')\n            if mod_name == 'numpy':\n                if not colon:\n                    return _cpu.CpuDevice()\n            elif mod_name == 'cupy':\n                if colon:\n                    return cuda.GpuDevice.from_device_id(int(precise_spec))\n            elif mod_name == 'intel64':\n                if not colon:\n                    return intel64.Intel64Device()\n            raise ValueError(\n                'Device specifiers starting with \\'@\\' must be followed by'\n                ' a module name and depending on the module, module specific'\n                ' precise device specifiers. Actual: {}'.format(device_spec))\n        else:\n            # String device specifier without '@' prefix is assumed to be a\n            # ChainerX device.\n            if not chainerx.is_available():\n                raise RuntimeError(\n                    'Tried to parse ChainerX device specifier \\'{}\\', '\n                    'but ChainerX is not available. '\n                    'Note that device specifiers without \\'@\\' prefix are '\n                    'assumed to be ChainerX device '\n                    'specifiers.'.format(device_spec))\n            return _chainerx.ChainerxDevice(chainerx.get_device(device_spec))\n\n    raise TypeError(\n        'Device specifier must be a backend.Device, cuda.Device,'\n        ' chainerx.Device, integer or a string. Actual: {}'.format(\n            type(device_spec)))\n\n\ndef _get_device_cupy_or_numpy(device_spec):\n    # legacy spec of (gpu) device\n    if device_spec >= 0:\n        return cuda.GpuDevice.from_device_id(device_spec)\n    else:\n        return _cpu.CpuDevice()\n\n\ndef using_device(device_spec):\n    \"\"\"Context manager to apply the thread-local device state.\n\n    Args:\n        device_spec (object): Device specifier. See :func:`chainer.get_device`\n            for details.\n\n    .. admonition:: Example\n\n        .. testcode::\n           :skipif: doctest_helper.skipif_not_enough_cuda_devices(2)\n\n           with chainer.using_device('@cupy:1'):\n               a = cupy.empty((3, 2))\n\n           assert a.device.id == 1\n\n    \"\"\"\n\n    # TODO(niboshi): Set default device (once this concept is introduced in\n    # Chainer).\n    device = get_device(device_spec)\n    return device.create_context()\n\n\ndef get_array_module(*args):\n    \"\"\"Gets an appropriate NumPy-compatible module to process arguments\n\n    This function will return their data arrays' array module for\n    :class:`~chainer.Variable` arguments.\n\n    Args:\n        args: Values to determine whether NumPy, CuPy, or ChainerX should be\n            used.\n\n    Returns:\n        module: :mod:`numpy`, :mod:`cupy`, or :mod:`chainerx` is returned based\n        on the types of the arguments.\n\n    \"\"\"\n    is_chainerx_available = chainerx.is_available()\n    if is_chainerx_available or cuda.available:\n        arrays = []\n        for arg in args:\n            # Unwrap arrays\n            if isinstance(arg, chainer.variable.Variable):\n                array = arg.data\n            else:\n                array = arg\n            if is_chainerx_available and isinstance(array, chainerx.ndarray):\n                return chainerx\n            arrays.append(array)\n        if cuda.available:\n            return cuda.cupy.get_array_module(*arrays)\n    return numpy\n\n\ndef get_device_from_array(*arrays):\n    \"\"\"Gets the device from arrays.\n\n    The device on which the given array reside is returned.\n\n    .. note::\n\n        Unlike :func:`get_array_module`, this method does not recognize\n        :class:`~chainer.Variable` objects.\n        If you need to get device from the :class:`~chainer.Variable` instance\n        ``v``, you need to use ``get_device_from_array(v.array)``.\n\n    Args:\n        arrays (array or list of arrays):\n            Arrays to determine the device. If multiple arrays are given, the\n            device correspoinding to the first array which is not NumPy array\n            is returned.\n\n    Returns:\n        chainer.backend.Device: Device instance.\n    \"\"\"\n    for array in arrays:\n        device = GpuDevice.from_array(array)\n        if device is not None:\n            return device\n\n        if isinstance(array, chainerx.ndarray):\n            return ChainerxDevice(array.device)\n\n        device = Intel64Device.from_array(array)\n        if device is not None:\n            return device\n\n    return CpuDevice()\n", "path": "chainer/backend.py"}], "after_files": [{"content": "import numpy\nimport six\n\nimport chainer\nfrom chainer.backends import _chainerx\nfrom chainer.backends import _cpu\nfrom chainer.backends import cuda\nfrom chainer.backends import intel64\nimport chainerx\n\n# Aliases\nfrom chainer._backend import Device\nfrom chainer.backends._chainerx import ChainerxDevice\nfrom chainer.backends._chainerx import from_chx  # NOQA\nfrom chainer.backends._chainerx import to_chx  # NOQA\nfrom chainer.backends._cpu import CpuDevice\nfrom chainer.backends.cuda import GpuDevice\nfrom chainer.backends.intel64 import Intel64Device\nfrom chainer import types  # NOQA\n\n\ndef _contains_nan(x):\n    \"\"\"Returns whether the input array has NaN values.\n\n    Args:\n        x (numpy.ndarray or cupy.ndarray): Array to be checked.\n\n    Returns:\n        bool: True if the input has NaN values.\n\n    \"\"\"\n    if x.dtype.kind in ('f', 'c'):\n        device = get_device_from_array(x)\n        with chainer.using_device(device):\n            return device.xp.isnan(x).any()\n    else:\n        return False\n\n\ndef copyto(dst, src):\n    \"\"\"Copies the elements of an ndarray to those of another one.\n\n    This function can copy the CPU/GPU arrays to the destination arrays on\n    another device.\n\n    Args:\n        dst (`numpy.ndarray`, `cupy.ndarray` or `ideep4py.mdarray`):\n            Destination array.\n        src (`numpy.ndarray`, `cupy.ndarray` or `ideep4py.mdarray`):\n            Source array.\n\n    \"\"\"\n    if isinstance(dst, chainerx.ndarray):\n        dst[...] = _chainerx._array_to_chainerx(src, dst.device)\n        return\n\n    if isinstance(src, chainerx.ndarray):\n        src = from_chx(src)\n\n    if isinstance(dst, numpy.ndarray):\n        numpy.copyto(dst, _cpu._to_cpu(src))\n    elif isinstance(dst, intel64.mdarray):\n        intel64.ideep.basic_copyto(\n            dst, _cpu._to_cpu(src))\n    elif isinstance(dst, cuda.ndarray):\n        if isinstance(src, chainer.get_cpu_array_types()):\n            src = numpy.asarray(src)\n            if dst.flags.c_contiguous or dst.flags.f_contiguous:\n                dst.set(src)\n            else:\n                cuda.cupy.copyto(dst, cuda.to_gpu(src, device=dst.device))\n        elif isinstance(src, cuda.ndarray):\n            cuda.cupy.copyto(dst, src)\n        else:\n            raise TypeError('cannot copy from non-array object of type {}'\n                            .format(type(src)))\n    else:\n        raise TypeError('cannot copy to non-array object of type {}'.format(\n            type(dst)))\n\n\ndef _guess_device_from_array_module(xp):\n    \"\"\"Returns a plausible device from array module\n\n    .. warning::\n\n        There can be multiple devices for a module\n\n    \"\"\"\n    if xp is cuda.cupy:\n        return cuda.GpuDevice(cuda.Device())\n    elif xp is chainerx:\n        return _chainerx.ChainerxDevice(chainerx.get_default_device())\n    else:\n        # Cannot detect intel64, because xp of intel64 is numpy.\n        return _cpu.CpuDevice()\n\n\ndef get_device(device_spec):\n    # type: (types.DeviceSpec) -> Device\n    \"\"\"Returns a device object.\n\n    Args:\n        device_spec (object): Device specifier.\n            If a :class:`chainer.backend.Device` instance is given, it is\n            returned intact. Otherwise the following values are supported:\n\n            * ChainerX devices\n\n              * A string representing a device.\n                (ex. ``'native:0'``, ``'native'``)\n              * A :class:`chainerx.Device` object.\n\n            * CuPy\n\n              * A string starts with ``'@cupy:'``.\n                (ex. ``'@cupy:0'``)\n              * A :class:`cupy.cuda.Device` object.\n\n            * NumPy\n\n              * The string ``'@numpy'``.\n\n            * NumPy with Intel Architecture\n\n              * The string ``'@intel64'``.\n    \"\"\"\n    if isinstance(device_spec, Device):\n        return device_spec\n\n    if isinstance(device_spec, cuda._integer_types):\n        return _get_device_cupy_or_numpy(device_spec)\n\n    if chainerx.is_available() and isinstance(device_spec, chainerx.Device):\n        return _chainerx.ChainerxDevice(device_spec)\n\n    if cuda.available and isinstance(device_spec, cuda.Device):\n        return cuda.GpuDevice(device_spec)\n\n    if isinstance(device_spec, six.string_types):\n        # '-1', '0', '1', ...\n        try:\n            int_device_spec = int(device_spec)\n        except ValueError:\n            pass\n        else:\n            return _get_device_cupy_or_numpy(int_device_spec)\n\n        if device_spec.startswith('@'):\n            # '@module:...'\n            mod_name, colon, precise_spec = device_spec[1:].partition(':')\n            if mod_name == 'numpy':\n                if not colon:\n                    return _cpu.CpuDevice()\n            elif mod_name == 'cupy':\n                if colon:\n                    return cuda.GpuDevice.from_device_id(int(precise_spec))\n            elif mod_name == 'intel64':\n                if not colon:\n                    return intel64.Intel64Device()\n            raise ValueError(\n                'Device specifiers starting with \\'@\\' must be followed by'\n                ' a module name and depending on the module, module specific'\n                ' precise device specifiers. Actual: {}'.format(device_spec))\n        else:\n            # String device specifier without '@' prefix is assumed to be a\n            # ChainerX device.\n            if not chainerx.is_available():\n                raise RuntimeError(\n                    'Tried to parse ChainerX device specifier \\'{}\\', '\n                    'but ChainerX is not available. '\n                    'Note that device specifiers without \\'@\\' prefix are '\n                    'assumed to be ChainerX device '\n                    'specifiers.'.format(device_spec))\n            return _chainerx.ChainerxDevice(chainerx.get_device(device_spec))\n\n    raise TypeError(\n        'Device specifier must be a backend.Device, cuda.Device,'\n        ' chainerx.Device, integer or a string. Actual: {}'.format(\n            type(device_spec)))\n\n\ndef _get_device_cupy_or_numpy(device_spec):\n    # legacy spec of (gpu) device\n    if device_spec >= 0:\n        return cuda.GpuDevice.from_device_id(device_spec)\n    else:\n        return _cpu.CpuDevice()\n\n\ndef using_device(device_spec):\n    \"\"\"Context manager to apply the thread-local device state.\n\n    Args:\n        device_spec (object): Device specifier. See :func:`chainer.get_device`\n            for details.\n\n    .. admonition:: Example\n\n        .. testcode::\n           :skipif: doctest_helper.skipif_not_enough_cuda_devices(2)\n\n           with chainer.using_device('@cupy:1'):\n               a = cupy.empty((3, 2))\n\n           assert a.device.id == 1\n\n    \"\"\"\n\n    # TODO(niboshi): Set default device (once this concept is introduced in\n    # Chainer).\n    device = get_device(device_spec)\n    return device.create_context()\n\n\ndef get_array_module(*args):\n    \"\"\"Gets an appropriate NumPy-compatible module to process arguments\n\n    This function will return their data arrays' array module for\n    :class:`~chainer.Variable` arguments.\n\n    Args:\n        args: Values to determine whether NumPy, CuPy, or ChainerX should be\n            used.\n\n    Returns:\n        module: :mod:`numpy`, :mod:`cupy`, or :mod:`chainerx` is returned based\n        on the types of the arguments.\n\n    \"\"\"\n    is_chainerx_available = chainerx.is_available()\n    if is_chainerx_available or cuda.available:\n        arrays = []\n        for arg in args:\n            # Unwrap arrays\n            if isinstance(arg, chainer.variable.Variable):\n                array = arg.data\n            else:\n                array = arg\n            if is_chainerx_available and isinstance(array, chainerx.ndarray):\n                return chainerx\n            arrays.append(array)\n        if cuda.available:\n            return cuda.cupy.get_array_module(*arrays)\n    return numpy\n\n\ndef get_device_from_array(*arrays):\n    \"\"\"Gets the device from arrays.\n\n    The device on which the given array reside is returned.\n\n    .. note::\n\n        Unlike :func:`get_array_module`, this method does not recognize\n        :class:`~chainer.Variable` objects.\n        If you need to get device from the :class:`~chainer.Variable` instance\n        ``v``, you need to use ``get_device_from_array(v.array)``.\n\n    Args:\n        arrays (array or list of arrays):\n            Arrays to determine the device. If multiple arrays are given, the\n            device correspoinding to the first array which is not NumPy array\n            is returned.\n\n    Returns:\n        chainer.backend.Device: Device instance.\n    \"\"\"\n    for array in arrays:\n        device = GpuDevice.from_array(array)\n        if device is not None:\n            return device\n\n        if isinstance(array, chainerx.ndarray):\n            return ChainerxDevice(array.device)\n\n        device = Intel64Device.from_array(array)\n        if device is not None:\n            return device\n\n    return CpuDevice()\n", "path": "chainer/backend.py"}]}