def _create_graph(ops):
    """
  Creates an adjacency representation of the directed graph formed from the
  list of TF ops.
  Nodes are the ops. Directed edge from an op "A" to an op "B" implies that at
  least one of the outputs of A is feeding as an input to B.

  :param: ops: list of ops. List of size N.
  :return: G: list of lists. Outer list is of size N.

  Let the number of ops be N.
  Then the adjacency representation is a list of lists: G. G[i] is the list of
  all ops that have directed edges impingent from op "i",
  i.e. G[i] is the fan-out list of op "i"
  """
    n = len(ops)
    G = [[] for i in range(n)]
    op_name_to_index = dict()
    for i, op in enumerate(ops):
        op_name_to_index[op.name] = i
    for i, op in enumerate(ops):
        for inp in op.inputs:
            G[op_name_to_index[inp.op.name]].append(i)
    return G
