code: def gsddmm_real(gidx, op, X, Y, lhs_target, rhs_target):
      out = _gsddmm(gidx, op, X, Y, lhs_target, rhs_target)
  
      def grad(dZ):
          if op != "copy_rhs":
              if lhs_target in ["u", "v"]:
                  _gidx = gidx if lhs_target == "v" else gidx.reverse()
                  if op in ["add", "sub", "copy_lhs"]:
                      dX = _gspmm(_gidx, "copy_rhs", "sum", None, dZ)[0]
                  else:  # mul, div, dot
                      if rhs_target == lhs_target:
                          dX = _gspmm(
                              _gidx, "copy_rhs", "sum", None, dZ
                          )[0] * _muldiv(op, Y)
                      elif rhs_target == "e":
                          dX = _gspmm(
                              _gidx,
                              "copy_rhs",
                              "sum",
                              None,
                              dZ * _muldiv(op, Y),
                          )[0]
                      else:  # rhs_target = !lhs_target
                          dX = _gspmm(
                              _gidx, "mul", "sum", _muldiv(op, Y), dZ
                          )[0]
              else:  # lhs_target == 'e'
                  if op in ["add", "sub", "copy_lhs"]:
                      dX = dZ
                  else:  # mul, div, dot
                      dX = _gsddmm(
                          gidx,
                          "mul",
                          dZ,
                          _muldiv(op, Y),
                          "e",
                          rhs_target,
                      )
              dX = _reduce_grad(dX, X.shape)
          else:
              dX = tf.zeros_like(X)
          if op != "copy_lhs":
              if rhs_target in ["u", "v"]:
                  _gidx = gidx if rhs_target == "v" else gidx.reverse()
                  if op in ["add", "sub", "copy_rhs"]:
                      dY = _gspmm(
                          _gidx,
                          "copy_rhs",
                          "sum",
                          None,
                          _addsub(op, dZ),
                      )[0]
                  else:  # mul, div, dot
                      if lhs_target == rhs_target:
                          dY = (
                              _gspmm(
                                  _gidx, "copy_rhs", "sum", None, dZ
                              )[0]
                              * X
                          )
                      elif lhs_target == "e":
                          dY = _gspmm(
                              _gidx, "copy_rhs", "sum", None, dZ * X
                          )[0]
                      else:  # rhs_target = !lhs_target
                          dY = _gspmm(_gidx, "mul", "sum", X, dZ)[0]
                      if op == "div":
                          dY = -dY / (Y**2)
              else:
                  if op in ["add", "sub", "copy_rhs"]:
                      dY = _addsub(op, dZ)
                  else:  # mul, div, dot
                      dY = _gsddmm(gidx, "mul", dZ, X, "e", lhs_target)
                      if op == "div":
                          dY = -dY / (Y**2)
              dY = _reduce_grad(dY, Y.shape)
          else:
              dY = tf.zeros_like(Y)
          return dX, dY
  
      return out, grad
  
imports: import numpy
  import tensorflow
  from ..._sparse_ops import _bwd_segment_cmp, _csrmask, _csrmm, _csrsum, _gsddmm, _gspmm, _scatter_add, _segment_reduce
  from ...base import ALL, is_all
  from ...heterograph_index import create_unitgraph_from_csr
  from .tensor import asnumpy, context, copy_to, tensor, zerocopy_from_numpy
label_desc: Use image node_id 10 for calling a global function with example usage: gsddmm_real(gidx, op, X, Y, lhs_target, rhs_target) and returns: out,  grad, dX,  dY