code: def edge_type_subgraph(graph, etypes, output_device=None):
      """Return the subgraph induced on given edge types.
  
      An edge-type-induced subgraph contains all the edges of the given subset of
      the edge types of a graph. It also contains all nodes of a particular type
      if some nodes of the type are incident to these edges.
      In addition to extracting the subgraph, DGL also copies the features of the
      extracted nodes and edges to the resulting graph.
      The copy is *lazy* and incurs data movement only when needed.
  
      Parameters
      ----------
      graph : DGLGraph
          The graph to extract subgraphs from.
      etypes : list[str] or list[(str, str, str)]
          The type names of the edges in the subgraph. The allowed type name
          formats are:
  
          * ``(str, str, str)`` for source node type, edge type and destination node type.
          * or one ``str`` for the edge type name  if the name can uniquely identify a
            triplet format in the graph.
      output_device : Framework-specific device context object, optional
          The output device.  Default is the same as the input graph.
  
      Returns
      -------
      G : DGLGraph
          The subgraph.
  
      Notes
      -----
  
      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 example uses PyTorch backend.
  
      >>> import dgl
      >>> import torch
  
      Instantiate a heterograph.
  
      >>> g = dgl.heterograph({
      >>>     ('user', 'plays', 'game'): ([0, 1, 1, 2], [0, 0, 2, 1]),
      >>>     ('user', 'follows', 'user'): ([0, 1, 1], [1, 2, 2])
      >>> })
      >>> # Set edge features
      >>> g.edges['follows'].data['h'] = torch.tensor([[0.], [1.], [2.]])
  
      Get subgraphs.
  
      >>> sub_g = g.edge_type_subgraph(['follows'])
      >>> sub_g
      Graph(num_nodes=3, num_edges=3,
            ndata_schemes={}
            edata_schemes={'h': Scheme(shape=(1,), dtype=torch.float32)})
  
      Get the shared edge features.
  
      >>> sub_g.edges['follows'].data['h']
      tensor([[0.],
              [1.],
              [2.]])
  
      See Also
      --------
      node_type_subgraph
      """
      etype_ids = [graph.get_etype_id(etype) for etype in etypes]
      # meta graph is homogeneous graph, still using int64
      meta_src, meta_dst, _ = graph._graph.metagraph.find_edges(
          utils.toindex(etype_ids, "int64")
      )
      rel_graphs = [
          graph._graph.get_relation_graph(i) for i in etype_ids
      ]
      meta_src = meta_src.tonumpy()
      meta_dst = meta_dst.tonumpy()
      ntypes_invmap = {
          n: i for i, n in enumerate(set(meta_src) | set(meta_dst))
      }
      mapped_meta_src = [ntypes_invmap[v] for v in meta_src]
      mapped_meta_dst = [ntypes_invmap[v] for v in meta_dst]
      node_frames = [graph._node_frames[i] for i in ntypes_invmap]
      edge_frames = [graph._edge_frames[i] for i in etype_ids]
      induced_ntypes = [graph._ntypes[i] for i in ntypes_invmap]
      induced_etypes = [
          graph._etypes[i] for i in etype_ids
      ]  # get the "name" of edge type
      num_nodes_per_induced_type = [
          graph.num_nodes(ntype) for ntype in induced_ntypes
      ]
  
      metagraph = graph_index.from_edge_list(
          (mapped_meta_src, mapped_meta_dst), True
      )
      # num_nodes_per_type should be int64
      hgidx = heterograph_index.create_heterograph_from_relations(
          metagraph,
          rel_graphs,
          utils.toindex(num_nodes_per_induced_type, "int64"),
      )
      hg = DGLGraph(
          hgidx,
          induced_ntypes,
          induced_etypes,
          node_frames,
          edge_frames,
      )
      return hg if output_device is None else hg.to(output_device)
  
file_path: dgl/python/dgl/subgraph.py
imports: from collections.abc import Mapping
  from .None import backend, graph_index, heterograph_index, utils
  from ._ffi.function import _init_api
  from .base import DGLError
  from .heterograph import DGLGraph
  from .utils import context_of, recursive_apply
label_desc: Use image node_id 8 for calling a global function with example usage: edge_type_subgraph(graph, etypes, output_device) and returns: unknown