code: def gsddmm(g, op, lhs_data, rhs_data, lhs_target="u", rhs_target="v"):
      r"""Generalized Sampled-Dense-Dense Matrix Multiplication interface.
      It computes edge features by :attr:`op` lhs features and rhs features.
  
      .. math::
  
          x_{e} = \phi(x_{lhs}, x_{rhs}), \forall (u,e,v)\in \mathcal{G}
  
      where :math:`x_{e}` is the returned feature on edges and :math:`x_u`,
      :math:`x_v` refers to :attr:`u`, :attr:`v` respectively. :math:`\phi`
      is the binary operator :attr:`op`, and :math:`\mathcal{G}` is the graph
      we apply gsddmm on: :attr:`g`. :math:`lhs` and :math:`rhs` are one of
      :math:`u,v,e`'s.
  
      Parameters
      ----------
      g : DGLGraph
          The input graph.
      op : str
          Binary operator, could be ``add``, ``sub``, ``mul``, ``div``, ``dot``,
          ``copy_lhs``, ``copy_rhs``.
      lhs_data : tensor or None
          The left operand, could be None if it's not required by op.
      rhs_data : tensor or None
          The right operand, could be None if it's not required by op.
      lhs_target: str
          Choice of ``u``(source), ``e``(edge) or ``v``(destination) for left operand.
      rhs_target: str
          Choice of ``u``(source), ``e``(edge) or ``v``(destination) for right operand.
  
      Returns
      -------
      tensor
          The result tensor.
      """
      if g._graph.number_of_etypes() == 1:
          if op not in ["copy_lhs", "copy_rhs"]:
              lhs_data, rhs_data = reshape_lhs_rhs(lhs_data, rhs_data)
          return gsddmm_internal(
              g._graph, op, lhs_data, rhs_data, lhs_target, rhs_target
          )
      else:
          if op == "copy_lhs":
              rhs_data = [None] * g._graph.number_of_etypes()
          elif op == "copy_rhs":
              lhs_data = [None] * g._graph.number_of_ntypes()
          # TODO (Israt): Call reshape_lhs_rhs() on lhs and rhs data to match their dimension
          # and avoid broadcasting issue. Handle the case where different nodes have
          # different dimensions, and different etypes may need different broadcasting
          # dims for the same node.
          lhs_and_rhs_tuple = tuple(list(lhs_data) + list(rhs_data))
          return gsddmm_internal_hetero(
              g._graph,
              op,
              len(lhs_data),
              lhs_target,
              rhs_target,
              *lhs_and_rhs_tuple,
          )
  
file_path: dgl/python/dgl/ops/sddmm.py
imports: import sys
  from itertools import product
  from ..None import backend
  from ..backend import gsddmm, gsddmm_hetero
label_desc: Use image node_id 2 for calling a global function with example usage: gsddmm(g, op, lhs_data, rhs_data, lhs_target, rhs_target) and returns: gsddmm_internal, gsddmm_internal_hetero