code: def _gsddmm(gidx, op, lhs, rhs, lhs_target="u", rhs_target="v"):
      r"""Generalized Sampled-Dense-Dense Matrix Multiplication interface. It
      takes the result of :attr:`op` on source node feature and destination node
      feature, leads to a feature on edge.
  
      .. math::
          x_{e} = \phi(x_u, x_e, x_v), \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`.
  
      Parameters
      ----------
      gidx : HeteroGraphIndex
          The input graph index.
      op : str
          Binary operator, could be ``add``, ``sub``, ``mul``, ``div``, ``dot``,
          ``copy_lhs``, ``copy_rhs``.
      lhs : tensor or None
          Left hand operand.
      rhs : tensor or None
          Right hand operand.
      lhs_target : str
          The target of left hand operand, could be ``src``, ``edge``, ``dst``
          or their alias ``u``, ``e``, ``v``.
      rhs_target : str
          The target of right hand operand, could be ``src``, ``edge``, ``dst``
          or their alias ``u``, ``e``, ``v``.
  
      Returns
      -------
      tensor
          The result tensor.
  
      Notes
      -----
      This function does not handle gradients.
      """
      if gidx.number_of_etypes() != 1:
          raise DGLError(
              "We only support gsddmm on graph with one edge type"
          )
      use_lhs = op != "copy_rhs"
      use_rhs = op != "copy_lhs"
      if use_lhs and use_rhs:
          if F.dtype(lhs) != F.dtype(rhs):
              raise DGLError(
                  "The operands data type don't match: {} and {}, please convert them"
                  " to the same type.".format(
                      F.dtype(lhs), F.dtype(rhs)
                  )
              )
      # deal with scalar features.
      expand_lhs, expand_rhs = False, False
      if use_lhs:
          if F.ndim(lhs) == 1:
              lhs = F.unsqueeze(lhs, -1)
              expand_lhs = True
      if use_rhs:
          if F.ndim(rhs) == 1:
              rhs = F.unsqueeze(rhs, -1)
              expand_rhs = True
      lhs_target = target_mapping[lhs_target]
      rhs_target = target_mapping[rhs_target]
  
      ctx = F.context(lhs) if use_lhs else F.context(rhs)
      dtype = F.dtype(lhs) if use_lhs else F.dtype(rhs)
      lhs_shp = F.shape(lhs) if use_lhs else (0,)
      rhs_shp = F.shape(rhs) if use_rhs else (0,)
      out_shp = (gidx.num_edges(0),) + infer_broadcast_shape(
          op, lhs_shp[1:], rhs_shp[1:]
      )
      out = F.empty(out_shp, dtype, ctx)
      if gidx.num_edges(0) > 0:
          _CAPI_DGLKernelSDDMM(
              gidx,
              op,
              to_dgl_nd(lhs if use_lhs else None),
              to_dgl_nd(rhs if use_rhs else None),
              to_dgl_nd_for_write(out),
              lhs_target,
              rhs_target,
          )
      if (expand_lhs or not use_lhs) and (expand_rhs or not use_rhs):
          out = F.squeeze(out, -1)
      return out
  
imports: from __future__ import absolute_import
  from .None import backend, ndarray
  from ._ffi.function import _init_api
  from .base import DGLError
label_desc: Use image node_id 13 for calling a global function with example usage: _gsddmm(gidx, op, lhs, rhs, lhs_target, rhs_target) and returns: out