def _group_merge_refs(proto_op_dag, merge_refs):
    """
    Takes the protbuf representation of the operator dag together with the merge references and converts them into
    grouped merge references, which is pairs of (to-op-index, from-op-index).
    Two ops can be merged if:
      - All inputs of the to-op come from one and the same from-op.
      - OR inputs can come from external inputs.
    :param proto_op_dag: the protobuf representation of the operator dag.
    :param merge_refs: merge references.
    :return: pairs of (to-op-index, from-op-index).
    """
    merge_group_info = set()
    for merge_ref in merge_refs:
        merge_group_info.add((merge_ref.to_op_index, merge_ref.
            from_op_index, merge_ref.from_out_arg_index))
    group_merge_refs = []
    for i, reference in enumerate(proto_op_dag.references):
        if len(reference.input_refs) == 0:
            continue
        from_op_index = reference.input_refs[0].op_index
        if from_op_index == i:
            continue
        to_op_index = i
        do_group = True
        for in_ref in reference.input_refs:
            if in_ref.is_leaf:
                continue
            if in_ref.op_index != from_op_index:
                do_group = False
                break
            from_out_arg_index = in_ref.op_output_index
            if (to_op_index, from_op_index, from_out_arg_index
                ) not in merge_group_info:
                do_group = False
                break
        if do_group:
            group_merge_refs.append((to_op_index, from_op_index))
    return group_merge_refs
