code: def gradients(ys, xs, grad_ys=None):
    
    graph = ys[0].graph
    if not grad_ys:
      grad_ys = [Constant(y.mesh, 1.0, y.shape, y.dtype).outputs[0] for y in ys]
    # figure out what Tensors are downstream of xs
    downstream = set(xs)
    for op in graph.operations:
      if op.has_gradient:
        if set(op.inputs) & downstream:
          downstream |= set(op.outputs)
    tensor_to_gradient = dict(zip(ys, grad_ys))
    for op in graph.operations[::-1]:
      grad_outputs = [tensor_to_gradient.get(out) for out in op.outputs]
      if op.has_gradient and any(grad_outputs) and (set(op.inputs) & downstream):
        with tf.variable_scope(op.name + "/gradients"):
          input_grads = op.gradient(grad_outputs)
          for inp, grad in zip(op.inputs, input_grads):
            if inp in downstream and grad is not None:
              if inp in tensor_to_gradient:
                tensor_to_gradient[inp] += grad
              else:
                tensor_to_gradient[inp] = grad
    return [tensor_to_gradient.get(x, None) for x in xs]
docs: Compute gradients in dtf.
  
    Args:
      ys: a list of Tensors
      xs: a list of Tensors
      grad_ys: an optional list of Tensors
  
    Returns:
      grad_xs: a list of Tensors