def get_unreachable_ops(graph, outputs):
  """Finds all of the tensors in graph that are unreachable from outputs."""
  outputs = flatten_recursive(outputs)
  output_to_op = collections.defaultdict(list)
  op_to_all = collections.defaultdict(list)
  assign_out_to_in = collections.defaultdict(list)

  for op in graph.get_operations():
    for x in op.inputs:
      op_to_all[op.name].append(x.name)
    for y in op.outputs:
      output_to_op[y.name].append(op.name)
      op_to_all[op.name].append(y.name)
    if str(op.type) == "Assign":
      for y in op.outputs:
        for x in op.inputs:
          assign_out_to_in[y.name].append(x.name)

  assign_groups = collections.defaultdict(list)
  for out_name in assign_out_to_in.keys():
    name_group = assign_out_to_in[out_name]
    for n1 in name_group:
      assign_groups[n1].append(out_name)
      for n2 in name_group:
        if n1 != n2:
          assign_groups[n1].append(n2)

  seen_tensors = set()
  stack = [x.name for x in outputs]
  while stack:
    name = stack.pop()
    if name in seen_tensors:
      continue
    seen_tensors.add(name)

    if name in output_to_op:
      for op_name in output_to_op[name]:
        if op_name in op_to_all:
          for input_name in op_to_all[op_name]:
            if input_name not in stack:
              stack.append(input_name)

    stack.extend([n for n in assign_groups[name] if n not in stack])

  unreachable_ops = []
  for op in graph.get_operations():
    all_names = [x.name for x in list(op.inputs) + op.outputs]
    is_unreachable = any(name for name in all_names if name not in seen_tensors)
    if is_unreachable:
      unreachable_ops.append(op)
  return unreachable_ops
Finds all of the tensors in graph that are unreachable from outputs.
language/canine/modeling_test.py