r"""Returns TensorList if any containing accumulated values of tensor. We try to find a pattern of the form: input_tl tensor \ / (TensorListPushBack) | output_tl which satisfies the following conditions: 1. input_tl must be in tensor.graph.inpu
(tensor)
| 759 | |
| 760 | |
| 761 | def _get_accumulator(tensor): |
| 762 | r"""Returns TensorList if any containing accumulated values of tensor. |
| 763 | |
| 764 | We try to find a pattern of the form: |
| 765 | |
| 766 | input_tl tensor |
| 767 | \ / |
| 768 | (TensorListPushBack) |
| 769 | | |
| 770 | output_tl |
| 771 | |
| 772 | which satisfies the following conditions: |
| 773 | |
| 774 | 1. input_tl must be in tensor.graph.inputs. |
| 775 | 2. output_tl or Identity(output_tl) must be in tensor.graph.outputs. |
| 776 | 3. tensor.graph.input_index(input_tl) == tensor.graph.output_index(output_t). |
| 777 | |
| 778 | output_tl or Identity(output_tl) (whichever is in tensor.graph.outputs) is |
| 779 | returned if such a pattern is found else None is returned. |
| 780 | |
| 781 | Args: |
| 782 | tensor: The Tensor to be accumulated. |
| 783 | |
| 784 | Returns: |
| 785 | A variant tensor in the same graph as `tensor` or None if no accumulator is |
| 786 | found. |
| 787 | """ |
| 788 | assert isinstance(tensor.graph, func_graph_module.FuncGraph) |
| 789 | |
| 790 | def get_func_graph_output(t): |
| 791 | """Returns t or Identity(t) whichever exists in graph outputs else None.""" |
| 792 | for output in tensor.graph.outputs: |
| 793 | if output is t: |
| 794 | return t |
| 795 | # tf.defun adds an Identity for each output, check whether that is the case. |
| 796 | identity_op = t.consumers()[0] |
| 797 | if (identity_op.type == "Identity" and |
| 798 | identity_op.outputs[0] in tensor.graph.outputs): |
| 799 | return identity_op.outputs[0] |
| 800 | return None |
| 801 | |
| 802 | for consumer in tensor.consumers(): |
| 803 | # Find the consumer that is a TensorListPushBack node whose TensorList input |
| 804 | # is in the list of function inputs. |
| 805 | if consumer.type != "TensorListPushBack": |
| 806 | continue |
| 807 | |
| 808 | accum_input_idx = -1 |
| 809 | for accum_input_idx, inp in enumerate(tensor.graph.inputs): |
| 810 | if inp is consumer.inputs[0]: |
| 811 | break |
| 812 | else: |
| 813 | continue |
| 814 | |
| 815 | output = get_func_graph_output(consumer.outputs[0]) |
| 816 | if output is None: |
| 817 | # The TensorList output of `consumer` is not in the list of function |
| 818 | # outputs. |
no test coverage detected