code: def _update_grad_minmax_hetero(
      gidx, op, list_x, list_idx, list_idx_etype, list_dX
  ):
      r"""Update gradients for reduce operator max and min (on first dimension) implementation.
  
      Parameters
      ----------
      gidx : HeteroGraphIndex
          The input graph index.
      list_x : List of tensors
          List of the input features.
      list_idx : List of tensors
          List of the indices array.
      list_idx_etype : List of tensors
          List of the node- or edge-type array.
      list_dX : List of tensors
          List of gradients.
  
      Returns
      -------
      Tensor
          The output tensor.
      """
      use_u = op != "copy_rhs"
      use_e = op != "copy_lhs"
      list_out = [None] * len(list_dX)
      for etid in range(gidx.number_of_etypes()):
          src_id, dst_id = gidx.metagraph.find_edge(
              etid
          )  # gidx is reveresed
          x = list_x[src_id]
          ctx = F.context(x)
          dtype = F.dtype(x)
          if use_u:
              out_shp = (len(list_dX[dst_id]),) + F.shape(x)[1:]
              list_out[dst_id] = F.zeros(out_shp, dtype, ctx)
          if use_e:
              out_shp = (len(list_dX[etid]),) + F.shape(x)[1:]
              list_out[etid] = F.zeros(out_shp, dtype, ctx)
  
      _CAPI_DGLKernelUpdateGradMinMaxHetero(
          gidx,
          op,
          [to_dgl_nd(x) for x in list_x],
          [to_dgl_nd(idx) for idx in list_idx],
          [to_dgl_nd(idx_etype) for idx_etype in list_idx_etype],
          [to_dgl_nd_for_write(out) for out in list_out],
      )
      return tuple(list_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 17 for calling a global function with example usage: _update_grad_minmax_hetero(gidx, op, list_x, list_idx, list_idx_etype, list_dX) and returns: tuple