We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Indexing with assignment between broadcastable arrays is inconsistent with NumPy
When performing `A[idx, ...] = B` with `B` broadcastable over `A[idx, ...]` (so no storage expansion for `A[idx, ...]` is necessary) with `B.ndim > A.ndim` CuPy throws a shape mismatch error while NumPy handles this case.

* Code to reproduce
```python
In [1]: import numpy

In [2]: import cupy

In [3]: def test(module):
   ...:     x = module.zeros((3, 3, 3))
   ...:     y = module.ones((1, 3, 3))
   ...:     x[0, ...] = y
   ...:     return x
   ...: 
   ...: 

In [4]: test(numpy)
Out[4]: 
array([[[1., 1., 1.],
        [1., 1., 1.],
        [1., 1., 1.]],

       [[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]],

       [[0., 0., 0.],
        [0., 0., 0.],
        [0., 0., 0.]]])

In [5]: test(cupy)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-3f849ce2914e> in <module>()
----> 1 test(cupy)

<ipython-input-3-450cff366473> in test(module)
      2     x = module.zeros((3, 3, 3))
      3     y = module.ones((1, 3, 3))
----> 4     x[0, ...] = y
      5     return x

cupy/_core/core.pyx in cupy._core.core.ndarray.__setitem__()

cupy/_core/_routines_indexing.pyx in cupy._core._routines_indexing._ndarray_setitem()

cupy/_core/_routines_indexing.pyx in cupy._core._routines_indexing._scatter_op()

cupy/_core/_kernel.pyx in cupy._core._kernel.ufunc.__call__()

cupy/_core/_kernel.pyx in cupy._core._kernel._get_out_args()

ValueError: Out shape is mismatched

```

* Conditions
```
OS                           : Linux-5.4.0-81-generic-x86_64-with-debian-bullseye-sid
Python Version               : 3.6.7
CuPy Version                 : 9.5.0
CuPy Platform                : NVIDIA CUDA
NumPy Version                : 1.19.5
SciPy Version                : None
Cython Build Version         : 0.29.24
Cython Runtime Version       : None
CUDA Root                    : /home/nik/.conda/envs/pytorch-cuda-dev
nvcc PATH                    : /home/nik/.conda/envs/pytorch-cuda-dev/bin/nvcc
CUDA Build Version           : 11020
CUDA Driver Version          : 11030
CUDA Runtime Version         : 11020
cuBLAS Version               : (available)
cuFFT Version                : 10401
cuRAND Version               : 10203
cuSOLVER Version             : (11, 1, 0)
cuSPARSE Version             : (available)
NVRTC Version                : (11, 2)
Thrust Version               : 101000
CUB Build Version            : 101000
Jitify Build Version         : <unknown>
cuDNN Build Version          : 8201
cuDNN Version                : 8004
NCCL Build Version           : None
NCCL Runtime Version         : None
cuTENSOR Version             : None
cuSPARSELt Build Version     : None
Device 0 Name                : NVIDIA GeForce RTX 2060
Device 0 Compute Capability  : 75
Device 0 PCI Bus ID          : 0000:01:00.0
Device 1 Name                : NVIDIA GeForce RTX 2060
Device 1 Compute Capability  : 75
Device 1 PCI Bus ID          : 0000:21:00.0
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cupy/_manipulation/basic.py`
Content:
```
1 import numpy
2 
3 from cupy import _core
4 from cupy._core import _fusion_interface
5 from cupy._core import fusion
6 from cupy._sorting import search
7 from cupy_backends.cuda.api import runtime
8 
9 
10 def copyto(dst, src, casting='same_kind', where=None):
11     """Copies values from one array to another with broadcasting.
12 
13     This function can be called for arrays on different devices. In this case,
14     casting, ``where``, and broadcasting is not supported, and an exception is
15     raised if these are used.
16 
17     Args:
18         dst (cupy.ndarray): Target array.
19         src (cupy.ndarray): Source array.
20         casting (str): Casting rule. See :func:`numpy.can_cast` for detail.
21         where (cupy.ndarray of bool): If specified, this array acts as a mask,
22             and an element is copied only if the corresponding element of
23             ``where`` is True.
24 
25     .. seealso:: :func:`numpy.copyto`
26 
27     """
28 
29     src_type = type(src)
30     src_is_python_scalar = src_type in (
31         int, bool, float, complex,
32         fusion._FusionVarScalar, _fusion_interface._ScalarProxy)
33     if src_is_python_scalar:
34         src_dtype = numpy.dtype(type(src))
35         can_cast = numpy.can_cast(src, dst.dtype, casting)
36     else:
37         src_dtype = src.dtype
38         can_cast = numpy.can_cast(src_dtype, dst.dtype, casting)
39 
40     if not can_cast:
41         raise TypeError('Cannot cast %s to %s in %s casting mode' %
42                         (src_dtype, dst.dtype, casting))
43     if fusion._is_fusing():
44         if where is None:
45             _core.elementwise_copy(src, dst)
46         else:
47             fusion._call_ufunc(search._where_ufunc, where, src, dst, dst)
48         return
49 
50     if where is not None:
51         _core.elementwise_copy(src, dst, _where=where)
52         return
53 
54     if dst.size == 0:
55         return
56 
57     if src_is_python_scalar:
58         dst.fill(src)
59         return
60 
61     if _can_memcpy(dst, src):
62         dst.data.copy_from_async(src.data, src.nbytes)
63         return
64 
65     device = dst.device
66     prev_device = runtime.getDevice()
67     try:
68         runtime.setDevice(device.id)
69         if src.device != device:
70             src = src.copy()
71         _core.elementwise_copy(src, dst)
72     finally:
73         runtime.setDevice(prev_device)
74 
75 
76 def _can_memcpy(dst, src):
77     c_contiguous = dst.flags.c_contiguous and src.flags.c_contiguous
78     f_contiguous = dst.flags.f_contiguous and src.flags.f_contiguous
79     return (c_contiguous or f_contiguous) and dst.dtype == src.dtype and \
80         dst.size == src.size
81
```
--- 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/cupy/_manipulation/basic.py b/cupy/_manipulation/basic.py
--- a/cupy/_manipulation/basic.py
+++ b/cupy/_manipulation/basic.py
@@ -40,6 +40,16 @@
     if not can_cast:
         raise TypeError('Cannot cast %s to %s in %s casting mode' %
                         (src_dtype, dst.dtype, casting))
+
+    if not src_is_python_scalar and src.ndim > dst.ndim:
+        # NumPy allows stripping leading unit dimensions.
+        try:
+            src = src.squeeze(tuple(range(src.ndim - dst.ndim)))
+        except ValueError:
+            # "cannot select an axis to squeeze out
+            # which has size not equal to one"
+            pass  # raise an error later
+
     if fusion._is_fusing():
         if where is None:
             _core.elementwise_copy(src, dst)

{"golden_diff": "diff --git a/cupy/_manipulation/basic.py b/cupy/_manipulation/basic.py\n--- a/cupy/_manipulation/basic.py\n+++ b/cupy/_manipulation/basic.py\n@@ -40,6 +40,16 @@\n     if not can_cast:\n         raise TypeError('Cannot cast %s to %s in %s casting mode' %\n                         (src_dtype, dst.dtype, casting))\n+\n+    if not src_is_python_scalar and src.ndim > dst.ndim:\n+        # NumPy allows stripping leading unit dimensions.\n+        try:\n+            src = src.squeeze(tuple(range(src.ndim - dst.ndim)))\n+        except ValueError:\n+            # \"cannot select an axis to squeeze out\n+            # which has size not equal to one\"\n+            pass  # raise an error later\n+\n     if fusion._is_fusing():\n         if where is None:\n             _core.elementwise_copy(src, dst)\n", "issue": "Indexing with assignment between broadcastable arrays is inconsistent with NumPy\nWhen performing `A[idx, ...] = B` with `B` broadcastable over `A[idx, ...]` (so no storage expansion for `A[idx, ...]` is necessary) with `B.ndim > A.ndim` CuPy throws a shape mismatch error while NumPy handles this case.\r\n\r\n* Code to reproduce\r\n```python\r\nIn [1]: import numpy\r\n\r\nIn [2]: import cupy\r\n\r\nIn [3]: def test(module):\r\n   ...:     x = module.zeros((3, 3, 3))\r\n   ...:     y = module.ones((1, 3, 3))\r\n   ...:     x[0, ...] = y\r\n   ...:     return x\r\n   ...: \r\n   ...: \r\n\r\nIn [4]: test(numpy)\r\nOut[4]: \r\narray([[[1., 1., 1.],\r\n        [1., 1., 1.],\r\n        [1., 1., 1.]],\r\n\r\n       [[0., 0., 0.],\r\n        [0., 0., 0.],\r\n        [0., 0., 0.]],\r\n\r\n       [[0., 0., 0.],\r\n        [0., 0., 0.],\r\n        [0., 0., 0.]]])\r\n\r\nIn [5]: test(cupy)\r\n---------------------------------------------------------------------------\r\nValueError                                Traceback (most recent call last)\r\n<ipython-input-5-3f849ce2914e> in <module>()\r\n----> 1 test(cupy)\r\n\r\n<ipython-input-3-450cff366473> in test(module)\r\n      2     x = module.zeros((3, 3, 3))\r\n      3     y = module.ones((1, 3, 3))\r\n----> 4     x[0, ...] = y\r\n      5     return x\r\n\r\ncupy/_core/core.pyx in cupy._core.core.ndarray.__setitem__()\r\n\r\ncupy/_core/_routines_indexing.pyx in cupy._core._routines_indexing._ndarray_setitem()\r\n\r\ncupy/_core/_routines_indexing.pyx in cupy._core._routines_indexing._scatter_op()\r\n\r\ncupy/_core/_kernel.pyx in cupy._core._kernel.ufunc.__call__()\r\n\r\ncupy/_core/_kernel.pyx in cupy._core._kernel._get_out_args()\r\n\r\nValueError: Out shape is mismatched\r\n\r\n```\r\n\r\n* Conditions\r\n```\r\nOS                           : Linux-5.4.0-81-generic-x86_64-with-debian-bullseye-sid\r\nPython Version               : 3.6.7\r\nCuPy Version                 : 9.5.0\r\nCuPy Platform                : NVIDIA CUDA\r\nNumPy Version                : 1.19.5\r\nSciPy Version                : None\r\nCython Build Version         : 0.29.24\r\nCython Runtime Version       : None\r\nCUDA Root                    : /home/nik/.conda/envs/pytorch-cuda-dev\r\nnvcc PATH                    : /home/nik/.conda/envs/pytorch-cuda-dev/bin/nvcc\r\nCUDA Build Version           : 11020\r\nCUDA Driver Version          : 11030\r\nCUDA Runtime Version         : 11020\r\ncuBLAS Version               : (available)\r\ncuFFT Version                : 10401\r\ncuRAND Version               : 10203\r\ncuSOLVER Version             : (11, 1, 0)\r\ncuSPARSE Version             : (available)\r\nNVRTC Version                : (11, 2)\r\nThrust Version               : 101000\r\nCUB Build Version            : 101000\r\nJitify Build Version         : <unknown>\r\ncuDNN Build Version          : 8201\r\ncuDNN Version                : 8004\r\nNCCL Build Version           : None\r\nNCCL Runtime Version         : None\r\ncuTENSOR Version             : None\r\ncuSPARSELt Build Version     : None\r\nDevice 0 Name                : NVIDIA GeForce RTX 2060\r\nDevice 0 Compute Capability  : 75\r\nDevice 0 PCI Bus ID          : 0000:01:00.0\r\nDevice 1 Name                : NVIDIA GeForce RTX 2060\r\nDevice 1 Compute Capability  : 75\r\nDevice 1 PCI Bus ID          : 0000:21:00.0\r\n```\r\n\n", "before_files": [{"content": "import numpy\n\nfrom cupy import _core\nfrom cupy._core import _fusion_interface\nfrom cupy._core import fusion\nfrom cupy._sorting import search\nfrom cupy_backends.cuda.api import runtime\n\n\ndef copyto(dst, src, casting='same_kind', where=None):\n    \"\"\"Copies values from one array to another with broadcasting.\n\n    This function can be called for arrays on different devices. In this case,\n    casting, ``where``, and broadcasting is not supported, and an exception is\n    raised if these are used.\n\n    Args:\n        dst (cupy.ndarray): Target array.\n        src (cupy.ndarray): Source array.\n        casting (str): Casting rule. See :func:`numpy.can_cast` for detail.\n        where (cupy.ndarray of bool): If specified, this array acts as a mask,\n            and an element is copied only if the corresponding element of\n            ``where`` is True.\n\n    .. seealso:: :func:`numpy.copyto`\n\n    \"\"\"\n\n    src_type = type(src)\n    src_is_python_scalar = src_type in (\n        int, bool, float, complex,\n        fusion._FusionVarScalar, _fusion_interface._ScalarProxy)\n    if src_is_python_scalar:\n        src_dtype = numpy.dtype(type(src))\n        can_cast = numpy.can_cast(src, dst.dtype, casting)\n    else:\n        src_dtype = src.dtype\n        can_cast = numpy.can_cast(src_dtype, dst.dtype, casting)\n\n    if not can_cast:\n        raise TypeError('Cannot cast %s to %s in %s casting mode' %\n                        (src_dtype, dst.dtype, casting))\n    if fusion._is_fusing():\n        if where is None:\n            _core.elementwise_copy(src, dst)\n        else:\n            fusion._call_ufunc(search._where_ufunc, where, src, dst, dst)\n        return\n\n    if where is not None:\n        _core.elementwise_copy(src, dst, _where=where)\n        return\n\n    if dst.size == 0:\n        return\n\n    if src_is_python_scalar:\n        dst.fill(src)\n        return\n\n    if _can_memcpy(dst, src):\n        dst.data.copy_from_async(src.data, src.nbytes)\n        return\n\n    device = dst.device\n    prev_device = runtime.getDevice()\n    try:\n        runtime.setDevice(device.id)\n        if src.device != device:\n            src = src.copy()\n        _core.elementwise_copy(src, dst)\n    finally:\n        runtime.setDevice(prev_device)\n\n\ndef _can_memcpy(dst, src):\n    c_contiguous = dst.flags.c_contiguous and src.flags.c_contiguous\n    f_contiguous = dst.flags.f_contiguous and src.flags.f_contiguous\n    return (c_contiguous or f_contiguous) and dst.dtype == src.dtype and \\\n        dst.size == src.size\n", "path": "cupy/_manipulation/basic.py"}], "after_files": [{"content": "import numpy\n\nfrom cupy import _core\nfrom cupy._core import _fusion_interface\nfrom cupy._core import fusion\nfrom cupy._sorting import search\nfrom cupy_backends.cuda.api import runtime\n\n\ndef copyto(dst, src, casting='same_kind', where=None):\n    \"\"\"Copies values from one array to another with broadcasting.\n\n    This function can be called for arrays on different devices. In this case,\n    casting, ``where``, and broadcasting is not supported, and an exception is\n    raised if these are used.\n\n    Args:\n        dst (cupy.ndarray): Target array.\n        src (cupy.ndarray): Source array.\n        casting (str): Casting rule. See :func:`numpy.can_cast` for detail.\n        where (cupy.ndarray of bool): If specified, this array acts as a mask,\n            and an element is copied only if the corresponding element of\n            ``where`` is True.\n\n    .. seealso:: :func:`numpy.copyto`\n\n    \"\"\"\n\n    src_type = type(src)\n    src_is_python_scalar = src_type in (\n        int, bool, float, complex,\n        fusion._FusionVarScalar, _fusion_interface._ScalarProxy)\n    if src_is_python_scalar:\n        src_dtype = numpy.dtype(type(src))\n        can_cast = numpy.can_cast(src, dst.dtype, casting)\n    else:\n        src_dtype = src.dtype\n        can_cast = numpy.can_cast(src_dtype, dst.dtype, casting)\n\n    if not can_cast:\n        raise TypeError('Cannot cast %s to %s in %s casting mode' %\n                        (src_dtype, dst.dtype, casting))\n\n    if not src_is_python_scalar and src.ndim > dst.ndim:\n        # NumPy allows stripping leading unit dimensions.\n        try:\n            src = src.squeeze(tuple(range(src.ndim - dst.ndim)))\n        except ValueError:\n            # \"cannot select an axis to squeeze out\n            # which has size not equal to one\"\n            pass  # raise an error later\n\n    if fusion._is_fusing():\n        if where is None:\n            _core.elementwise_copy(src, dst)\n        else:\n            fusion._call_ufunc(search._where_ufunc, where, src, dst, dst)\n        return\n\n    if where is not None:\n        _core.elementwise_copy(src, dst, _where=where)\n        return\n\n    if dst.size == 0:\n        return\n\n    if src_is_python_scalar:\n        dst.fill(src)\n        return\n\n    if _can_memcpy(dst, src):\n        dst.data.copy_from_async(src.data, src.nbytes)\n        return\n\n    device = dst.device\n    prev_device = runtime.getDevice()\n    try:\n        runtime.setDevice(device.id)\n        if src.device != device:\n            src = src.copy()\n        _core.elementwise_copy(src, dst)\n    finally:\n        runtime.setDevice(prev_device)\n\n\ndef _can_memcpy(dst, src):\n    c_contiguous = dst.flags.c_contiguous and src.flags.c_contiguous\n    f_contiguous = dst.flags.f_contiguous and src.flags.f_contiguous\n    return (c_contiguous or f_contiguous) and dst.dtype == src.dtype and \\\n        dst.size == src.size\n", "path": "cupy/_manipulation/basic.py"}]}