# Path: experimental/lo/compress.py
# class Compressor:
#   """Implements a hierarchical set class with better performance than a set."""
# 
#   def __init__(self, hash_only_input=False):
#     self.n_dict = {}
#     self.hash_only_input = hash_only_input
# 
#   def add_entry(self, table_in, table_out=""):
#     """Adds entry (table_in, table_out) to the set."""
#     line = (table_in, table_out)
# 
#     if self.hash_only_input:
#       h_line = hash(table_in)
#     else:
#       h_line = hash(line)
# 
#     if self.n_dict.get(h_line, None):
#       self.n_dict[h_line] = self.n_dict[h_line].union([line])
#     else:
#       self.n_dict[h_line] = set([line])
# 
#   def has_entry(self, table_in, table_out=""):
#     """Checks if table_in is already stored in the set."""
# 
#     line = (table_in, table_out)
# 
#     if self.hash_only_input:
#       h_line = hash(table_in)
#     else:
#       h_line = hash(line)
# 
#     if not self.n_dict.get(h_line, None):
#       return None
# 
#     set_h_line = self.n_dict[h_line]
# 
#     for (ti, to) in set_h_line:
#       if table_in == ti:
#         return to
# 
#     return None
# 
#   def __call__(self):
#     for key in self.n_dict:
#       for line in self.n_dict[key]:
#         yield line
# 
# Path: experimental/lo/utils.py
# def get_padding_value(padding, kernel):
#   """Returns padding value for kernel."""
# 
#   if padding == "valid":
#     return 0
#   elif padding == "same":
#     return kernel // 2
#   elif padding == "full":
#     return kernel - 1
# 
#   raise ValueError("accepted paddings are 'valid', 'same' or 'full', found " +
#                    padding)


import multiprocessing as mp
import os
import shutil
import numpy as np
import six
from .compress import Compressor
from tensorflow.keras.models import Model
from .utils import get_padding_value

  # if kernel is not specified, use the kernel size from i_layer

  if not kernel:
    kernel = i_layer.kernel_size

  # if strides is not specified, use the strides from i_layer

  if not strides:
    strides = i_layer.strides

  # if padding is not specified, use the padding from i_layer

  if not padding:
    padding = i_layer.padding

  # for conv2d, we want a list for kernel, strides and padding

  if not isinstance(kernel, list) and not isinstance(kernel, tuple):
    kernel = [kernel, kernel]

  if not isinstance(strides, list) and not isinstance(strides, tuple):
    strides = [strides, strides]

  if not isinstance(padding, list) and not isinstance(padding, tuple):
    padding = [padding, padding]

  # compute the padding value

  padding[0] = get_padding_value(padding[0], kernel[0])

# Path: experimental/lo/compress.py
# class Compressor:
#   """Implements a hierarchical set class with better performance than a set."""
# 
#   def __init__(self, hash_only_input=False):
#     self.n_dict = {}
#     self.hash_only_input = hash_only_input
# 
#   def add_entry(self, table_in, table_out=""):
#     """Adds entry (table_in, table_out) to the set."""
#     line = (table_in, table_out)
# 
#     if self.hash_only_input:
#       h_line = hash(table_in)
#     else:
#       h_line = hash(line)
# 
#     if self.n_dict.get(h_line, None):
#       self.n_dict[h_line] = self.n_dict[h_line].union([line])
#     else:
#       self.n_dict[h_line] = set([line])
# 
#   def has_entry(self, table_in, table_out=""):
#     """Checks if table_in is already stored in the set."""
# 
#     line = (table_in, table_out)
# 
#     if self.hash_only_input:
#       h_line = hash(table_in)
#     else:
#       h_line = hash(line)
# 
#     if not self.n_dict.get(h_line, None):
#       return None
# 
#     set_h_line = self.n_dict[h_line]
# 
#     for (ti, to) in set_h_line:
#       if table_in == ti:
#         return to
# 
#     return None
# 
#   def __call__(self):
#     for key in self.n_dict:
#       for line in self.n_dict[key]:
#         yield line
# 
# Path: experimental/lo/utils.py
# def get_padding_value(padding, kernel):
#   """Returns padding value for kernel."""
# 
#   if padding == "valid":
#     return 0
#   elif padding == "same":
#     return kernel // 2
#   elif padding == "full":
#     return kernel - 1
# 
#   raise ValueError("accepted paddings are 'valid', 'same' or 'full', found " +
#                    padding)


# Path: experimental/lo/conv2d.py
import multiprocessing as mp
import os
import shutil
import numpy as np
import six
from .compress import Compressor
from tensorflow.keras.models import Model
from .utils import get_padding_value


  # if kernel is not specified, use the kernel size from i_layer

  if not kernel:
    kernel = i_layer.kernel_size

  # if strides is not specified, use the strides from i_layer

  if not strides:
    strides = i_layer.strides

  # if padding is not specified, use the padding from i_layer

  if not padding:
    padding = i_layer.padding

  # for conv2d, we want a list for kernel, strides and padding

  if not isinstance(kernel, list) and not isinstance(kernel, tuple):
    kernel = [kernel, kernel]

  if not isinstance(strides, list) and not isinstance(strides, tuple):
    strides = [strides, strides]

  if not isinstance(padding, list) and not isinstance(padding, tuple):
    padding = [padding, padding]

  # compute the padding value

  padding[0] = get_padding_value(padding[0], kernel[0])

  padding[1] = get_padding_value(padding[1], kernel[1])