# Path: paleo/profilers/base.py
# class BaseProfiler(object):
#     """The base class of profilers. """
# 
#     def __init__(self, name, options):
#         self._name = name
#         self._logger = logging.getLogger('paleo.profilers.' + self._name)
#         self._msg = ''
#         self._options = options
# 
#     @property
#     def message(self):
#         return self._msg
# 
#     @message.setter
#     def message(self, msg):
#         self._msg = msg
# 
#     def clear_msg(self):
#         self._msg = ''
# 
#     @property
#     def options(self):
#         return self._options
# 
#     @property
#     def name(self):
#         if self._name:
#             return self._name
#         return "BaseProfiler"
# 
#     @abstractmethod
#     def profile(self, layer, num_iter=50, num_warmup=10, direction='forward'):
#         """Profiles the given layer and returns the time and std across num_iter
#         trails."""
#         return TimeMeasure()
# 
# class TimeMeasure(object):
#     def __init__(self, comp_time=0, comm_time=0, total_time=None):
#         self._comp_time = comp_time
#         self._comp_time_std = 0
#         self._comm_time = comm_time
#         self._comm_time_std = 0
#         if not total_time:
#             total_time = comp_time + comm_time
#         self._total_time = total_time
#         self._total_time_std = 0
# 
#     def __repr__(self):
#         return '%f (comp=%f, comm=%f)' % (self.total_time, self.comp_time,
#                                           self.comm_time)
# 
#     @property
#     def comp_time(self):
#         return self._comp_time
# 
#     @comp_time.setter
#     def comp_time(self, val):
#         self._comp_time = val
#         self._total_time = self._comp_time + self._comm_time
# 
#     @property
#     def comm_time(self):
#         return self._comm_time
# 
#     @comm_time.setter
#     def comm_time(self, val):
#         self._comm_time = val
#         self._total_time = self._comp_time + self._comm_time
# 
#     @property
#     def total_time(self):
#         return self._total_time
# 
#     @property
#     def lowerbound(self):
#         """A lowerbound under perfect pipelining."""
#         return max(self._comp_time, self._comm_time)
# 
#     @total_time.setter
#     def total_time(self, val):
#         self._total_time = val
# 
#     def __radd__(self, other):
#         if other == 0:
#             return self
#         else:
#             return self.__add__(other)
# 
#     def __add__(self, other):
#         if isinstance(other, int):
#             return TimeMeasure(total_time=self.total_time + other)
#         res = TimeMeasure(
#             comp_time=self.comp_time + other.comp_time,
#             comm_time=self.comm_time + other.comm_time,
#             total_time=self.total_time + other.total_time)
#         # Sometimes the time measure may not have detailed items,
#         # in this case we set total time directly.
#         # expected_total_time = self.total_time + other.total_time
#         # if res.total_time != expected_total_time:
#         #     res.comm_time = 0
#         #     res.comp_time = 0
#         #     res.total_time = expected_total_time
#         return res
# 
#     def __sub__(self, other):
#         res = TimeMeasure(
#             comp_time=self.comp_time - other.comp_time,
#             comm_time=self.comm_time - other.comm_time,
#             total_time=self.total_time - other.total_time)
#         return res


import time
import logging
import tensorflow as tf
import numpy as np
from six.moves import range
from paleo.profilers.base import BaseProfiler, TimeMeasure
        if layer.layertype == 'conv2d':
            ops, bwd_ops = self._ops_conv2d(layer, graph)
        elif layer.layertype == 'innerproduct':
            ops, bwd_ops = self._ops_innerproduct(layer, graph)
        elif layer.layertype == 'pool2d':
            ops, bwd_ops = self._ops_pool2d(layer, graph)
        elif layer.layertype == 'dropout':
            ops, bwd_ops = self._ops_dropout(layer, graph)
        elif layer.layertype == 'concat':
            ops, bwd_ops = self._ops_concat(layer, graph)
        elif layer.layertype == 'reshape':
            ops, bwd_ops = self._ops_reshape(layer, graph)
        else:
            self._logger.warning('Unimplemented \'%s\'' % layer.layertype)

        return self._execute(ops, bwd_ops, graph)

    def profile_full_pass(self, layers):
        graph, end_points, variables = self._compose_full_graph(layers)

        # Forward pass.
        if layers[-1].layertype in ['softmax', 'sigmoid']:
            last_op = end_points[layers[-2].name]
            loss_op = end_points[layers[-1].name]
        else:
            last_op = end_points[layers[-1].name]
            loss_op = None
        forward_time = self._execute(last_op, None, graph)

        # Backward pass.

# Path: paleo/profilers/base.py
# class BaseProfiler(object):
#     """The base class of profilers. """
# 
#     def __init__(self, name, options):
#         self._name = name
#         self._logger = logging.getLogger('paleo.profilers.' + self._name)
#         self._msg = ''
#         self._options = options
# 
#     @property
#     def message(self):
#         return self._msg
# 
#     @message.setter
#     def message(self, msg):
#         self._msg = msg
# 
#     def clear_msg(self):
#         self._msg = ''
# 
#     @property
#     def options(self):
#         return self._options
# 
#     @property
#     def name(self):
#         if self._name:
#             return self._name
#         return "BaseProfiler"
# 
#     @abstractmethod
#     def profile(self, layer, num_iter=50, num_warmup=10, direction='forward'):
#         """Profiles the given layer and returns the time and std across num_iter
#         trails."""
#         return TimeMeasure()
# 
# class TimeMeasure(object):
#     def __init__(self, comp_time=0, comm_time=0, total_time=None):
#         self._comp_time = comp_time
#         self._comp_time_std = 0
#         self._comm_time = comm_time
#         self._comm_time_std = 0
#         if not total_time:
#             total_time = comp_time + comm_time
#         self._total_time = total_time
#         self._total_time_std = 0
# 
#     def __repr__(self):
#         return '%f (comp=%f, comm=%f)' % (self.total_time, self.comp_time,
#                                           self.comm_time)
# 
#     @property
#     def comp_time(self):
#         return self._comp_time
# 
#     @comp_time.setter
#     def comp_time(self, val):
#         self._comp_time = val
#         self._total_time = self._comp_time + self._comm_time
# 
#     @property
#     def comm_time(self):
#         return self._comm_time
# 
#     @comm_time.setter
#     def comm_time(self, val):
#         self._comm_time = val
#         self._total_time = self._comp_time + self._comm_time
# 
#     @property
#     def total_time(self):
#         return self._total_time
# 
#     @property
#     def lowerbound(self):
#         """A lowerbound under perfect pipelining."""
#         return max(self._comp_time, self._comm_time)
# 
#     @total_time.setter
#     def total_time(self, val):
#         self._total_time = val
# 
#     def __radd__(self, other):
#         if other == 0:
#             return self
#         else:
#             return self.__add__(other)
# 
#     def __add__(self, other):
#         if isinstance(other, int):
#             return TimeMeasure(total_time=self.total_time + other)
#         res = TimeMeasure(
#             comp_time=self.comp_time + other.comp_time,
#             comm_time=self.comm_time + other.comm_time,
#             total_time=self.total_time + other.total_time)
#         # Sometimes the time measure may not have detailed items,
#         # in this case we set total time directly.
#         # expected_total_time = self.total_time + other.total_time
#         # if res.total_time != expected_total_time:
#         #     res.comm_time = 0
#         #     res.comp_time = 0
#         #     res.total_time = expected_total_time
#         return res
# 
#     def __sub__(self, other):
#         res = TimeMeasure(
#             comp_time=self.comp_time - other.comp_time,
#             comm_time=self.comm_time - other.comm_time,
#             total_time=self.total_time - other.total_time)
#         return res


# Path: paleo/profilers/tensorflow_profiler.py
import time
import logging
import tensorflow as tf
import numpy as np
from six.moves import range
from paleo.profilers.base import BaseProfiler, TimeMeasure

        if layer.layertype == 'conv2d':
            ops, bwd_ops = self._ops_conv2d(layer, graph)
        elif layer.layertype == 'innerproduct':
            ops, bwd_ops = self._ops_innerproduct(layer, graph)
        elif layer.layertype == 'pool2d':
            ops, bwd_ops = self._ops_pool2d(layer, graph)
        elif layer.layertype == 'dropout':
            ops, bwd_ops = self._ops_dropout(layer, graph)
        elif layer.layertype == 'concat':
            ops, bwd_ops = self._ops_concat(layer, graph)
        elif layer.layertype == 'reshape':
            ops, bwd_ops = self._ops_reshape(layer, graph)
        else:
            self._logger.warning('Unimplemented \'%s\'' % layer.layertype)

        return self._execute(ops, bwd_ops, graph)

    def profile_full_pass(self, layers):
        graph, end_points, variables = self._compose_full_graph(layers)

        # Forward pass.
        if layers[-1].layertype in ['softmax', 'sigmoid']:
            last_op = end_points[layers[-2].name]
            loss_op = end_points[layers[-1].name]
        else:
            last_op = end_points[layers[-1].name]
            loss_op = None
        forward_time = self._execute(last_op, None, graph)

        # Backward pass.

        softmax_time = TimeMeasure()