code: def to_bidirected(g, copy_ndata=False, readonly=None):
      r"""Convert the graph to a bi-directional simple graph and return.
  
      For an input graph :math:`G`, return a new graph :math:`G'` such that an edge
      :math:`(u, v)\in G'` exists if and only if there exists an edge
      :math:`(v, u)\in G`. The resulting graph :math:`G'` is a simple graph,
      meaning there is no parallel edge.
  
      The operation only works for edges whose two endpoints belong to the same node type.
      DGL will raise error if the input graph is heterogeneous and contains edges
      with different types of endpoints.
  
      Parameters
      ----------
      g : DGLGraph
          The input graph.
      copy_ndata: bool, optional
          If True, the node features of the bidirected graph are copied from the
          original graph. If False, the bidirected graph will not have any node features.
          (Default: False)
      readonly : bool
          **DEPRECATED**.
  
      Returns
      -------
      DGLGraph
          The bidirected graph
  
      Notes
      -----
      If :attr:`copy_ndata` is True, the resulting graph will share the node feature
      tensors with the input graph. Hence, users should try to avoid in-place operations
      which will be visible to both graphs.
  
      This function discards the batch information. Please use
      :func:`dgl.DGLGraph.set_batch_num_nodes`
      and :func:`dgl.DGLGraph.set_batch_num_edges` on the transformed graph
      to maintain the information.
  
      Examples
      --------
      The following examples use PyTorch backend.
  
      >>> import dgl
      >>> import torch as th
      >>> g = dgl.graph((th.tensor([0, 1, 2]), th.tensor([1, 2, 0])))
      >>> bg1 = dgl.to_bidirected(g)
      >>> bg1.edges()
      (tensor([0, 1, 2, 1, 2, 0]), tensor([1, 2, 0, 0, 1, 2]))
  
      The graph already have i->j and j->i
  
      >>> g = dgl.graph((th.tensor([0, 1, 2, 0]), th.tensor([1, 2, 0, 2])))
      >>> bg1 = dgl.to_bidirected(g)
      >>> bg1.edges()
      (tensor([0, 1, 2, 1, 2, 0]), tensor([1, 2, 0, 0, 1, 2]))
  
      **Heterogeneous graphs with Multiple Edge Types**
  
      >>> g = dgl.heterograph({
      ...     ('user', 'wins', 'user'): (th.tensor([0, 2, 0, 2]), th.tensor([1, 1, 2, 0])),
      ...     ('user', 'follows', 'user'): (th.tensor([1, 2, 1]), th.tensor([2, 1, 1]))
      ... })
      >>> bg1 = dgl.to_bidirected(g)
      >>> bg1.edges(etype='wins')
      (tensor([0, 0, 1, 1, 2, 2]), tensor([1, 2, 0, 2, 0, 1]))
      >>> bg1.edges(etype='follows')
      (tensor([1, 1, 2]), tensor([1, 2, 1]))
      """
      if readonly is not None:
          dgl_warning(
              "Parameter readonly is deprecated"
              "There will be no difference between readonly and non-readonly DGLGraph"
          )
  
      for c_etype in g.canonical_etypes:
          if c_etype[0] != c_etype[2]:
              assert False, (
                  "to_bidirected is not well defined for "
                  "unidirectional bipartite graphs"
                  ", but {} is unidirectional bipartite".format(c_etype)
              )
  
      g = add_reverse_edges(g, copy_ndata=copy_ndata, copy_edata=False)
      g = to_simple(
          g, return_counts=None, copy_ndata=copy_ndata, copy_edata=False
      )
      return g
  
imports: import copy
  from collections.abc import Iterable, Mapping
  import numpy
  import scipy.sparse
  import scipy.sparse.linalg
  from ..utils import version
  from ..None import backend, batch, convert, function, ndarray, subgraph, utils
  from .._ffi.function import _init_api
  from ..base import dgl_warning, DGLError, EID, NID
  from ..frame import Frame
  from ..heterograph import DGLGraph
  from ..heterograph_index import create_heterograph_from_relations, create_metagraph_index
  from ..partition import metis_partition, metis_partition_assignment, partition_graph_with_halo
  from ..sampling.neighbor import sample_neighbors
label_desc: Use image node_id 8 for calling a global function with example usage: to_bidirected(g, copy_ndata, readonly) and returns: g