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 _get_packed_combine(self, operation_def, input_values):
      for value in input_values:
          keyed_value = nodes.apply_operation(
              analyzer_nodes.AddKey,
              value,
              key=operation_def.label,
              label="AddKey[{}]".format(operation_def.label),
          )
          self._flatten_inputs.append(keyed_value)
      # TODO(b/134414978): When we add support for multi-phase merge packing,
      # add phase number to the flatten and packed combine labels.
      flatten_label = "FlattenInputForPackedCombineMerge[{}]".format(
          len(self._flatten_inputs)
      )
      flatten_node = nodes.apply_operation(
          beam_nodes.Flatten, *self._flatten_inputs, label=flatten_label
      )
      packed_combine_label = "PackedCombineMerge[{}]".format(
          len(self._flatten_inputs)
      )
      packed_combine = nodes.apply_operation(
          analyzer_nodes.PackedCombineMerge,
          flatten_node,
          combiners=list(
              self._packable_combine_extract_outputs.values()
          ),
          label=packed_combine_label,
      )
      self.final_packed_merge_combine_label = packed_combine_label
      return packed_combine
  
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 4 for calling the _PackMergeCombineVisitor obj's underlying member method code with example usage: obj._get_packed_combine(operation_def, input_values) and returns: packed_combine