We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
cupy.where fails for complex arrays
The function cupy.where does not work for complex arrays (numpy.where does):

```
import cupy as cp
a = cp.arange(5).astype(cp.complex128)
b = cp.arange(5).astype(cp.complex128)
c = cp.where(a==b,a,b)
```

fails with the error message

> TypeError: Wrong type ((<class 'numpy.bool_'>, <class 'numpy.complex128'>, <class 'numpy.complex128'>)) of arguments for cupy_where

For `cp.float64`, everything works fine.

CuPy Version          : 6.4.0
CUDA Root             : /usr
CUDA Build Version    : 8000
CUDA Driver Version   : 10020
CUDA Runtime Version  : 8000
cuDNN Build Version   : 7102
cuDNN Version         : 7102
NCCL Build Version    : 2213
NCCL Runtime Version  : (unknown)

--- 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/sorting/search.py`
Content:
```
1 from cupy import core
2 from cupy.core import fusion
3 
4 
5 def argmax(a, axis=None, dtype=None, out=None, keepdims=False):
6     """Returns the indices of the maximum along an axis.
7 
8     Args:
9         a (cupy.ndarray): Array to take argmax.
10         axis (int): Along which axis to find the maximum. ``a`` is flattened by
11             default.
12         dtype: Data type specifier.
13         out (cupy.ndarray): Output array.
14         keepdims (bool): If ``True``, the axis ``axis`` is preserved as an axis
15             of length one.
16 
17     Returns:
18         cupy.ndarray: The indices of the maximum of ``a`` along an axis.
19 
20     .. seealso:: :func:`numpy.argmax`
21 
22     """
23     # TODO(okuta): check type
24     return a.argmax(axis=axis, dtype=dtype, out=out, keepdims=keepdims)
25 
26 
27 # TODO(okuta): Implement nanargmax
28 
29 
30 def argmin(a, axis=None, dtype=None, out=None, keepdims=False):
31     """Returns the indices of the minimum along an axis.
32 
33     Args:
34         a (cupy.ndarray): Array to take argmin.
35         axis (int): Along which axis to find the minimum. ``a`` is flattened by
36             default.
37         dtype: Data type specifier.
38         out (cupy.ndarray): Output array.
39         keepdims (bool): If ``True``, the axis ``axis`` is preserved as an axis
40             of length one.
41 
42     Returns:
43         cupy.ndarray: The indices of the minimum of ``a`` along an axis.
44 
45     .. seealso:: :func:`numpy.argmin`
46 
47     """
48     # TODO(okuta): check type
49     return a.argmin(axis=axis, dtype=dtype, out=out, keepdims=keepdims)
50 
51 
52 # TODO(okuta): Implement nanargmin
53 
54 
55 # TODO(okuta): Implement argwhere
56 
57 
58 def nonzero(a):
59     """Return the indices of the elements that are non-zero.
60 
61     Returns a tuple of arrays, one for each dimension of a,
62     containing the indices of the non-zero elements in that dimension.
63 
64     Args:
65         a (cupy.ndarray): array
66 
67     Returns:
68         tuple of arrays: Indices of elements that are non-zero.
69 
70     .. seealso:: :func:`numpy.nonzero`
71 
72     """
73     assert isinstance(a, core.ndarray)
74     return a.nonzero()
75 
76 
77 def flatnonzero(a):
78     """Return indices that are non-zero in the flattened version of a.
79 
80     This is equivalent to a.ravel().nonzero()[0].
81 
82     Args:
83         a (cupy.ndarray): input array
84 
85     Returns:
86         cupy.ndarray: Output array,
87         containing the indices of the elements of a.ravel() that are non-zero.
88 
89     .. seealso:: :func:`numpy.flatnonzero`
90     """
91     assert isinstance(a, core.ndarray)
92     return a.ravel().nonzero()[0]
93 
94 
95 _where_ufunc = core.create_ufunc(
96     'cupy_where',
97     ('???->?', '?bb->b', '?BB->B', '?hh->h', '?HH->H', '?ii->i', '?II->I',
98      '?ll->l', '?LL->L', '?qq->q', '?QQ->Q', '?ee->e', '?ff->f',
99      # On CUDA 6.5 these combinations don't work correctly (on CUDA >=7.0, it
100      # works).
101      # See issue #551.
102      '?hd->d', '?Hd->d',
103      '?dd->d'),
104     'out0 = in0 ? in1 : in2')
105 
106 
107 def where(condition, x=None, y=None):
108     """Return elements, either from x or y, depending on condition.
109 
110     If only condition is given, return ``condition.nonzero()``.
111 
112     Args:
113         condition (cupy.ndarray): When True, take x, otherwise take y.
114         x (cupy.ndarray): Values from which to choose on ``True``.
115         y (cupy.ndarray): Values from which to choose on ``False``.
116 
117     Returns:
118         cupy.ndarray: Each element of output contains elements of ``x`` when
119             ``condition`` is ``True``, otherwise elements of ``y``. If only
120             ``condition`` is given, return the tuple ``condition.nonzero()``,
121             the indices where ``condition`` is True.
122 
123     .. seealso:: :func:`numpy.where`
124 
125     """
126 
127     missing = (x is None, y is None).count(True)
128 
129     if missing == 1:
130         raise ValueError('Must provide both \'x\' and \'y\' or neither.')
131     if missing == 2:
132         return nonzero(condition)
133 
134     if fusion._is_fusing():
135         return fusion._call_ufunc(_where_ufunc, condition, x, y)
136     return _where_ufunc(condition.astype('?'), x, y)
137 
138 
139 # TODO(okuta): Implement searchsorted
140 
141 
142 # TODO(okuta): Implement extract
143
```
--- 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/sorting/search.py b/cupy/sorting/search.py
--- a/cupy/sorting/search.py
+++ b/cupy/sorting/search.py
@@ -100,7 +100,7 @@
      # works).
      # See issue #551.
      '?hd->d', '?Hd->d',
-     '?dd->d'),
+     '?dd->d', '?FF->F', '?DD->D'),
     'out0 = in0 ? in1 : in2')

{"golden_diff": "diff --git a/cupy/sorting/search.py b/cupy/sorting/search.py\n--- a/cupy/sorting/search.py\n+++ b/cupy/sorting/search.py\n@@ -100,7 +100,7 @@\n      # works).\n      # See issue #551.\n      '?hd->d', '?Hd->d',\n-     '?dd->d'),\n+     '?dd->d', '?FF->F', '?DD->D'),\n     'out0 = in0 ? in1 : in2')\n", "issue": "cupy.where fails for complex arrays\nThe function cupy.where does not work for complex arrays (numpy.where does):\r\n\r\n```\r\nimport cupy as cp\r\na = cp.arange(5).astype(cp.complex128)\r\nb = cp.arange(5).astype(cp.complex128)\r\nc = cp.where(a==b,a,b)\r\n```\r\n\r\nfails with the error message\r\n\r\n> TypeError: Wrong type ((<class 'numpy.bool_'>, <class 'numpy.complex128'>, <class 'numpy.complex128'>)) of arguments for cupy_where\r\n\r\nFor `cp.float64`, everything works fine.\r\n\r\nCuPy Version          : 6.4.0\r\nCUDA Root             : /usr\r\nCUDA Build Version    : 8000\r\nCUDA Driver Version   : 10020\r\nCUDA Runtime Version  : 8000\r\ncuDNN Build Version   : 7102\r\ncuDNN Version         : 7102\r\nNCCL Build Version    : 2213\r\nNCCL Runtime Version  : (unknown)\n", "before_files": [{"content": "from cupy import core\nfrom cupy.core import fusion\n\n\ndef argmax(a, axis=None, dtype=None, out=None, keepdims=False):\n    \"\"\"Returns the indices of the maximum along an axis.\n\n    Args:\n        a (cupy.ndarray): Array to take argmax.\n        axis (int): Along which axis to find the maximum. ``a`` is flattened by\n            default.\n        dtype: Data type specifier.\n        out (cupy.ndarray): Output array.\n        keepdims (bool): If ``True``, the axis ``axis`` is preserved as an axis\n            of length one.\n\n    Returns:\n        cupy.ndarray: The indices of the maximum of ``a`` along an axis.\n\n    .. seealso:: :func:`numpy.argmax`\n\n    \"\"\"\n    # TODO(okuta): check type\n    return a.argmax(axis=axis, dtype=dtype, out=out, keepdims=keepdims)\n\n\n# TODO(okuta): Implement nanargmax\n\n\ndef argmin(a, axis=None, dtype=None, out=None, keepdims=False):\n    \"\"\"Returns the indices of the minimum along an axis.\n\n    Args:\n        a (cupy.ndarray): Array to take argmin.\n        axis (int): Along which axis to find the minimum. ``a`` is flattened by\n            default.\n        dtype: Data type specifier.\n        out (cupy.ndarray): Output array.\n        keepdims (bool): If ``True``, the axis ``axis`` is preserved as an axis\n            of length one.\n\n    Returns:\n        cupy.ndarray: The indices of the minimum of ``a`` along an axis.\n\n    .. seealso:: :func:`numpy.argmin`\n\n    \"\"\"\n    # TODO(okuta): check type\n    return a.argmin(axis=axis, dtype=dtype, out=out, keepdims=keepdims)\n\n\n# TODO(okuta): Implement nanargmin\n\n\n# TODO(okuta): Implement argwhere\n\n\ndef nonzero(a):\n    \"\"\"Return the indices of the elements that are non-zero.\n\n    Returns a tuple of arrays, one for each dimension of a,\n    containing the indices of the non-zero elements in that dimension.\n\n    Args:\n        a (cupy.ndarray): array\n\n    Returns:\n        tuple of arrays: Indices of elements that are non-zero.\n\n    .. seealso:: :func:`numpy.nonzero`\n\n    \"\"\"\n    assert isinstance(a, core.ndarray)\n    return a.nonzero()\n\n\ndef flatnonzero(a):\n    \"\"\"Return indices that are non-zero in the flattened version of a.\n\n    This is equivalent to a.ravel().nonzero()[0].\n\n    Args:\n        a (cupy.ndarray): input array\n\n    Returns:\n        cupy.ndarray: Output array,\n        containing the indices of the elements of a.ravel() that are non-zero.\n\n    .. seealso:: :func:`numpy.flatnonzero`\n    \"\"\"\n    assert isinstance(a, core.ndarray)\n    return a.ravel().nonzero()[0]\n\n\n_where_ufunc = core.create_ufunc(\n    'cupy_where',\n    ('???->?', '?bb->b', '?BB->B', '?hh->h', '?HH->H', '?ii->i', '?II->I',\n     '?ll->l', '?LL->L', '?qq->q', '?QQ->Q', '?ee->e', '?ff->f',\n     # On CUDA 6.5 these combinations don't work correctly (on CUDA >=7.0, it\n     # works).\n     # See issue #551.\n     '?hd->d', '?Hd->d',\n     '?dd->d'),\n    'out0 = in0 ? in1 : in2')\n\n\ndef where(condition, x=None, y=None):\n    \"\"\"Return elements, either from x or y, depending on condition.\n\n    If only condition is given, return ``condition.nonzero()``.\n\n    Args:\n        condition (cupy.ndarray): When True, take x, otherwise take y.\n        x (cupy.ndarray): Values from which to choose on ``True``.\n        y (cupy.ndarray): Values from which to choose on ``False``.\n\n    Returns:\n        cupy.ndarray: Each element of output contains elements of ``x`` when\n            ``condition`` is ``True``, otherwise elements of ``y``. If only\n            ``condition`` is given, return the tuple ``condition.nonzero()``,\n            the indices where ``condition`` is True.\n\n    .. seealso:: :func:`numpy.where`\n\n    \"\"\"\n\n    missing = (x is None, y is None).count(True)\n\n    if missing == 1:\n        raise ValueError('Must provide both \\'x\\' and \\'y\\' or neither.')\n    if missing == 2:\n        return nonzero(condition)\n\n    if fusion._is_fusing():\n        return fusion._call_ufunc(_where_ufunc, condition, x, y)\n    return _where_ufunc(condition.astype('?'), x, y)\n\n\n# TODO(okuta): Implement searchsorted\n\n\n# TODO(okuta): Implement extract\n", "path": "cupy/sorting/search.py"}], "after_files": [{"content": "from cupy import core\nfrom cupy.core import fusion\n\n\ndef argmax(a, axis=None, dtype=None, out=None, keepdims=False):\n    \"\"\"Returns the indices of the maximum along an axis.\n\n    Args:\n        a (cupy.ndarray): Array to take argmax.\n        axis (int): Along which axis to find the maximum. ``a`` is flattened by\n            default.\n        dtype: Data type specifier.\n        out (cupy.ndarray): Output array.\n        keepdims (bool): If ``True``, the axis ``axis`` is preserved as an axis\n            of length one.\n\n    Returns:\n        cupy.ndarray: The indices of the maximum of ``a`` along an axis.\n\n    .. seealso:: :func:`numpy.argmax`\n\n    \"\"\"\n    # TODO(okuta): check type\n    return a.argmax(axis=axis, dtype=dtype, out=out, keepdims=keepdims)\n\n\n# TODO(okuta): Implement nanargmax\n\n\ndef argmin(a, axis=None, dtype=None, out=None, keepdims=False):\n    \"\"\"Returns the indices of the minimum along an axis.\n\n    Args:\n        a (cupy.ndarray): Array to take argmin.\n        axis (int): Along which axis to find the minimum. ``a`` is flattened by\n            default.\n        dtype: Data type specifier.\n        out (cupy.ndarray): Output array.\n        keepdims (bool): If ``True``, the axis ``axis`` is preserved as an axis\n            of length one.\n\n    Returns:\n        cupy.ndarray: The indices of the minimum of ``a`` along an axis.\n\n    .. seealso:: :func:`numpy.argmin`\n\n    \"\"\"\n    # TODO(okuta): check type\n    return a.argmin(axis=axis, dtype=dtype, out=out, keepdims=keepdims)\n\n\n# TODO(okuta): Implement nanargmin\n\n\n# TODO(okuta): Implement argwhere\n\n\ndef nonzero(a):\n    \"\"\"Return the indices of the elements that are non-zero.\n\n    Returns a tuple of arrays, one for each dimension of a,\n    containing the indices of the non-zero elements in that dimension.\n\n    Args:\n        a (cupy.ndarray): array\n\n    Returns:\n        tuple of arrays: Indices of elements that are non-zero.\n\n    .. seealso:: :func:`numpy.nonzero`\n\n    \"\"\"\n    assert isinstance(a, core.ndarray)\n    return a.nonzero()\n\n\ndef flatnonzero(a):\n    \"\"\"Return indices that are non-zero in the flattened version of a.\n\n    This is equivalent to a.ravel().nonzero()[0].\n\n    Args:\n        a (cupy.ndarray): input array\n\n    Returns:\n        cupy.ndarray: Output array,\n        containing the indices of the elements of a.ravel() that are non-zero.\n\n    .. seealso:: :func:`numpy.flatnonzero`\n    \"\"\"\n    assert isinstance(a, core.ndarray)\n    return a.ravel().nonzero()[0]\n\n\n_where_ufunc = core.create_ufunc(\n    'cupy_where',\n    ('???->?', '?bb->b', '?BB->B', '?hh->h', '?HH->H', '?ii->i', '?II->I',\n     '?ll->l', '?LL->L', '?qq->q', '?QQ->Q', '?ee->e', '?ff->f',\n     # On CUDA 6.5 these combinations don't work correctly (on CUDA >=7.0, it\n     # works).\n     # See issue #551.\n     '?hd->d', '?Hd->d',\n     '?dd->d', '?FF->F', '?DD->D'),\n    'out0 = in0 ? in1 : in2')\n\n\ndef where(condition, x=None, y=None):\n    \"\"\"Return elements, either from x or y, depending on condition.\n\n    If only condition is given, return ``condition.nonzero()``.\n\n    Args:\n        condition (cupy.ndarray): When True, take x, otherwise take y.\n        x (cupy.ndarray): Values from which to choose on ``True``.\n        y (cupy.ndarray): Values from which to choose on ``False``.\n\n    Returns:\n        cupy.ndarray: Each element of output contains elements of ``x`` when\n            ``condition`` is ``True``, otherwise elements of ``y``. If only\n            ``condition`` is given, return the tuple ``condition.nonzero()``,\n            the indices where ``condition`` is True.\n\n    .. seealso:: :func:`numpy.where`\n\n    \"\"\"\n\n    missing = (x is None, y is None).count(True)\n\n    if missing == 1:\n        raise ValueError('Must provide both \\'x\\' and \\'y\\' or neither.')\n    if missing == 2:\n        return nonzero(condition)\n\n    if fusion._is_fusing():\n        return fusion._call_ufunc(_where_ufunc, condition, x, y)\n    return _where_ufunc(condition.astype('?'), x, y)\n\n\n# TODO(okuta): Implement searchsorted\n\n\n# TODO(okuta): Implement extract\n", "path": "cupy/sorting/search.py"}]}