code: def bfs(
      G,
      start=None,
      depth_limit=None,
      i_start=None,
      directed=None,
      return_predecessors=True,
  ):
      """
      Find the distances and predecessors for a breadth first traversal of a
      graph.  Unlike SSSP, BFS supports unweighted graphs.
  
      Parameters
      ----------
      G : cugraph.Graph, networkx.Graph, CuPy or SciPy sparse matrix
          Graph or matrix object, which should contain the connectivity
          information. Edge weights, if present, should be single or double
          precision floating point values.
  
      start : Integer or list, optional (default=None)
          The id of the graph vertex from which the traversal begins, or
          if a list, the vertex from which the traversal begins in each
          component of the graph.  Only one vertex per connected
          component of the graph is allowed.
  
      depth_limit : Integer or None, optional (default=None)
          Limit the depth of the search
  
      i_start : Integer, optional (default=None)
          Identical to start, added for API compatibility. Only start or i_start
          can be set, not both.
  
      directed : bool, optional (default=None)
          NOTE
              For non-Graph-type (eg. sparse matrix) values of G only. Raises
              TypeError if used with a Graph object.
  
          If True, then convert the input matrix to a directed cugraph.Graph,
          otherwise an undirected cugraph.Graph object will be used.
  
      return_predecessors : bool, optional (default=True)
          Whether to return the predecessors for each vertex (returns -1
          for each vertex otherwise)
  
      Returns
      -------
      Return value type is based on the input type.  If G is a cugraph.Graph,
      returns:
  
         cudf.DataFrame
            df['vertex'] vertex IDs
  
            df['distance'] path distance for each vertex from the starting vertex
  
            df['predecessor'] for each i'th position in the column, the vertex ID
            immediately preceding the vertex at position i in the 'vertex' column
  
      If G is a networkx.Graph, returns:
  
         pandas.DataFrame with contents equivalent to the cudf.DataFrame
         described above.
  
      If G is a CuPy or SciPy matrix, returns:
         a 2-tuple of CuPy ndarrays (if CuPy matrix input) or Numpy ndarrays (if
         SciPy matrix input) representing:
  
         distance: cupy or numpy ndarray
            ndarray of shortest distances between source and vertex.
  
         predecessor: cupy or numpy ndarray
            ndarray of predecessors of a vertex on the path from source, which
            can be used to reconstruct the shortest paths.
  
         ...or if return_sp_counter is True, returns a 3-tuple with the above two
         arrays plus:
  
         sp_counter: cupy or numpy ndarray
            ndarray of number of shortest paths leading to each vertex.
  
      Examples
      --------
      >>> from cugraph.datasets import karate
      >>> G = karate.get_graph(download=True)
      >>> df = cugraph.bfs(G, 0)
  
      """
      (start, directed) = _ensure_args(G, start, i_start, directed)
  
      # FIXME: allow nx_weight_attr to be specified
      (G, input_type) = ensure_cugraph_obj(
          G,
          nx_weight_attr="weight",
          matrix_graph_type=Graph(directed=directed),
      )
  
      # The BFS C++ extension assumes the start vertex is a cudf.Series object,
      # and operates on internal vertex IDs if renumbered.
      is_dataframe = isinstance(start, cudf.DataFrame) or isinstance(
          start, dask_cudf.DataFrame
      )
      if G.renumbered is True:
          if is_dataframe:
              start = G.lookup_internal_vertex_id(start, start.columns)
          else:
              start = G.lookup_internal_vertex_id(cudf.Series(start))
  
      else:
          if is_dataframe:
              start = start[start.columns[0]]
          else:
              vertex_dtype = G.nodes().dtype
              start = cudf.Series(start, dtype=vertex_dtype)
  
      distances, predecessors, vertices = pylibcugraph_bfs(
          handle=ResourceHandle(),
          graph=G._plc_graph,
          sources=start,
          direction_optimizing=False,
          depth_limit=depth_limit if depth_limit is not None else -1,
          compute_predecessors=return_predecessors,
          do_expensive_check=False,
      )
  
      result_df = cudf.DataFrame(
          {
              "vertex": cudf.Series(vertices),
              "distance": cudf.Series(distances),
              "predecessor": cudf.Series(predecessors),
          }
      )
  
      if G.renumbered:
          result_df = G.unrenumber(result_df, "vertex")
          result_df = G.unrenumber(result_df, "predecessor")
          result_df.fillna(-1, inplace=True)
  
      return _convert_df_to_output_type(result_df, input_type)
  
file_path: cugraph/python/cugraph/cugraph/traversal/bfs.py
imports: import cudf
  import dask_cudf
  from pylibcugraph import ResourceHandle
  from pylibcugraph import bfs
  from cugraph.structure.graph_classes import Graph
  from cugraph.utilities import ensure_cugraph_obj, is_matrix_type, is_cp_matrix_type, is_nx_graph_type, cupy_package
label_desc: Use image node_id 3 for calling a global function with example usage: bfs(G, start, depth_limit, i_start, directed, return_predecessors) and returns: _convert_df_to_output_type