Returns the set of tensors/ops reachable from `inputs`. Stops if all targets have been found (target is optional). Only valid in Symbolic mode, not Eager mode. Args: inputs: List of tensors. targets: List of tensors. Returns: A set of tensors reachable from the inputs (includ
(inputs, targets=None)
| 94 | |
| 95 | |
| 96 | def get_reachable_from_inputs(inputs, targets=None): |
| 97 | """Returns the set of tensors/ops reachable from `inputs`. |
| 98 | |
| 99 | Stops if all targets have been found (target is optional). |
| 100 | |
| 101 | Only valid in Symbolic mode, not Eager mode. |
| 102 | |
| 103 | Args: |
| 104 | inputs: List of tensors. |
| 105 | targets: List of tensors. |
| 106 | |
| 107 | Returns: |
| 108 | A set of tensors reachable from the inputs (includes the inputs themselves). |
| 109 | """ |
| 110 | inputs = nest.flatten(inputs, expand_composites=True) |
| 111 | reachable = object_identity.ObjectIdentitySet(inputs) |
| 112 | if targets: |
| 113 | remaining_targets = object_identity.ObjectIdentitySet(nest.flatten(targets)) |
| 114 | queue = inputs[:] |
| 115 | |
| 116 | while queue: |
| 117 | x = queue.pop() |
| 118 | if isinstance(x, tuple(_user_convertible_tensor_types)): |
| 119 | # Can't find consumers of user-specific types. |
| 120 | continue |
| 121 | |
| 122 | if isinstance(x, ops.Operation): |
| 123 | outputs = x.outputs[:] or [] |
| 124 | outputs += x._control_outputs # pylint: disable=protected-access |
| 125 | elif isinstance(x, variables.Variable): |
| 126 | try: |
| 127 | outputs = [x.op] |
| 128 | except AttributeError: |
| 129 | # Variables can be created in an Eager context. |
| 130 | outputs = [] |
| 131 | elif tensor_util.is_tensor(x): |
| 132 | outputs = x.consumers() |
| 133 | else: |
| 134 | raise TypeError('Expected Operation, Variable, or Tensor, got ' + str(x)) |
| 135 | |
| 136 | for y in outputs: |
| 137 | if y not in reachable: |
| 138 | reachable.add(y) |
| 139 | if targets: |
| 140 | remaining_targets.discard(y) |
| 141 | queue.insert(0, y) |
| 142 | |
| 143 | if targets and not remaining_targets: |
| 144 | return reachable |
| 145 | |
| 146 | return reachable |
| 147 | |
| 148 | |
| 149 | # This function needs access to private functions of `nest`. |