def clone(self):
        """Return a heterograph object that is a clone of current graph.

        Returns
        -------
        DGLGraph
            The graph object that is a clone of current graph.
        """
        # XXX(minjie): Do a shallow copy first to clone some internal metagraph information.
        #   Not a beautiful solution though.
        ret = copy.copy(self)

        # Clone the graph structure
        meta_edges = []
        for s_ntype, _, d_ntype in self.canonical_etypes:
            meta_edges.append(
                (self.get_ntype_id(s_ntype), self.get_ntype_id(d_ntype))
            )

        metagraph = graph_index.from_edge_list(meta_edges, True)
        # rebuild graph idx
        num_nodes_per_type = [
            self.num_nodes(c_ntype) for c_ntype in self.ntypes
        ]
        relation_graphs = [
            self._graph.get_relation_graph(self.get_etype_id(c_etype))
            for c_etype in self.canonical_etypes
        ]
        ret._graph = heterograph_index.create_heterograph_from_relations(
            metagraph,
            relation_graphs,
            utils.toindex(num_nodes_per_type, "int64"),
        )

        # Clone the frames
        ret._node_frames = [fr.clone() for fr in self._node_frames]
        ret._edge_frames = [fr.clone() for fr in self._edge_frames]

        # Copy the batch information
        ret._batch_num_nodes = copy.copy(self._batch_num_nodes)
        ret._batch_num_edges = copy.copy(self._batch_num_edges)

        return ret
Return a heterograph object that is a clone of current graph.

        Returns
        -------
        DGLGraph
            The graph object that is a clone of current graph.
        
python/dgl/heterograph.py