Home | History | Annotate | Download | only in kernel_tests
      1 # Copyright 2016 The TensorFlow Authors. All Rights Reserved.
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #     http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 # ==============================================================================
     15 """Tests for DecodeJpegOp."""
     16 
     17 from __future__ import absolute_import
     18 from __future__ import division
     19 from __future__ import print_function
     20 
     21 import os
     22 import time
     23 
     24 from six.moves import xrange  # pylint: disable=redefined-builtin
     25 from tensorflow.python.client import session
     26 from tensorflow.python.framework import ops
     27 from tensorflow.python.ops import array_ops
     28 from tensorflow.python.ops import control_flow_ops
     29 from tensorflow.python.ops import image_ops
     30 from tensorflow.python.ops import io_ops
     31 from tensorflow.python.ops import variable_scope
     32 from tensorflow.python.ops import variables
     33 from tensorflow.python.platform import test
     34 
     35 prefix_path = 'third_party/tensorflow/core/lib/jpeg/testdata'
     36 
     37 
     38 class DecodeJpegBenchmark(test.Benchmark):
     39   """Evaluate tensorflow DecodeJpegOp performance."""
     40 
     41   def _evalDecodeJpeg(self,
     42                       image_name,
     43                       parallelism,
     44                       num_iters,
     45                       crop_during_decode=None,
     46                       crop_window=None,
     47                       tile=None):
     48     """Evaluate DecodeJpegOp for the given image.
     49 
     50     TODO(tanmingxing): add decoding+cropping as well.
     51 
     52     Args:
     53       image_name: a string of image file name (without suffix).
     54       parallelism: the number of concurrent decode_jpeg ops to be run.
     55       num_iters: number of iterations for evaluation.
     56       crop_during_decode: If true, use fused DecodeAndCropJpeg instead of
     57           separate decode and crop ops. It is ignored if crop_window is None.
     58       crop_window: if not None, crop the decoded image. Depending on
     59           crop_during_decode, cropping could happen during or after decoding.
     60       tile: if not None, tile the image to composite a larger fake image.
     61 
     62     Returns:
     63       The duration of the run in seconds.
     64     """
     65     ops.reset_default_graph()
     66 
     67     image_file_path = os.path.join(prefix_path, image_name)
     68 
     69     if tile is None:
     70       image_content = variable_scope.get_variable(
     71           'image_%s' % image_name,
     72           initializer=io_ops.read_file(image_file_path))
     73     else:
     74       single_image = image_ops.decode_jpeg(
     75           io_ops.read_file(image_file_path), channels=3, name='single_image')
     76       # Tile the image to composite a new larger image.
     77       tiled_image = array_ops.tile(single_image, tile)
     78       image_content = variable_scope.get_variable(
     79           'tiled_image_%s' % image_name,
     80           initializer=image_ops.encode_jpeg(tiled_image))
     81 
     82     with session.Session() as sess:
     83       sess.run(variables.global_variables_initializer())
     84       images = []
     85       for _ in xrange(parallelism):
     86         if crop_window is None:
     87           # No crop.
     88           image = image_ops.decode_jpeg(image_content, channels=3)
     89         elif crop_during_decode:
     90           # combined decode and crop.
     91           image = image_ops.decode_and_crop_jpeg(
     92               image_content, crop_window, channels=3)
     93         else:
     94           # separate decode and crop.
     95           image = image_ops.decode_jpeg(image_content, channels=3)
     96           image = image_ops.crop_to_bounding_box(
     97               image,
     98               offset_height=crop_window[0],
     99               offset_width=crop_window[1],
    100               target_height=crop_window[2],
    101               target_width=crop_window[3])
    102 
    103         images.append(image)
    104       r = control_flow_ops.group(*images)
    105 
    106       for _ in xrange(3):
    107         # Skip warm up time.
    108         sess.run(r)
    109 
    110       start_time = time.time()
    111       for _ in xrange(num_iters):
    112         sess.run(r)
    113     return time.time() - start_time
    114 
    115   def benchmarkDecodeJpegSmall(self):
    116     """Evaluate single DecodeImageOp for small size image."""
    117     num_iters = 10
    118     crop_window = [10, 10, 50, 50]
    119     for parallelism in [1, 100]:
    120       duration_decode = self._evalDecodeJpeg('small.jpg', parallelism,
    121                                              num_iters)
    122       duration_decode_crop = self._evalDecodeJpeg('small.jpg', parallelism,
    123                                                   num_iters, False, crop_window)
    124       duration_decode_after_crop = self._evalDecodeJpeg(
    125           'small.jpg', parallelism, num_iters, True, crop_window)
    126       self.report_benchmark(
    127           name='decode_jpeg_small_p%d' % (parallelism),
    128           iters=num_iters,
    129           wall_time=duration_decode)
    130       self.report_benchmark(
    131           name='decode_crop_jpeg_small_p%d' % (parallelism),
    132           iters=num_iters,
    133           wall_time=duration_decode_crop)
    134       self.report_benchmark(
    135           name='decode_after_crop_jpeg_small_p%d' % (parallelism),
    136           iters=num_iters,
    137           wall_time=duration_decode_after_crop)
    138 
    139   def benchmarkDecodeJpegMedium(self):
    140     """Evaluate single DecodeImageOp for medium size image."""
    141     num_iters = 10
    142     crop_window = [10, 10, 50, 50]
    143     for parallelism in [1, 100]:
    144       duration_decode = self._evalDecodeJpeg('medium.jpg', parallelism,
    145                                              num_iters)
    146       duration_decode_crop = self._evalDecodeJpeg('medium.jpg', parallelism,
    147                                                   num_iters, False, crop_window)
    148       duration_decode_after_crop = self._evalDecodeJpeg(
    149           'medium.jpg', parallelism, num_iters, True, crop_window)
    150       self.report_benchmark(
    151           name='decode_jpeg_medium_p%d' % (parallelism),
    152           iters=num_iters,
    153           wall_time=duration_decode)
    154       self.report_benchmark(
    155           name='decode_crop_jpeg_medium_p%d' % (parallelism),
    156           iters=num_iters,
    157           wall_time=duration_decode_crop)
    158       self.report_benchmark(
    159           name='decode_after_crop_jpeg_medium_p%d' % (parallelism),
    160           iters=num_iters,
    161           wall_time=duration_decode_after_crop)
    162 
    163   def benchmarkDecodeJpegLarge(self):
    164     """Evaluate single DecodeImageOp for large size image."""
    165     num_iters = 10
    166     crop_window = [10, 10, 50, 50]
    167     tile = [4, 4, 1]
    168     for parallelism in [1, 100]:
    169       # Tile the medium size image to composite a larger fake image.
    170       duration_decode = self._evalDecodeJpeg('medium.jpg', parallelism,
    171                                              num_iters, tile)
    172       duration_decode_crop = self._evalDecodeJpeg(
    173           'medium.jpg', parallelism, num_iters, False, crop_window, tile)
    174       duration_decode_after_crop = self._evalDecodeJpeg(
    175           'medium.jpg', parallelism, num_iters, True, crop_window, tile)
    176       self.report_benchmark(
    177           name='decode_jpeg_large_p%d' % (parallelism),
    178           iters=num_iters,
    179           wall_time=duration_decode)
    180       self.report_benchmark(
    181           name='decode_crop_jpeg_large_p%d' % (parallelism),
    182           iters=num_iters,
    183           wall_time=duration_decode_crop)
    184       self.report_benchmark(
    185           name='decode_after_crop_jpeg_large_p%d' % (parallelism),
    186           iters=num_iters,
    187           wall_time=duration_decode_after_crop)
    188 
    189 
    190 if __name__ == '__main__':
    191   test.main()
    192