# Path: deep_architect/helpers/tensorflow_support.py
# def siso_tensorflow_module(name, compile_fn, name_to_hyperp, scope=None):
#     return TensorflowModule(name, compile_fn, name_to_hyperp, ['in'], ['out'],
#                             scope).get_io()
# 
# class TensorflowModule(co.Module):
#     """Class for taking Tensorflow code and wrapping it in a DeepArchitect module.
# 
#     This class subclasses :class:`deep_architect.core.Module` as therefore inherits all
#     the functionality associated to it (e.g., keeping track of inputs, outputs,
#     and hyperparameters). It also enables to do the compile and forward
#     operations for these types of modules once a module is fully specified,
#     i.e., once all the hyperparameters have been chosen.
# 
#     The compile operation in this case creates all the variables used for the
#     fragment of the computational graph associated to this module.
#     The forward operation takes the variables that were created in the compile
#     operation and constructs the actual computational graph fragment associated
#     to this module.
# 
#     .. note::
#         This module is abstract, meaning that it does not actually implement
#         any particular Tensorflow computation. It simply wraps Tensorflow
#         functionality in a DeepArchitect module. The instantiation of the Tensorflow
#         variables is taken care by the `compile_fn` function that takes a two
#         dictionaries, one of inputs and another one of outputs, and
#         returns another function that takes a dictionary of inputs and creates
#         the computational graph. This functionality makes extensive use of closures.
# 
#         The keys of the dictionaries that are passed to the compile
#         and forward function match the names of the inputs and hyperparameters
#         respectively. The dictionary returned by the forward function has keys
#         equal to the names of the outputs.
# 
#     The usage of this class is best understood through examples.
#     Examples for how to instantiate objects of this class to implement
#     specific Tensorflow computation can be found in
#     :mod:`deep_architect.search_spaces.tensorflow.conv2d`.
# 
#     Args:
#         name (str): Name of the module
#         name_to_hyperp (dict[str,deep_architect.core.Hyperparameter]): Dictionary of
#             hyperparameters that the model depends on. The keys are the local
#             names of the hyperparameters.
#         compile_fn ((dict[str,object], dict[str,object]) -> ((dict[str,object]) -> ((dict[str,object]) | (dict[str,object], dict[tensorflow.python.framework.ops.Tensor,object], dict[tensorflow.python.framework.ops.Tensor,object])))):
#             The first function takes two dictionaries with
#             keys corresponding to `input_names` and `output_names` and returns
#             a function that takes a dictionary with keys corresponding to
#             `input_names` and returns a dictionary with keys corresponding
#             to `output_names`. The first function may also return
#             two additional dictionaries mapping Tensorflow placeholders to the
#             values that they will take during training and test.
#         input_names (list[str]): List of names for the inputs.
#         output_names (list[str]): List of names for the outputs.
#         scope (deep_architect.core.Scope, optional): Scope where the module will be
#             registered.
# 
#     """
# 
#     def __init__(self,
#                  name,
#                  compile_fn,
#                  name_to_hyperp,
#                  input_names,
#                  output_names,
#                  scope=None):
#         co.Module.__init__(self, scope, name)
#         hyperparam_dict = {}
#         for h in name_to_hyperp:
#             if not isinstance(name_to_hyperp[h], co.Hyperparameter):
#                 hyperparam_dict[h] = D([name_to_hyperp[h]])
#             else:
#                 hyperparam_dict[h] = name_to_hyperp[h]
# 
#         self._register(input_names, output_names, hyperparam_dict)
#         self._compile_fn = compile_fn
# 
#     def _compile(self):
#         input_name_to_val = self._get_input_values()
#         hyperp_name_to_val = self._get_hyperp_values()
# 
#         out = self._compile_fn(input_name_to_val, hyperp_name_to_val)
#         if isinstance(out, tuple):
#             (self._fn, self.train_feed, self.eval_feed) = out
#         else:
#             self._fn = out
# 
#     def _forward(self):
#         input_name_to_val = self._get_input_values()
#         output_name_to_val = self._fn(input_name_to_val)
#         self._set_output_values(output_name_to_val)
# 
#     def _update(self):
#         pass


from deep_architect.helpers.tensorflow_support import (siso_tensorflow_module,
                                                       TensorflowModule)
import tensorflow as tf
        def fn(di):
            return {
                'out':
                tf.nn.max_pool(di['in'],
                               [1, dh['kernel_size'], dh['kernel_size'], 1],
                               [1, dh['stride'], dh['stride'], 1], 'SAME')
            }

        return fn

    return siso_tensorflow_module('MaxPool2D', compile_fn, {
        'kernel_size': h_kernel_size,
        'stride': h_stride,
    })


def avg_pool2d(h_kernel_size, h_stride=1):

    def compile_fn(di, dh):

        def fn(di):
            return {
                'out':
                tf.nn.avg_pool(di['in'],
                               [1, dh['kernel_size'], dh['kernel_size'], 1],
                               [1, dh['stride'], dh['stride'], 1], 'SAME')
            }

        return fn


# Path: deep_architect/helpers/tensorflow_support.py
# def siso_tensorflow_module(name, compile_fn, name_to_hyperp, scope=None):
#     return TensorflowModule(name, compile_fn, name_to_hyperp, ['in'], ['out'],
#                             scope).get_io()
# 
# class TensorflowModule(co.Module):
#     """Class for taking Tensorflow code and wrapping it in a DeepArchitect module.
# 
#     This class subclasses :class:`deep_architect.core.Module` as therefore inherits all
#     the functionality associated to it (e.g., keeping track of inputs, outputs,
#     and hyperparameters). It also enables to do the compile and forward
#     operations for these types of modules once a module is fully specified,
#     i.e., once all the hyperparameters have been chosen.
# 
#     The compile operation in this case creates all the variables used for the
#     fragment of the computational graph associated to this module.
#     The forward operation takes the variables that were created in the compile
#     operation and constructs the actual computational graph fragment associated
#     to this module.
# 
#     .. note::
#         This module is abstract, meaning that it does not actually implement
#         any particular Tensorflow computation. It simply wraps Tensorflow
#         functionality in a DeepArchitect module. The instantiation of the Tensorflow
#         variables is taken care by the `compile_fn` function that takes a two
#         dictionaries, one of inputs and another one of outputs, and
#         returns another function that takes a dictionary of inputs and creates
#         the computational graph. This functionality makes extensive use of closures.
# 
#         The keys of the dictionaries that are passed to the compile
#         and forward function match the names of the inputs and hyperparameters
#         respectively. The dictionary returned by the forward function has keys
#         equal to the names of the outputs.
# 
#     The usage of this class is best understood through examples.
#     Examples for how to instantiate objects of this class to implement
#     specific Tensorflow computation can be found in
#     :mod:`deep_architect.search_spaces.tensorflow.conv2d`.
# 
#     Args:
#         name (str): Name of the module
#         name_to_hyperp (dict[str,deep_architect.core.Hyperparameter]): Dictionary of
#             hyperparameters that the model depends on. The keys are the local
#             names of the hyperparameters.
#         compile_fn ((dict[str,object], dict[str,object]) -> ((dict[str,object]) -> ((dict[str,object]) | (dict[str,object], dict[tensorflow.python.framework.ops.Tensor,object], dict[tensorflow.python.framework.ops.Tensor,object])))):
#             The first function takes two dictionaries with
#             keys corresponding to `input_names` and `output_names` and returns
#             a function that takes a dictionary with keys corresponding to
#             `input_names` and returns a dictionary with keys corresponding
#             to `output_names`. The first function may also return
#             two additional dictionaries mapping Tensorflow placeholders to the
#             values that they will take during training and test.
#         input_names (list[str]): List of names for the inputs.
#         output_names (list[str]): List of names for the outputs.
#         scope (deep_architect.core.Scope, optional): Scope where the module will be
#             registered.
# 
#     """
# 
#     def __init__(self,
#                  name,
#                  compile_fn,
#                  name_to_hyperp,
#                  input_names,
#                  output_names,
#                  scope=None):
#         co.Module.__init__(self, scope, name)
#         hyperparam_dict = {}
#         for h in name_to_hyperp:
#             if not isinstance(name_to_hyperp[h], co.Hyperparameter):
#                 hyperparam_dict[h] = D([name_to_hyperp[h]])
#             else:
#                 hyperparam_dict[h] = name_to_hyperp[h]
# 
#         self._register(input_names, output_names, hyperparam_dict)
#         self._compile_fn = compile_fn
# 
#     def _compile(self):
#         input_name_to_val = self._get_input_values()
#         hyperp_name_to_val = self._get_hyperp_values()
# 
#         out = self._compile_fn(input_name_to_val, hyperp_name_to_val)
#         if isinstance(out, tuple):
#             (self._fn, self.train_feed, self.eval_feed) = out
#         else:
#             self._fn = out
# 
#     def _forward(self):
#         input_name_to_val = self._get_input_values()
#         output_name_to_val = self._fn(input_name_to_val)
#         self._set_output_values(output_name_to_val)
# 
#     def _update(self):
#         pass


# Path: deep_architect/contrib/deep_learning_backend/tensorflow_ops.py
from deep_architect.helpers.tensorflow_support import (siso_tensorflow_module,
                                                       TensorflowModule)
import tensorflow as tf

        def fn(di):
            return {
                'out':
                tf.nn.max_pool(di['in'],
                               [1, dh['kernel_size'], dh['kernel_size'], 1],
                               [1, dh['stride'], dh['stride'], 1], 'SAME')
            }

        return fn

    return siso_tensorflow_module('MaxPool2D', compile_fn, {
        'kernel_size': h_kernel_size,
        'stride': h_stride,
    })


def avg_pool2d(h_kernel_size, h_stride=1):

    def compile_fn(di, dh):

        def fn(di):
            return {
                'out':
                tf.nn.avg_pool(di['in'],
                               [1, dh['kernel_size'], dh['kernel_size'], 1],
                               [1, dh['stride'], dh['stride'], 1], 'SAME')
            }

        return fn


    return siso_tensorflow_module('MaxPool2D', compile_fn, {