# Path: morph_net/framework/concat_and_slice_regularizers.py
# class ConcatRegularizer(generic_regularizers.OpRegularizer):
# class SlicingReferenceRegularizer(generic_regularizers.OpRegularizer):
#   def __init__(self, regularizers_to_concatenate):
#   def regularization_vector(self):
#   def alive_vector(self):
#   def __init__(self, get_regularizer_to_slice, begin, size):
#   def regularization_vector(self):
#   def alive_vector(self):
# 
# Path: morph_net/framework/constant_op_regularizer.py
# class ConstantOpRegularizer(generic_regularizers.OpRegularizer):
#   def __init__(self, size):
#   def regularization_vector(self):
#   def alive_vector(self):
# 
# Path: morph_net/framework/grouping_regularizers.py
# DEFAULT_THRESHOLD = 0.01
# class MaxGroupingRegularizer(generic_regularizers.OpRegularizer):
# class L2GroupingRegularizer(generic_regularizers.OpRegularizer):
#   def __init__(self, regularizers_to_group):
#   def regularization_vector(self):
#   def alive_vector(self):
#   def __init__(self, regularizers_to_group, threshold=DEFAULT_THRESHOLD):
#   def regularization_vector(self):
#   def alive_vector(self):
# def lazy_square(tensor):
# 
# 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):


import collections
import tensorflow.compat.v1 as tf
from morph_net.framework import concat_and_slice_regularizers
from morph_net.framework import constant_op_regularizer
from morph_net.framework import grouping_regularizers
from morph_net.framework import op_handler_util
from typing import List
      Boolean indicating if op is a source op.
    """
    op_handler = self._op_handler_dict[op.type]
    return op_handler.is_source_op

  def is_passthrough(self, op):
    """Returns True if op is passthrough.

    Args:
      op: tf.Operation to check whether it is passthrough.

    Returns:
      Boolean indicating if op is passthrough.
    """
    op_handler = self._op_handler_dict[op.type]
    return op_handler.is_passthrough

  def get_op_slices(self, op):
    """Returns OpSlice objects that are mapped to op.

    If no mapping exists, a new OpSlice object will be created and mapped to op.

    Args:
      op: A tf.Operation to get OpSlice for.

    Returns:
      List of OpSlice that constitute op.
    """
    if op not in self._op_slice_dict:
      # No OpSlice exists for op so create a new one.

# Path: morph_net/framework/concat_and_slice_regularizers.py
# class ConcatRegularizer(generic_regularizers.OpRegularizer):
# class SlicingReferenceRegularizer(generic_regularizers.OpRegularizer):
#   def __init__(self, regularizers_to_concatenate):
#   def regularization_vector(self):
#   def alive_vector(self):
#   def __init__(self, get_regularizer_to_slice, begin, size):
#   def regularization_vector(self):
#   def alive_vector(self):
# 
# Path: morph_net/framework/constant_op_regularizer.py
# class ConstantOpRegularizer(generic_regularizers.OpRegularizer):
#   def __init__(self, size):
#   def regularization_vector(self):
#   def alive_vector(self):
# 
# Path: morph_net/framework/grouping_regularizers.py
# DEFAULT_THRESHOLD = 0.01
# class MaxGroupingRegularizer(generic_regularizers.OpRegularizer):
# class L2GroupingRegularizer(generic_regularizers.OpRegularizer):
#   def __init__(self, regularizers_to_group):
#   def regularization_vector(self):
#   def alive_vector(self):
#   def __init__(self, regularizers_to_group, threshold=DEFAULT_THRESHOLD):
#   def regularization_vector(self):
#   def alive_vector(self):
# def lazy_square(tensor):
# 
# 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/op_regularizer_manager.py
import collections
import tensorflow.compat.v1 as tf
from morph_net.framework import concat_and_slice_regularizers
from morph_net.framework import constant_op_regularizer
from morph_net.framework import grouping_regularizers
from morph_net.framework import op_handler_util
from typing import List

      Boolean indicating if op is a source op.
    """
    op_handler = self._op_handler_dict[op.type]
    return op_handler.is_source_op

  def is_passthrough(self, op):
    """Returns True if op is passthrough.

    Args:
      op: tf.Operation to check whether it is passthrough.

    Returns:
      Boolean indicating if op is passthrough.
    """
    op_handler = self._op_handler_dict[op.type]
    return op_handler.is_passthrough

  def get_op_slices(self, op):
    """Returns OpSlice objects that are mapped to op.

    If no mapping exists, a new OpSlice object will be created and mapped to op.

    Args:
      op: A tf.Operation to get OpSlice for.

    Returns:
      List of OpSlice that constitute op.
    """
    if op not in self._op_slice_dict:
      # No OpSlice exists for op so create a new one.

      size = op_handler_util.get_op_size(op)