class_docstr: Duck-typed version of the DGLHeteroGraph class made for cuGraph
  for storing graph structure and node/edge feature data.
  
  This object is wrapper around cugraph's Multi GPU MultiGraph and returns samples
  that conform with `DGLHeteroGraph`
  See: https://docs.rapids.ai/api/cugraph/nightly/api_docs/cugraph_dgl.html
class_docstr_tok: ["Duck-typed","version","of","the","DGLHeteroGraph","class","made","for","cuGraph","for","storing","graph","structure","and","node\/edge","feature","data",".","This","object","is","wrapper","around","cugraph","'s","Multi","GPU","MultiGraph","and","returns","samples","that","conform","with","`","DGLHeteroGraph","`","See",":","https",":","\/\/docs.rapids.ai\/api\/cugraph\/nightly\/api_docs\/cugraph_dgl.html"]
docstr: Return the source and destination node ID(s) given the edge ID(s).
  
  Parameters
  ----------
  eid : edge ID(s)
      The edge IDs. The allowed formats are:
  
      * ``int``: A single ID.
      * Int Tensor: Each element is an ID.
      The tensor must have the same device type
      and ID data type as the graph's.
      * iterable[int]: Each element is an ID.
  
  etype : Tuple[str, str, str]
      The type name of the edges.
      Can be omitted if the graph has only one type of edges.
  
  Returns
  -------
  Tensor
      The source node IDs of the edges.
      The i-th element is the source node ID of the i-th edge.
  Tensor
      The destination node IDs of the edges.
      The i-th element is the destination node ID of the i-th edge.
code: def find_edges(
      self,
      eid,
      etype: Optional[Tuple[str, str, str]] = None,
      output_device=None,
  ):
      """
      Return the source and destination node ID(s) given the edge ID(s).
  
      Parameters
      ----------
      eid : edge ID(s)
          The edge IDs. The allowed formats are:
  
          * ``int``: A single ID.
          * Int Tensor: Each element is an ID.
          The tensor must have the same device type
          and ID data type as the graph's.
          * iterable[int]: Each element is an ID.
  
      etype : Tuple[str, str, str]
          The type name of the edges.
          Can be omitted if the graph has only one type of edges.
  
      Returns
      -------
      Tensor
          The source node IDs of the edges.
          The i-th element is the source node ID of the i-th edge.
      Tensor
          The destination node IDs of the edges.
          The i-th element is the destination node ID of the i-th edge.
      """
  
      if etype:
          src_type, connection_type, dst_type = etype
      eid = self.dgl_e_id_to_cugraph_id(eid, etype)
      # TODO: implement below
      src, dst = self.find_edges(eid, etype)
      src = torch.as_tensor(src, device="cuda")
      dst = torch.as_tensor(dst, device="cuda")
      src = self.cugraph_n_id_to_dgl_id(src, src_type)
      dst = self.cugraph_n_id_to_dgl_id(dst, dst_type)
  
      return src, dst
  
imports: from __future__ import annotations
  from typing import Optional, Sequence, Tuple, Dict, Union
  from functools import cached_property
  from cugraph.utilities.utils import import_optional, MissingModule
  from cugraph.gnn import FeatureStore
  from cugraph.gnn.dgl_extensions.dgl_uniform_sampler import DGLUniformSampler
  import cudf
  import dask_cudf
  import cupy
  from cugraph_dgl.utils.cugraph_storage_utils import _assert_valid_canonical_etype, backend_dtype_to_np_dtype_dict, add_edge_ids_to_edges_dict, add_node_offset_to_edges_dict
  from cugraph_dgl.utils.feature_storage import dgl_FeatureStorage
label_desc: Use image node_id 7 for calling the CuGraphStorage obj's underlying member method code with example usage: obj.find_edges(eid, etype, output_device) and returns: src,  dst