class_docstr: A visitor that inspects the graph and looks for combine nodes.
  
  This visitor takes the grouped combines and performs the packing of those
  combines.
                 Before packing
             ...               ...
              /                  \
           Combine1             Combine2
             /                     \
  ExtractCombineMergeOutputs1    ExtractCombineMergeOutputs2
  
                 After packing
             ...        ...
              /           \
           AddKey1         AddKey2
              \             /
               \           /
                \         /
                  Flatten
                     |
                 PackedCombineMerge
               /                    \
     ExtractFromDict1              ExtractFromDict2
              /                        \
  ExtractPackedCombineMergeOutputs1    ExtractPackedCombineMergeOutputs2
  
  Since the inputs to the final flatten node before the packed merge come from
  different paths, we add redundant flatten and packed merge nodes each time we
  visit a new input of the final flatten node. At the end of this traversal,
  we would have one final packed merge node with a corresponding flatten node
  having all the needed inputs, and in addition to this we would have a set of
  redundant packed merge and flatten nodes which needs to be removed.
class_docstr_tok: ["A","visitor","that","inspects","the","graph","and","looks","for","combine","nodes",".","This","visitor","takes","the","grouped","combines","and","performs","the","packing","of","those","combines",".","Before","packing","...","...","\/","\\","Combine1","Combine2","\/","\\","ExtractCombineMergeOutputs1","ExtractCombineMergeOutputs2","After","packing","...","...","\/","\\","AddKey1","AddKey2","\\","\/","\\","\/","\\","\/","Flatten","|","PackedCombineMerge","\/","\\","ExtractFromDict1","ExtractFromDict2","\/","\\","ExtractPackedCombineMergeOutputs1","ExtractPackedCombineMergeOutputs2","Since","the","inputs","to","the","final","flatten","node","before","the","packed","merge","come","from","different","paths",",","we","add","redundant","flatten","and","packed","merge","nodes","each","time","we","visit","a","new","input","of","the","final","flatten","node",".","At","the","end","of","this","traversal",",","we","would","have","one","final","packed","merge","node","with","a","corresponding","flatten","node","having","all","the","needed","inputs",",","and","in","addition","to","this","we","would","have","a","set","of","redundant","packed","merge","and","flatten","nodes","which","needs","to","be","removed","."]
code: def __init__(self, packable_combine_extract_outputs):
      super().__init__()
      self._packable_combine_extract_outputs = (
          packable_combine_extract_outputs
      )
      # Gather all the input nodes that we need to flatten to be passed as input
      # to the packed merge node.
      self._flatten_inputs = []
      # Keep track of the label of the final packed merge combine node.
      self.final_packed_merge_combine_label = None
  
imports: import collections
  import dataclasses
  from typing import Sequence
  from tensorflow_transform import analyzer_nodes
  from tensorflow_transform import nodes
  from tensorflow_transform.beam import beam_nodes
label_desc: Use image node_id 1 to create a new _PackMergeCombineVisitor object from inherited base classes: _ValidationVisitor with example: obj = _PackMergeCombineVisitor(packable_combine_extract_outputs)