prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Fix `cupyx.scipy.sparse.csgraph` module to work with the latest RAPIDS cuGraph
  Follow the API change introduced in RAPIDS 22.12.
  https://github.com/cupy/cupy/pull/7647#discussion_r1244820097
  
  cc/ @pentschev 
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `cupyx/scipy/sparse/csgraph/_traversal.py`
  Content:
  ```
  1 import cupy
  2 import cupyx.scipy.sparse
  3 try:
  4     import pylibcugraph
  5     pylibcugraph_available = True
  6 except ModuleNotFoundError:
  7     pylibcugraph_available = False
  8 
  9 
  10 def connected_components(csgraph, directed=True, connection='weak',
  11                          return_labels=True):
  12     """Analyzes the connected components of a sparse graph
  13 
  14     Args:
  15         csgraph (cupy.ndarray of cupyx.scipy.sparse.csr_matrix): The adjacency
  16             matrix representing connectivity among nodes.
  17         directed (bool): If ``True``, it operates on a directed graph. If
  18             ``False``, it operates on an undirected graph.
  19         connection (str): ``'weak'`` or ``'strong'``. For directed graphs, the
  20             type of connection to use. Nodes i and j are "strongly" connected
  21             only when a path exists both from i to j and from j to i.
  22             If ``directed`` is ``False``, this argument is ignored.
  23         return_labels (bool): If ``True``, it returns the labels for each of
  24             the connected components.
  25 
  26     Returns:
  27         tuple of int and cupy.ndarray, or int:
  28             If ``return_labels`` == ``True``, returns a tuple ``(n, labels)``,
  29             where ``n`` is the number of connected components and ``labels`` is
  30             labels of each connected components. Otherwise, returns ``n``.
  31 
  32     .. seealso:: :func:`scipy.sparse.csgraph.connected_components`
  33     """
  34     if not pylibcugraph_available:
  35         raise RuntimeError('pylibcugraph is not available')
  36 
  37     connection = connection.lower()
  38     if connection not in ('weak', 'strong'):
  39         raise ValueError("connection must be 'weak' or 'strong'")
  40 
  41     if not directed:
  42         connection = 'weak'
  43 
  44     if csgraph.ndim != 2:
  45         raise ValueError('graph should have two dimensions')
  46 
  47     if not cupyx.scipy.sparse.isspmatrix_csr(csgraph):
  48         csgraph = cupyx.scipy.sparse.csr_matrix(csgraph)
  49     m, m1 = csgraph.shape
  50     if m != m1:
  51         raise ValueError('graph should be a square array')
  52     if csgraph.nnz == 0:
  53         return m, cupy.arange(m, dtype=csgraph.indices.dtype)
  54     labels = cupy.empty(m, dtype=csgraph.indices.dtype)
  55 
  56     if connection == 'strong':
  57         pylibcugraph.strongly_connected_components(
  58             offsets=csgraph.indptr, indices=csgraph.indices, weights=None,
  59             num_verts=m, num_edges=csgraph.nnz, labels=labels)
  60     else:
  61         csgraph += csgraph.T
  62         if not cupyx.scipy.sparse.isspmatrix_csr(csgraph):
  63             csgraph = cupyx.scipy.sparse.csr_matrix(csgraph)
  64         pylibcugraph.weakly_connected_components(
  65             offsets=csgraph.indptr, indices=csgraph.indices, weights=None,
  66             num_verts=m, num_edges=csgraph.nnz, labels=labels)
  67         # Note: In the case of weak connection, cuGraph creates labels with a
  68         # start number of 1, so decrement the label number.
  69         labels -= 1
  70 
  71     count = cupy.zeros((1,), dtype=csgraph.indices.dtype)
  72     root_labels = cupy.empty((m,), dtype=csgraph.indices.dtype)
  73     _cupy_count_components(labels, count, root_labels, size=m)
  74     n = int(count[0])
  75     if not return_labels:
  76         return n
  77     _cupy_adjust_labels(n, cupy.sort(root_labels[:n]), labels)
  78     return n, labels
  79 
  80 
  81 _cupy_count_components = cupy.ElementwiseKernel(
  82     '',
  83     'raw I labels, raw int32 count, raw int32 root_labels',
  84     '''
  85     int j = i;
  86     while (j != labels[j]) { j = labels[j]; }
  87     if (j != i) {
  88         labels[i] = j;
  89     } else {
  90         int k = atomicAdd(&count[0], 1);
  91         root_labels[k] = i;
  92     }
  93     ''',
  94     '_cupy_count_components')
  95 
  96 
  97 _cupy_adjust_labels = cupy.ElementwiseKernel(
  98     'int32 n_root_labels, raw I root_labels',
  99     'I labels',
  100     '''
  101     int cur_label = labels;
  102     int j_min = 0;
  103     int j_max = n_root_labels - 1;
  104     int j = (j_min + j_max) / 2;
  105     while (j_min < j_max) {
  106         if (cur_label == root_labels[j]) break;
  107         if (cur_label < root_labels[j]) {
  108             j_max = j - 1;
  109         } else {
  110             j_min = j + 1;
  111         }
  112         j = (j_min + j_max) / 2;
  113     }
  114     labels = j;
  115     ''',
  116     '_cupy_adjust_labels')
  117
  ```
  --- 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/cupyx/scipy/sparse/csgraph/_traversal.py b/cupyx/scipy/sparse/csgraph/_traversal.py
  --- a/cupyx/scipy/sparse/csgraph/_traversal.py
  +++ b/cupyx/scipy/sparse/csgraph/_traversal.py
  @@ -51,9 +51,9 @@
           raise ValueError('graph should be a square array')
       if csgraph.nnz == 0:
           return m, cupy.arange(m, dtype=csgraph.indices.dtype)
  -    labels = cupy.empty(m, dtype=csgraph.indices.dtype)
   
       if connection == 'strong':
  +        labels = cupy.empty(m, dtype=csgraph.indices.dtype)
           pylibcugraph.strongly_connected_components(
               offsets=csgraph.indptr, indices=csgraph.indices, weights=None,
               num_verts=m, num_edges=csgraph.nnz, labels=labels)
  @@ -61,12 +61,15 @@
           csgraph += csgraph.T
           if not cupyx.scipy.sparse.isspmatrix_csr(csgraph):
               csgraph = cupyx.scipy.sparse.csr_matrix(csgraph)
  -        pylibcugraph.weakly_connected_components(
  -            offsets=csgraph.indptr, indices=csgraph.indices, weights=None,
  -            num_verts=m, num_edges=csgraph.nnz, labels=labels)
  -        # Note: In the case of weak connection, cuGraph creates labels with a
  -        # start number of 1, so decrement the label number.
  -        labels -= 1
  +        _, labels = pylibcugraph.weakly_connected_components(
  +            resource_handle=None,
  +            graph=None,
  +            indices=csgraph.indices,
  +            offsets=csgraph.indptr,
  +            weights=None,
  +            labels=None,
  +            do_expensive_check=False,
  +        )
   
       count = cupy.zeros((1,), dtype=csgraph.indices.dtype)
       root_labels = cupy.empty((m,), dtype=csgraph.indices.dtype)
  
verification_info: {"golden_diff": "diff --git a/cupyx/scipy/sparse/csgraph/_traversal.py b/cupyx/scipy/sparse/csgraph/_traversal.py\n--- a/cupyx/scipy/sparse/csgraph/_traversal.py\n+++ b/cupyx/scipy/sparse/csgraph/_traversal.py\n@@ -51,9 +51,9 @@\n         raise ValueError('graph should be a square array')\n     if csgraph.nnz == 0:\n         return m, cupy.arange(m, dtype=csgraph.indices.dtype)\n-    labels = cupy.empty(m, dtype=csgraph.indices.dtype)\n \n     if connection == 'strong':\n+        labels = cupy.empty(m, dtype=csgraph.indices.dtype)\n         pylibcugraph.strongly_connected_components(\n             offsets=csgraph.indptr, indices=csgraph.indices, weights=None,\n             num_verts=m, num_edges=csgraph.nnz, labels=labels)\n@@ -61,12 +61,15 @@\n         csgraph += csgraph.T\n         if not cupyx.scipy.sparse.isspmatrix_csr(csgraph):\n             csgraph = cupyx.scipy.sparse.csr_matrix(csgraph)\n-        pylibcugraph.weakly_connected_components(\n-            offsets=csgraph.indptr, indices=csgraph.indices, weights=None,\n-            num_verts=m, num_edges=csgraph.nnz, labels=labels)\n-        # Note: In the case of weak connection, cuGraph creates labels with a\n-        # start number of 1, so decrement the label number.\n-        labels -= 1\n+        _, labels = pylibcugraph.weakly_connected_components(\n+            resource_handle=None,\n+            graph=None,\n+            indices=csgraph.indices,\n+            offsets=csgraph.indptr,\n+            weights=None,\n+            labels=None,\n+            do_expensive_check=False,\n+        )\n \n     count = cupy.zeros((1,), dtype=csgraph.indices.dtype)\n     root_labels = cupy.empty((m,), dtype=csgraph.indices.dtype)\n", "issue": "Fix `cupyx.scipy.sparse.csgraph` module to work with the latest RAPIDS cuGraph\nFollow the API change introduced in RAPIDS 22.12.\r\nhttps://github.com/cupy/cupy/pull/7647#discussion_r1244820097\r\n\r\ncc/ @pentschev \n", "before_files": [{"content": "import cupy\nimport cupyx.scipy.sparse\ntry:\n    import pylibcugraph\n    pylibcugraph_available = True\nexcept ModuleNotFoundError:\n    pylibcugraph_available = False\n\n\ndef connected_components(csgraph, directed=True, connection='weak',\n                         return_labels=True):\n    \"\"\"Analyzes the connected components of a sparse graph\n\n    Args:\n        csgraph (cupy.ndarray of cupyx.scipy.sparse.csr_matrix): The adjacency\n            matrix representing connectivity among nodes.\n        directed (bool): If ``True``, it operates on a directed graph. If\n            ``False``, it operates on an undirected graph.\n        connection (str): ``'weak'`` or ``'strong'``. For directed graphs, the\n            type of connection to use. Nodes i and j are \"strongly\" connected\n            only when a path exists both from i to j and from j to i.\n            If ``directed`` is ``False``, this argument is ignored.\n        return_labels (bool): If ``True``, it returns the labels for each of\n            the connected components.\n\n    Returns:\n        tuple of int and cupy.ndarray, or int:\n            If ``return_labels`` == ``True``, returns a tuple ``(n, labels)``,\n            where ``n`` is the number of connected components and ``labels`` is\n            labels of each connected components. Otherwise, returns ``n``.\n\n    .. seealso:: :func:`scipy.sparse.csgraph.connected_components`\n    \"\"\"\n    if not pylibcugraph_available:\n        raise RuntimeError('pylibcugraph is not available')\n\n    connection = connection.lower()\n    if connection not in ('weak', 'strong'):\n        raise ValueError(\"connection must be 'weak' or 'strong'\")\n\n    if not directed:\n        connection = 'weak'\n\n    if csgraph.ndim != 2:\n        raise ValueError('graph should have two dimensions')\n\n    if not cupyx.scipy.sparse.isspmatrix_csr(csgraph):\n        csgraph = cupyx.scipy.sparse.csr_matrix(csgraph)\n    m, m1 = csgraph.shape\n    if m != m1:\n        raise ValueError('graph should be a square array')\n    if csgraph.nnz == 0:\n        return m, cupy.arange(m, dtype=csgraph.indices.dtype)\n    labels = cupy.empty(m, dtype=csgraph.indices.dtype)\n\n    if connection == 'strong':\n        pylibcugraph.strongly_connected_components(\n            offsets=csgraph.indptr, indices=csgraph.indices, weights=None,\n            num_verts=m, num_edges=csgraph.nnz, labels=labels)\n    else:\n        csgraph += csgraph.T\n        if not cupyx.scipy.sparse.isspmatrix_csr(csgraph):\n            csgraph = cupyx.scipy.sparse.csr_matrix(csgraph)\n        pylibcugraph.weakly_connected_components(\n            offsets=csgraph.indptr, indices=csgraph.indices, weights=None,\n            num_verts=m, num_edges=csgraph.nnz, labels=labels)\n        # Note: In the case of weak connection, cuGraph creates labels with a\n        # start number of 1, so decrement the label number.\n        labels -= 1\n\n    count = cupy.zeros((1,), dtype=csgraph.indices.dtype)\n    root_labels = cupy.empty((m,), dtype=csgraph.indices.dtype)\n    _cupy_count_components(labels, count, root_labels, size=m)\n    n = int(count[0])\n    if not return_labels:\n        return n\n    _cupy_adjust_labels(n, cupy.sort(root_labels[:n]), labels)\n    return n, labels\n\n\n_cupy_count_components = cupy.ElementwiseKernel(\n    '',\n    'raw I labels, raw int32 count, raw int32 root_labels',\n    '''\n    int j = i;\n    while (j != labels[j]) { j = labels[j]; }\n    if (j != i) {\n        labels[i] = j;\n    } else {\n        int k = atomicAdd(&count[0], 1);\n        root_labels[k] = i;\n    }\n    ''',\n    '_cupy_count_components')\n\n\n_cupy_adjust_labels = cupy.ElementwiseKernel(\n    'int32 n_root_labels, raw I root_labels',\n    'I labels',\n    '''\n    int cur_label = labels;\n    int j_min = 0;\n    int j_max = n_root_labels - 1;\n    int j = (j_min + j_max) / 2;\n    while (j_min < j_max) {\n        if (cur_label == root_labels[j]) break;\n        if (cur_label < root_labels[j]) {\n            j_max = j - 1;\n        } else {\n            j_min = j + 1;\n        }\n        j = (j_min + j_max) / 2;\n    }\n    labels = j;\n    ''',\n    '_cupy_adjust_labels')\n", "path": "cupyx/scipy/sparse/csgraph/_traversal.py"}], "after_files": [{"content": "import cupy\nimport cupyx.scipy.sparse\ntry:\n    import pylibcugraph\n    pylibcugraph_available = True\nexcept ModuleNotFoundError:\n    pylibcugraph_available = False\n\n\ndef connected_components(csgraph, directed=True, connection='weak',\n                         return_labels=True):\n    \"\"\"Analyzes the connected components of a sparse graph\n\n    Args:\n        csgraph (cupy.ndarray of cupyx.scipy.sparse.csr_matrix): The adjacency\n            matrix representing connectivity among nodes.\n        directed (bool): If ``True``, it operates on a directed graph. If\n            ``False``, it operates on an undirected graph.\n        connection (str): ``'weak'`` or ``'strong'``. For directed graphs, the\n            type of connection to use. Nodes i and j are \"strongly\" connected\n            only when a path exists both from i to j and from j to i.\n            If ``directed`` is ``False``, this argument is ignored.\n        return_labels (bool): If ``True``, it returns the labels for each of\n            the connected components.\n\n    Returns:\n        tuple of int and cupy.ndarray, or int:\n            If ``return_labels`` == ``True``, returns a tuple ``(n, labels)``,\n            where ``n`` is the number of connected components and ``labels`` is\n            labels of each connected components. Otherwise, returns ``n``.\n\n    .. seealso:: :func:`scipy.sparse.csgraph.connected_components`\n    \"\"\"\n    if not pylibcugraph_available:\n        raise RuntimeError('pylibcugraph is not available')\n\n    connection = connection.lower()\n    if connection not in ('weak', 'strong'):\n        raise ValueError(\"connection must be 'weak' or 'strong'\")\n\n    if not directed:\n        connection = 'weak'\n\n    if csgraph.ndim != 2:\n        raise ValueError('graph should have two dimensions')\n\n    if not cupyx.scipy.sparse.isspmatrix_csr(csgraph):\n        csgraph = cupyx.scipy.sparse.csr_matrix(csgraph)\n    m, m1 = csgraph.shape\n    if m != m1:\n        raise ValueError('graph should be a square array')\n    if csgraph.nnz == 0:\n        return m, cupy.arange(m, dtype=csgraph.indices.dtype)\n\n    if connection == 'strong':\n        labels = cupy.empty(m, dtype=csgraph.indices.dtype)\n        pylibcugraph.strongly_connected_components(\n            offsets=csgraph.indptr, indices=csgraph.indices, weights=None,\n            num_verts=m, num_edges=csgraph.nnz, labels=labels)\n    else:\n        csgraph += csgraph.T\n        if not cupyx.scipy.sparse.isspmatrix_csr(csgraph):\n            csgraph = cupyx.scipy.sparse.csr_matrix(csgraph)\n        _, labels = pylibcugraph.weakly_connected_components(\n            resource_handle=None,\n            graph=None,\n            indices=csgraph.indices,\n            offsets=csgraph.indptr,\n            weights=None,\n            labels=None,\n            do_expensive_check=False,\n        )\n\n    count = cupy.zeros((1,), dtype=csgraph.indices.dtype)\n    root_labels = cupy.empty((m,), dtype=csgraph.indices.dtype)\n    _cupy_count_components(labels, count, root_labels, size=m)\n    n = int(count[0])\n    if not return_labels:\n        return n\n    _cupy_adjust_labels(n, cupy.sort(root_labels[:n]), labels)\n    return n, labels\n\n\n_cupy_count_components = cupy.ElementwiseKernel(\n    '',\n    'raw I labels, raw int32 count, raw int32 root_labels',\n    '''\n    int j = i;\n    while (j != labels[j]) { j = labels[j]; }\n    if (j != i) {\n        labels[i] = j;\n    } else {\n        int k = atomicAdd(&count[0], 1);\n        root_labels[k] = i;\n    }\n    ''',\n    '_cupy_count_components')\n\n\n_cupy_adjust_labels = cupy.ElementwiseKernel(\n    'int32 n_root_labels, raw I root_labels',\n    'I labels',\n    '''\n    int cur_label = labels;\n    int j_min = 0;\n    int j_max = n_root_labels - 1;\n    int j = (j_min + j_max) / 2;\n    while (j_min < j_max) {\n        if (cur_label == root_labels[j]) break;\n        if (cur_label < root_labels[j]) {\n            j_max = j - 1;\n        } else {\n            j_min = j + 1;\n        }\n        j = (j_min + j_max) / 2;\n    }\n    labels = j;\n    ''',\n    '_cupy_adjust_labels')\n", "path": "cupyx/scipy/sparse/csgraph/_traversal.py"}]}