prompt: 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()
  
  ```
  
golden_diff: 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')
  
verification_info: {"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"}]}