# Path: morph_net/framework/grouping_op_handler.py
# class GroupingOpHandler(op_handler.OpHandler):
#   def __init__(self, grouping_indices=None):
#   def is_source_op(self):
#   def is_passthrough(self):
#   def assign_grouping(self, op, op_reg_manager):
#   def create_regularizer(self, _):
#   def _get_input_output_op_slices(self, input_ops, output_ops, op_reg_manager):
#   def _is_broadcast(self, op, op_reg_manager):
# 
# Path: morph_net/framework/op_handler_util.py
# OP_TYPES_WITH_MULTIPLE_OUTPUTS = ('SplitV',)
# WEIGHTS_INDEX_DICT = {
#     'Conv2D': 1,
#     'Conv2DBackpropInput': 1,
#     'DepthwiseConv2dNative': 1,
#     'MatMul': 1
# }
# def get_input_ops(op, op_reg_manager, whitelist_indices=None):
#   def is_const(tensor):
#   def is_weight_tensor(i, op_type):
# def get_output_ops(op, op_reg_manager):
# def get_ops_without_groups(ops, op_reg_manager):
# def remove_non_passthrough_ops(ops, op_reg_manager):
# def group_op_with_inputs_and_outputs(op, input_op_slices, output_op_slices,
#                                      aligned_op_slice_sizes, op_reg_manager):
# def get_concat_input_op_slices(concat_ops, op_reg_manager):
# def get_op_slices(ops, op_reg_manager):
# def get_op_slice_sizes(op_slices):
# def get_aligned_op_slice_sizes(op_slices, input_op_slices, output_op_slices):
# def get_aligned_sizes(op_slice_sizes):
# def _get_num_slices(op_slice_sizes):
# def reslice_concat_ops(concat_ops, aligned_op_slice_sizes, op_reg_manager):
# def get_total_slice_size(op_slice_sizes, index, slice_count):
# def reslice_ops(ops, aligned_op_slice_sizes, op_reg_manager):
# def _get_source_op_slices(op_slices, op_reg_manager):
# def group_aligned_input_output_slices(
#     op, input_ops_to_process, output_ops_to_process, input_op_slices,
#     output_op_slices, aligned_op_slice_sizes, op_reg_manager):
# def get_op_size(op):
# def separate_same_size_ops(reference_op, ops):
# def group_match(regex, op_slices):


from morph_net.framework import grouping_op_handler
from morph_net.framework import op_handler_util
        [op] + output_ops_to_group, aligned_op_slice_sizes, op_reg_manager)

    # Rearrange OpSlice to align input and output.
    input_op_slices, output_op_slices = (
        self._get_depth_multiplier_input_output_op_slices(
            input_ops_to_group, input_size, output_ops_to_group,
            op_reg_manager, depth_multiplier))

    # Group with inputs and outputs.
    op_handler_util.group_aligned_input_output_slices(
        op, input_ops_to_process, output_ops_to_process, input_op_slices,
        output_op_slices, aligned_op_slice_sizes, op_reg_manager)

  def _get_depth_multiplier_input_output_op_slices(
      self, input_ops, input_size, output_ops, op_reg_manager,
      depth_multiplier):
    """Returns op slices for inputs and outputs.

    Args:
      input_ops: List of tf.Operation.
      input_size: Integer number of input channels.
      output_ops: List of tf.Operation.
      op_reg_manager: OpRegularizerManager to keep track of the grouping.
      depth_multiplier: Integer indicating how many times each input channel
        should be replicated.  Must be positive.

    Returns:
      Tuple of (input_op_slices, output_op_slices), where each element is a list
      of list of OpSlice with a list per op.
    """

# Path: morph_net/framework/grouping_op_handler.py
# class GroupingOpHandler(op_handler.OpHandler):
#   def __init__(self, grouping_indices=None):
#   def is_source_op(self):
#   def is_passthrough(self):
#   def assign_grouping(self, op, op_reg_manager):
#   def create_regularizer(self, _):
#   def _get_input_output_op_slices(self, input_ops, output_ops, op_reg_manager):
#   def _is_broadcast(self, op, op_reg_manager):
# 
# Path: morph_net/framework/op_handler_util.py
# OP_TYPES_WITH_MULTIPLE_OUTPUTS = ('SplitV',)
# WEIGHTS_INDEX_DICT = {
#     'Conv2D': 1,
#     'Conv2DBackpropInput': 1,
#     'DepthwiseConv2dNative': 1,
#     'MatMul': 1
# }
# def get_input_ops(op, op_reg_manager, whitelist_indices=None):
#   def is_const(tensor):
#   def is_weight_tensor(i, op_type):
# def get_output_ops(op, op_reg_manager):
# def get_ops_without_groups(ops, op_reg_manager):
# def remove_non_passthrough_ops(ops, op_reg_manager):
# def group_op_with_inputs_and_outputs(op, input_op_slices, output_op_slices,
#                                      aligned_op_slice_sizes, op_reg_manager):
# def get_concat_input_op_slices(concat_ops, op_reg_manager):
# def get_op_slices(ops, op_reg_manager):
# def get_op_slice_sizes(op_slices):
# def get_aligned_op_slice_sizes(op_slices, input_op_slices, output_op_slices):
# def get_aligned_sizes(op_slice_sizes):
# def _get_num_slices(op_slice_sizes):
# def reslice_concat_ops(concat_ops, aligned_op_slice_sizes, op_reg_manager):
# def get_total_slice_size(op_slice_sizes, index, slice_count):
# def reslice_ops(ops, aligned_op_slice_sizes, op_reg_manager):
# def _get_source_op_slices(op_slices, op_reg_manager):
# def group_aligned_input_output_slices(
#     op, input_ops_to_process, output_ops_to_process, input_op_slices,
#     output_op_slices, aligned_op_slice_sizes, op_reg_manager):
# def get_op_size(op):
# def separate_same_size_ops(reference_op, ops):
# def group_match(regex, op_slices):


# Path: morph_net/framework/depthwise_convolution_op_handler.py
from morph_net.framework import grouping_op_handler
from morph_net.framework import op_handler_util

        [op] + output_ops_to_group, aligned_op_slice_sizes, op_reg_manager)

    # Rearrange OpSlice to align input and output.
    input_op_slices, output_op_slices = (
        self._get_depth_multiplier_input_output_op_slices(
            input_ops_to_group, input_size, output_ops_to_group,
            op_reg_manager, depth_multiplier))

    # Group with inputs and outputs.
    op_handler_util.group_aligned_input_output_slices(
        op, input_ops_to_process, output_ops_to_process, input_op_slices,
        output_op_slices, aligned_op_slice_sizes, op_reg_manager)

  def _get_depth_multiplier_input_output_op_slices(
      self, input_ops, input_size, output_ops, op_reg_manager,
      depth_multiplier):
    """Returns op slices for inputs and outputs.

    Args:
      input_ops: List of tf.Operation.
      input_size: Integer number of input channels.
      output_ops: List of tf.Operation.
      op_reg_manager: OpRegularizerManager to keep track of the grouping.
      depth_multiplier: Integer indicating how many times each input channel
        should be replicated.  Must be positive.

    Returns:
      Tuple of (input_op_slices, output_op_slices), where each element is a list
      of list of OpSlice with a list per op.
    """

    input_op_slices = op_handler_util.get_op_slices(input_ops, op_reg_manager)