Add `op` to the current context.
(self, op)
| 972 | self._AddOpInternal(op) |
| 973 | |
| 974 | def _AddOpInternal(self, op): |
| 975 | """Add `op` to the current context.""" |
| 976 | if not op.inputs: |
| 977 | # If we're in a while loop, remove any control inputs from outside the |
| 978 | # loop. |
| 979 | self._RemoveExternalControlEdges(op) |
| 980 | |
| 981 | if not any( |
| 982 | util.OpInContext(input_op, self) for input_op in op.control_inputs): |
| 983 | # pylint: disable=protected-access |
| 984 | op._add_control_input(self._pivot.op) |
| 985 | # pylint: enable=protected-access |
| 986 | else: |
| 987 | # Make each input to 'op' available in this CondContext. If an input is |
| 988 | # already part of this context there's nothing to do, but if it's |
| 989 | # external, AddValue() will handle adding the appropriate Switch node and |
| 990 | # other bookkeeping. |
| 991 | for index in range(len(op.inputs)): |
| 992 | x = op.inputs[index] |
| 993 | if op.type == "Merge" and x.op.type == "NextIteration": |
| 994 | # Edge case: if we're importing a while loop inside this CondContext, |
| 995 | # AddValue() will not correctly handle the NextIteration inputs to |
| 996 | # Merge node. The problem is that the NextIteration should also be |
| 997 | # part of this context, but if we're importing it won't have been |
| 998 | # processed and added to the context yet, so AddValue() will try to |
| 999 | # add a Switch which results in an invalid graph. Instead, we use the |
| 1000 | # NextIteration input as-is here, and it will eventually be added to |
| 1001 | # the context via AddOp(). |
| 1002 | real_x = x |
| 1003 | else: |
| 1004 | real_x = self.AddValue(x) |
| 1005 | if real_x != x: |
| 1006 | # pylint: disable=protected-access |
| 1007 | op._update_input(index, real_x) |
| 1008 | # pylint: enable=protected-access |
| 1009 | # Remove any external control dependency on this op. |
| 1010 | self._RemoveExternalControlEdges(op) |
| 1011 | # pylint: disable=protected-access |
| 1012 | if op.graph._is_function(op.type) or op.type == "SymbolicGradient": |
| 1013 | op._add_control_input(self._pivot.op) |
| 1014 | # pylint: enable=protected-access |
| 1015 | |
| 1016 | # Mark op's outputs as seen by this context and any outer contexts. |
| 1017 | output_names = [x.name for x in op.outputs] |
| 1018 | ctxt = self |
| 1019 | while ctxt is not None: |
| 1020 | # pylint: disable=protected-access |
| 1021 | ctxt._values.update(output_names) |
| 1022 | ctxt = ctxt._outer_context |
| 1023 | # pylint: enable=protected-access |
| 1024 | |
| 1025 | if self._outer_context or not util.IsLoopExit(op): |
| 1026 | op.graph.prevent_fetching(op) |
| 1027 | |
| 1028 | if self._outer_context: |
| 1029 | self._outer_context.AddInnerOp(op) |
| 1030 | |
| 1031 | def _ProcessOutputTensor(self, val): |
no test coverage detected