| # Copyright 2017 The TensorFlow Authors. All Rights Reserved. |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| # ============================================================================== |
| """Tests for Grappler LayoutOptimizer.""" |
| |
| import numpy as np |
| |
| from tensorflow.core.protobuf import config_pb2 |
| from tensorflow.core.protobuf import device_properties_pb2 |
| from tensorflow.core.protobuf import rewriter_config_pb2 |
| from tensorflow.core.protobuf import saver_pb2 |
| from tensorflow.python.client import session |
| from tensorflow.python.framework import constant_op |
| from tensorflow.python.framework import dtypes |
| from tensorflow.python.framework import ops |
| from tensorflow.python.framework import random_seed |
| from tensorflow.python.framework import test_util |
| from tensorflow.python.grappler import cluster as gcluster |
| from tensorflow.python.grappler import tf_optimizer |
| from tensorflow.python.layers import convolutional as conv_layers |
| from tensorflow.python.ops import array_ops |
| from tensorflow.python.ops import gen_array_ops |
| from tensorflow.python.ops import gen_math_ops |
| from tensorflow.python.ops import gen_nn_ops |
| from tensorflow.python.ops import map_fn |
| from tensorflow.python.ops import math_ops |
| from tensorflow.python.ops import nn |
| from tensorflow.python.ops import random_ops |
| from tensorflow.python.ops import state_ops |
| from tensorflow.python.ops import variables |
| from tensorflow.python.platform import test |
| from tensorflow.python.training import gradient_descent |
| from tensorflow.python.training import saver as saver_lib |
| |
| |
| def _weight(shape): |
| """Generates a weight of a given shape.""" |
| return random_ops.truncated_normal(shape, seed=0, stddev=0.1) |
| |
| |
| def _bias(shape): |
| """Generates a bias of a given shape.""" |
| return constant_op.constant(0.1, shape=shape) |
| |
| |
| def _conv2d(x, w): |
| """Returns a 2d convolution layer with full stride.""" |
| return nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME') |
| |
| |
| def _max_pool_2x2(x): |
| """Downsamples a feature map by 2X.""" |
| return nn.max_pool( |
| x, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') |
| |
| |
| # Taken from tensorflow/examples/tutorials/mnist/mnist_deep.py |
| def _two_layer_model(x): |
| x_image = array_ops.reshape(x, [-1, 28, 28, 1]) |
| w_conv1 = _weight([5, 5, 1, 32]) |
| b_conv1 = _bias([32]) |
| h_conv1 = nn.relu(_conv2d(x_image, w_conv1) + b_conv1) |
| h_pool1 = _max_pool_2x2(h_conv1) |
| w_conv2 = _weight([5, 5, 32, 64]) |
| b_conv2 = _bias([64]) |
| h_conv2 = nn.relu(_conv2d(h_pool1, w_conv2) + b_conv2) |
| h_pool2 = _max_pool_2x2(h_conv2) |
| return h_pool2 |
| |
| |
| def _model_with_second_port(): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([2, 5, 5, 4], seed=0) |
| scale = constant_op.constant(0.1, shape=[4]) |
| offset = constant_op.constant(0.3, shape=[4]) |
| y, mean, _ = nn.fused_batch_norm(x, scale, offset) |
| mul = math_ops.add(y, mean) |
| output = array_ops.identity(mul) |
| return output |
| |
| |
| def _model_with_branch(x): |
| x_image = array_ops.reshape(x, [-1, 28, 28, 1]) |
| w_conv1 = _weight([5, 5, 1, 32]) |
| w_conv2 = _weight([5, 5, 1, 32]) |
| c_conv1 = _conv2d(x_image, w_conv1) |
| c_conv2 = _conv2d(x_image, w_conv2) |
| add = math_ops.add(c_conv1, c_conv2) |
| return add |
| |
| |
| def _model_with_vec_and_4d(x): |
| x_image = array_ops.reshape(x, [-1, 28, 28, 1]) |
| w_conv1 = _weight([5, 5, 1, 32]) |
| c_conv1 = _conv2d(x_image, w_conv1) |
| vector = constant_op.constant(6.4, shape=[32]) |
| add = math_ops.add(c_conv1, vector) |
| return add |
| |
| |
| def _loop(): |
| random_seed.set_random_seed(0) |
| x1 = random_ops.truncated_normal([1, 784], seed=0) |
| x2 = random_ops.truncated_normal([1, 784], seed=0) |
| x3 = random_ops.truncated_normal([1, 784], seed=0) |
| x4 = random_ops.truncated_normal([1, 784], seed=0) |
| elems = (x1, x2, x3, x4) |
| outputs = map_fn.map_fn(_two_layer_model, elems, dtype=dtypes.float32) |
| return outputs |
| |
| |
| def _loop_with_branch(): |
| random_seed.set_random_seed(0) |
| x1 = random_ops.truncated_normal([1, 784], seed=0) |
| x2 = random_ops.truncated_normal([1, 784], seed=0) |
| x3 = random_ops.truncated_normal([1, 784], seed=0) |
| x4 = random_ops.truncated_normal([1, 784], seed=0) |
| elems = (x1, x2, x3, x4) |
| outputs = map_fn.map_fn(_model_with_branch, elems, dtype=dtypes.float32) |
| return outputs |
| |
| |
| def _loop_with_vec_and_4d(): |
| random_seed.set_random_seed(0) |
| x1 = random_ops.truncated_normal([1, 784], seed=0) |
| x2 = random_ops.truncated_normal([1, 784], seed=0) |
| x3 = random_ops.truncated_normal([1, 784], seed=0) |
| x4 = random_ops.truncated_normal([1, 784], seed=0) |
| elems = (x1, x2, x3, x4) |
| outputs = map_fn.map_fn(_model_with_vec_and_4d, elems, dtype=dtypes.float32) |
| return outputs |
| |
| |
| def _get_config(layout_optimizer=True): |
| if layout_optimizer: |
| rewrite_options = rewriter_config_pb2.RewriterConfig( |
| layout_optimizer=rewriter_config_pb2.RewriterConfig.ON, |
| # do not remove duplicated nodes |
| arithmetic_optimization=rewriter_config_pb2.RewriterConfig.OFF) |
| else: |
| rewrite_options = rewriter_config_pb2.RewriterConfig( |
| layout_optimizer=rewriter_config_pb2.RewriterConfig.OFF, |
| # do not remove duplicated nodes |
| arithmetic_optimization=rewriter_config_pb2.RewriterConfig.OFF) |
| rewrite_options.min_graph_nodes = -1 |
| graph_options = config_pb2.GraphOptions( |
| rewrite_options=rewrite_options, build_cost_model=1) |
| config = config_pb2.ConfigProto(graph_options=graph_options) |
| config.graph_options.optimizer_options.opt_level = -1 |
| return config |
| |
| |
| def _simple_metagraph(depthwise=False): |
| random_seed.set_random_seed(0) |
| x = variables.Variable(random_ops.truncated_normal([1, 200, 200, 3], seed=0)) |
| conv = conv_layers.separable_conv2d if depthwise else conv_layers.conv2d |
| y = conv(x, 32, [3, 3]) |
| z = conv(y, 32, [3, 3]) |
| optimizer = gradient_descent.GradientDescentOptimizer(1e-4) |
| loss = math_ops.reduce_mean(z) |
| train_op = optimizer.minimize(loss) |
| graph = ops.get_default_graph() |
| graph.add_to_collection('train_op', train_op) |
| meta_graph = saver_lib.export_meta_graph(graph_def=graph.as_graph_def()) |
| return meta_graph |
| |
| |
| def _get_cluster(): |
| named_device = device_properties_pb2.NamedDevice() |
| named_device.name = '/GPU:0' |
| named_device.properties.type = 'GPU' |
| named_device.properties.num_cores = 24 |
| named_device.properties.frequency = 1000 |
| named_device.properties.environment['architecture'] = '4' |
| cluster = gcluster.Cluster(devices=[named_device]) |
| return cluster |
| |
| |
| def _is_transpose(node): |
| return node.endswith('TransposeNHWCToNCHW-LayoutOptimizer') or node.endswith( |
| 'TransposeNCHWToNHWC-LayoutOptimizer') or node.endswith( |
| 'TransposeNDHWCToNCDHW-LayoutOptimizer') or node.endswith( |
| 'TransposeNCDHWToNDHWC-LayoutOptimizer') |
| |
| |
| def _is_permute(node): |
| return node.endswith('VecPermuteNHWCToNCHW-LayoutOptimizer') or node.endswith( |
| 'VecPermuteNCHWToNHWC-LayoutOptimizer') |
| |
| |
| @test_util.for_all_test_methods(test_util.no_xla_auto_jit, |
| 'Test does not apply in XLA setting') |
| class LayoutOptimizerTest(test.TestCase): |
| """Tests the Grappler layout optimizer.""" |
| |
| def _assert_trans_nchw_to_nhwc(self, name, nodes): |
| self.assertIn(name + '-TransposeNCHWToNHWC-LayoutOptimizer', nodes) |
| |
| def _assert_trans_nhwc_to_nchw(self, name, nodes): |
| self.assertIn(name + '-TransposeNHWCToNCHW-LayoutOptimizer', nodes) |
| |
| def _assert_trans_ncdhw_to_ndhwc(self, name, nodes): |
| self.assertIn(name + '-TransposeNCDHWToNDHWC-LayoutOptimizer', nodes) |
| |
| def _assert_trans_ndhwc_to_ncdhw(self, name, nodes): |
| self.assertIn(name + '-TransposeNDHWCToNCDHW-LayoutOptimizer', nodes) |
| |
| def _assert_map_nhwc_to_nchw(self, name, nodes): |
| self.assertIn(name + '-DimMapNHWCToNCHW-LayoutOptimizer', nodes) |
| |
| def _assert_map_ndhwc_to_ncdhw(self, name, nodes): |
| self.assertIn(name + '-DataFormatDimMapNDHWCToNCDHW-LayoutOptimizer', nodes) |
| |
| def _assert_vec_nchw_to_nhwc(self, name, nodes): |
| self.assertIn(name + '-VecPermuteNCHWToNHWC-LayoutOptimizer', nodes) |
| |
| def _assert_vec_nhwc_to_nchw(self, name, nodes): |
| self.assertIn(name + '-VecPermuteNHWCToNCHW-LayoutOptimizer', nodes) |
| |
| def _assert_vec_ncdhw_to_ndhwc(self, name, nodes): |
| self.assertIn(name + '-DataFormatVecPermuteNCDHWToNDHWC-LayoutOptimizer', |
| nodes) |
| |
| def _assert_vec_ndhwc_to_ncdhw(self, name, nodes): |
| self.assertIn(name + '-DataFormatVecPermuteNDHWCToNCDHW-LayoutOptimizer', |
| nodes) |
| |
| def _train(self, checkpoint_path, layout_optimizer=False, restore=False): |
| ops.reset_default_graph() |
| graph = ops.get_default_graph() |
| with session.Session( |
| config=_get_config(layout_optimizer), graph=graph) as sess: |
| batch = 2 |
| height = 6 |
| width = 7 |
| input_channels = 3 |
| shape = [batch, height, width, input_channels] |
| image = array_ops.placeholder(dtype='float32', shape=shape) |
| conv1 = conv_layers.conv2d(image, 32, [3, 3]) |
| conv2 = conv_layers.conv2d(conv1, 32, [3, 3]) |
| optimizer = gradient_descent.GradientDescentOptimizer(0.01) |
| loss = math_ops.reduce_mean(conv2) |
| train_op = optimizer.minimize(loss) |
| saver = saver_lib.Saver(write_version=saver_pb2.SaverDef.V2) |
| |
| if restore: |
| saver.restore(sess, checkpoint_path) |
| else: |
| self.evaluate(variables.global_variables_initializer()) |
| |
| np.random.seed(0) |
| for _ in range(2): |
| image_val = np.random.rand(*shape).astype(np.float32) |
| sess.run([loss, train_op], feed_dict={image: image_val}) |
| |
| if restore: |
| all_vars = ops.get_collection(ops.GraphKeys.GLOBAL_VARIABLES) |
| all_vars_values = [var.eval(session=sess) for var in all_vars] |
| return all_vars_values |
| else: |
| saver.save(sess, checkpoint_path) |
| |
| @test_util.deprecated_graph_mode_only |
| def testTwoConvLayers(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| output = _two_layer_model(x) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('Relu_1-0-0', nodes) |
| |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testSplitWithNonConstAxis(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| dim = array_ops.placeholder(dtype='int32') |
| split = array_ops.split(conv, 2, axis=dim) |
| scale = constant_op.constant(0.1, shape=[32]) |
| offset = constant_op.constant(0.3, shape=[32]) |
| bn0 = nn.fused_batch_norm(split[0], scale, offset) |
| bn1 = nn.fused_batch_norm(split[1], scale, offset) |
| add = bn0[0] + bn1[0] |
| output = array_ops.identity(add) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={dim: 3}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata, feed_dict={dim: 3}) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('add_2-0-0', nodes) |
| self._assert_map_nhwc_to_nchw('split-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testSplitVWithNonConstAxis(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| dim = array_ops.placeholder(dtype='int32') |
| sizes = constant_op.constant([50, 10, 4], shape=[3]) |
| split = gen_array_ops.split_v( |
| value=conv, size_splits=sizes, axis=dim, num_split=3) |
| output = math_ops.reduce_sum(split[0]) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={dim: 3}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata, feed_dict={dim: 3}) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('SplitV-0-0', nodes) |
| self._assert_map_nhwc_to_nchw('SplitV-2', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testPadWithConstPaddings(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| paddings_val = [[1, 2], [3, 4], [5, 6], [7, 8]] |
| paddings = constant_op.constant( |
| paddings_val, dtype='int32', name='PaddingsConst') |
| pad = array_ops.pad(conv, paddings) |
| output = array_ops.identity(pad) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('Pad-0-0', nodes) |
| self.assertIn('Pad-1-LayoutOptimizer', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testReduceSum(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| reduce_sum = math_ops.reduce_sum(conv) |
| output = array_ops.identity(reduce_sum) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Three transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 1 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testCast(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| cast = math_ops.cast(conv, dtype='bool') |
| output = array_ops.identity(cast) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('Cast-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testSqueeze(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| reduce_sum = math_ops.reduce_sum(conv, axis=[1, 2]) |
| squeeze = array_ops.squeeze(reduce_sum) |
| output = array_ops.identity(squeeze) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Three transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 1 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testSqueezeAlongHW(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| reduce_sum = math_ops.reduce_sum(conv, axis=[1, 2], keepdims=True) |
| squeeze = array_ops.squeeze(reduce_sum, axis=[1, 2]) |
| output = array_ops.identity(squeeze) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Three transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 1 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testSqueezeAlongNHW(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| reduce_sum = math_ops.reduce_sum(conv, axis=[0, 1, 2], keepdims=True) |
| squeeze = array_ops.squeeze(reduce_sum, axis=[0, 1, 2]) |
| output = array_ops.identity(squeeze) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Three transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 1 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testReduceSumAlongHWC(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| reduce_sum = math_ops.reduce_sum(conv, axis=[1, 2, 3]) |
| output = array_ops.identity(reduce_sum) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Three transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 1 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testReduceSumAlongNHW(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| reduce_sum = math_ops.reduce_sum(conv, axis=[0, 1, 2]) |
| output = array_ops.identity(reduce_sum) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Three transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 1 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testReduceSumAlongC(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| reduce_sum = math_ops.reduce_sum(conv, axis=[3]) |
| output = array_ops.identity(reduce_sum) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Three transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 1 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testReduceSumAlongCKeepDims(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| reduce_sum = math_ops.reduce_sum(conv, axis=[3], keepdims=True) |
| output = array_ops.identity(reduce_sum) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('Sum-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testReduceSumAlongHKeepDims(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| reduce_sum = math_ops.reduce_sum(conv, axis=[2], keepdims=True) |
| output = array_ops.identity(reduce_sum) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testReduceSumAlongWCKeepDims(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| reduce_sum = math_ops.reduce_sum(conv, axis=[2, 3], keepdims=True) |
| output = array_ops.identity(reduce_sum) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testConcatWithControlDependency(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| axis = constant_op.constant(3) |
| var = variables.Variable(3) |
| assign = state_ops.assign(var, 6) |
| with ops.control_dependencies([assign]): |
| concat = array_ops.concat([conv, conv], axis) |
| output = array_ops.identity(concat) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('concat-0-0', nodes) |
| self.assertIn('concat-2-LayoutOptimizer', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testConcatWithControlDependencyFor5DTensor(self): |
| if not test.is_gpu_available(cuda_only=True): |
| self.skipTest('GPU required') |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([2, 2, 14, 14, 1], seed=0) |
| w = random_ops.truncated_normal([2, 2, 2, 1, 2], seed=0) |
| strides = [1, 1, 1, 1, 1] |
| y = gen_nn_ops.conv3d(x, w, strides, 'SAME') |
| axis = constant_op.constant(4) |
| var = variables.Variable(3) |
| assign = state_ops.assign(var, 6) |
| with ops.control_dependencies([assign]): |
| concat = array_ops.concat([y, y], axis) |
| output = array_ops.identity(concat) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3D-0', nodes) |
| self._assert_trans_ncdhw_to_ndhwc('concat-0-0', nodes) |
| self._assert_map_ndhwc_to_ncdhw('concat-2', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testFill(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = array_ops.placeholder(dtype='float32') |
| conv = _two_layer_model(x) |
| shape = array_ops.shape(conv) |
| scalar = array_ops.constant(5.7) |
| fill = array_ops.fill(shape, scalar) |
| output = array_ops.identity(fill) |
| |
| x_val = [3.4] * 784 |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={x: x_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={ |
| x: x_val |
| }) |
| |
| nodes = [] |
| num_transposes = 0 |
| num_vec_permute = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| if _is_permute(node.name): |
| num_vec_permute += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| # Two vector permute nodes were initially added in the Expand phase of |
| # LayoutOptimizer; they cancelled out each other in the Collapse phase. |
| expected_vec_permute = 0 |
| self.assertEqual(expected_vec_permute, num_vec_permute) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('Fill-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testTile(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| multiple = array_ops.placeholder(dtype='int32') |
| tile = array_ops.tile(conv, multiple) |
| output = array_ops.identity(tile) |
| |
| multiple_val = [2, 3, 4, 1] |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={multiple: multiple_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={ |
| multiple: multiple_val |
| }) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('Tile-0-0', nodes) |
| self._assert_vec_nhwc_to_nchw('Tile-1', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testReverseWithConstDims(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| dims = constant_op.constant([3, 1], name='DimsConst') |
| reverse = array_ops.reverse(conv, dims) |
| output = array_ops.identity(reverse) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('ReverseV2-0-0', nodes) |
| self.assertIn('ReverseV2-1-LayoutOptimizer', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testReverseWithNonConstDims(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| dims = array_ops.placeholder(dtype='int32') |
| reverse = array_ops.reverse(conv, dims) |
| output = array_ops.identity(reverse) |
| |
| dims_val = [2, 3] |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={dims: dims_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={ |
| dims: dims_val |
| }) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('ReverseV2-0-0', nodes) |
| self._assert_map_nhwc_to_nchw('ReverseV2-1', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testSelectOp(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| add = math_ops.add(conv, conv) |
| mean = math_ops.reduce_mean(conv) |
| condition = math_ops.less(conv, mean) |
| select = gen_math_ops.select(condition, conv, add) |
| output = array_ops.identity(select) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('Select-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testSelectOpConditionUnknownShape(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| add = math_ops.add(conv, conv) |
| condition = array_ops.placeholder(dtype='bool') |
| select = gen_math_ops.select(condition, conv, add) |
| output = array_ops.identity(select) |
| |
| condition_val = np.zeros((1, 7, 7, 64)) |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={condition: condition_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={condition: condition_val}) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 3 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testSelectOpScalarCondition(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| add = math_ops.add(conv, conv) |
| condition = constant_op.constant(True) |
| select = gen_math_ops.select(condition, conv, add) |
| output = array_ops.identity(select) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('Select-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testPadWithNonConstPaddings(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| paddings = array_ops.placeholder(dtype='int32') |
| pad = array_ops.pad(conv, paddings) |
| output = array_ops.identity(pad) |
| |
| paddings_val = [[1, 2], [3, 4], [5, 6], [7, 8]] |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={paddings: paddings_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={ |
| paddings: paddings_val |
| }) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('Pad-0-0', nodes) |
| self._assert_vec_nhwc_to_nchw('Pad-1', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testMaxPoolV2(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| ksize = constant_op.constant([1, 2, 3, 1], shape=[4]) |
| strides = array_ops.placeholder(dtype='int32', shape=[4]) |
| max_pool = gen_nn_ops.max_pool_v2(conv, ksize, strides, 'VALID') |
| output = array_ops.identity(max_pool) |
| |
| strides_val = [1, 3, 2, 1] |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={strides: strides_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={ |
| strides: strides_val |
| }) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('MaxPoolV2-0-0', nodes) |
| self._assert_vec_nhwc_to_nchw('MaxPoolV2-2', nodes) |
| self.assertIn('MaxPoolV2-1-LayoutOptimizer', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testMaxPoolGradV2(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| ksize = constant_op.constant([1, 2, 3, 1], shape=[4]) |
| strides = array_ops.placeholder(dtype='int32', shape=[4]) |
| max_pool_grad = gen_nn_ops.max_pool_grad_v2(conv, conv, conv, ksize, |
| strides, 'VALID') |
| output = array_ops.identity(max_pool_grad) |
| |
| strides_val = [1, 3, 2, 1] |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={strides: strides_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={ |
| strides: strides_val |
| }) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('MaxPoolGradV2-0-0', nodes) |
| self._assert_vec_nhwc_to_nchw('MaxPoolGradV2-4', nodes) |
| self.assertIn('MaxPoolGradV2-3-LayoutOptimizer', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testLeakyRelu(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([4, 14, 14, 1], seed=0) |
| w = random_ops.truncated_normal([2, 2, 1, 2], seed=0) |
| y = nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME') |
| y = nn.leaky_relu(y, alpha=0.2) |
| output = array_ops.identity(y) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nchw_to_nhwc('LeakyRelu-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testLeakyReluGrad(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([4, 14, 14, 1], seed=0) |
| w = random_ops.truncated_normal([2, 2, 1, 1], seed=0) |
| y = nn.conv2d(x, w, strides=[1, 1, 1, 1], padding='SAME') |
| y = gen_nn_ops.leaky_relu_grad(y, x, alpha=0.2) |
| output = array_ops.identity(y) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 3 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('LeakyReluGrad-1', nodes) |
| self._assert_trans_nchw_to_nhwc('LeakyReluGrad-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testLeakyReluGradFor5DTensors(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 4, 2, 3, 3], seed=0) |
| w = random_ops.truncated_normal([2, 2, 2, 3, 3], seed=0) |
| y = gen_nn_ops.conv3d(x, w, [1, 1, 1, 1, 1], 'SAME') |
| y = gen_nn_ops.leaky_relu_grad(y, x, alpha=0.2) |
| output = array_ops.identity(y) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 3 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_ndhwc_to_ncdhw('LeakyReluGrad-1', nodes) |
| self._assert_trans_ncdhw_to_ndhwc('LeakyReluGrad-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testReduceOpsFor5DTensors(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 4, 2, 3, 3], seed=0) |
| w = random_ops.truncated_normal([2, 2, 2, 3, 3], seed=0) |
| conv3d = gen_nn_ops.conv3d(x, w, [1, 1, 1, 1, 1], 'SAME') |
| y = math_ops.reduce_mean(conv3d, [0, 1, 2, 3], keepdims=True) |
| output = array_ops.identity(y) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # The reduce op Mean needs to dim map the input reduce index to NCDHW. |
| # Then, the output needs to be tranposed back to NDHWC. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3D-0', nodes) |
| self._assert_map_ndhwc_to_ncdhw('Mean-1', nodes) |
| self._assert_trans_ncdhw_to_ndhwc('Mean-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testBinaryOpsFor5DTensors(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 4, 2, 3, 3], seed=0) |
| w = random_ops.truncated_normal([2, 2, 2, 3, 3], seed=0) |
| mean = random_ops.truncated_normal([1, 1, 1, 1, 3], seed=0) |
| variance = random_ops.truncated_normal([1, 1, 1, 1, 3], seed=0) |
| gamma = random_ops.truncated_normal([1, 1, 1, 1, 3], seed=0) |
| beta = random_ops.truncated_normal([1, 1, 1, 1, 3], seed=0) |
| conv3d = gen_nn_ops.conv3d(x, w, [1, 1, 1, 1, 1], 'SAME') |
| y = nn.batch_normalization( |
| conv3d, |
| mean=mean, |
| variance=variance, |
| scale=gamma, |
| offset=beta, |
| variance_epsilon=0.001) |
| output = array_ops.identity(y) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # The binary ops mul_1 and add_1 in batch norm need to transpose one of |
| # the two inputs to NCDHW. The other input has already been tranposed via |
| # Conv3D. |
| expected_num_transposes = 4 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3D-0', nodes) |
| self._assert_trans_ndhwc_to_ncdhw('batchnorm/mul_1-1', nodes) |
| self._assert_trans_ndhwc_to_ncdhw('batchnorm/add_1-1', nodes) |
| self._assert_trans_ncdhw_to_ndhwc('batchnorm/add_1-0-0', nodes) |
| |
| @test_util.deprecated_graph_mode_only |
| def testBatchNorm3D(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x_3d = random_ops.truncated_normal([1, 4, 2, 3, 3], seed=0) |
| filters = random_ops.truncated_normal([2, 2, 2, 3, 3], seed=0) |
| strides_val = [1, 1, 1, 1, 1] |
| scale = constant_op.constant(0.1, shape=[3]) |
| offset = constant_op.constant(0.3, shape=[3]) |
| conv3d = gen_nn_ops.conv3d(x_3d, filters, strides_val, 'SAME') |
| y, _, _ = nn.fused_batch_norm(conv3d, scale, offset, data_format='NDHWC') |
| output = array_ops.identity(y) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3D-0', nodes) |
| self._assert_trans_ncdhw_to_ndhwc('FusedBatchNormV3-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testBatchNormGrad3D(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x_3d = random_ops.truncated_normal([1, 4, 2, 3, 3], seed=0) |
| filters = random_ops.truncated_normal([2, 2, 2, 3, 3], seed=0) |
| strides_val = [1, 1, 1, 1, 1] |
| scale = constant_op.constant(0.1, shape=[3]) |
| offset = constant_op.constant(0.3, shape=[3]) |
| mean = constant_op.constant(0.1, shape=[3]) |
| variance = constant_op.constant(0.3, shape=[3]) |
| conv3d = gen_nn_ops.conv3d(x_3d, filters, strides_val, 'SAME') |
| y, running_mean, running_var, r0, r1, r2 = gen_nn_ops.fused_batch_norm_v3( |
| conv3d, |
| scale, |
| offset, |
| mean, |
| variance, |
| epsilon=1.001e-5, |
| exponential_avg_factor=1.0, |
| data_format='NDHWC', |
| is_training=True, |
| name='batch_norm') |
| dx, dscale, doffset, _, _ = gen_nn_ops.fused_batch_norm_grad_v3( |
| y, |
| x_3d, |
| scale, |
| r0, |
| r1, |
| r2, |
| epsilon=1.001e-5, |
| data_format='NDHWC', |
| is_training=True) |
| output = array_ops.identity(dx) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 3 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3D-0', nodes) |
| self._assert_trans_ndhwc_to_ncdhw('FusedBatchNormGradV3-1', nodes) |
| self._assert_trans_ncdhw_to_ndhwc('FusedBatchNormGradV3-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testConv3D(self): |
| if not test.is_gpu_available(cuda_only=True): |
| self.skipTest('GPU required') |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([2, 2, 14, 14, 1], seed=0) |
| w = random_ops.truncated_normal([2, 2, 2, 1, 2], seed=0) |
| strides = [1, 1, 1, 1, 1] |
| y = gen_nn_ops.conv3d(x, w, strides, 'SAME') |
| output = array_ops.identity(y) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3D-0', nodes) |
| self._assert_trans_ncdhw_to_ndhwc('Conv3D-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testConv3DBackpropInput(self): |
| if not test.is_gpu_available(cuda_only=True): |
| self.skipTest('GPU required') |
| random_seed.set_random_seed(0) |
| dy = random_ops.truncated_normal([2, 2, 14, 14, 1], seed=0) |
| w = random_ops.truncated_normal([2, 2, 2, 1, 1], seed=0) |
| strides = [1, 1, 1, 1, 1] |
| x_shape = array_ops.shape(dy) |
| dx = gen_nn_ops.conv3d_backprop_input_v2(x_shape, w, dy, strides, 'SAME') |
| output = array_ops.identity(dx) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_vec_ndhwc_to_ncdhw('Conv3DBackpropInputV2-0', nodes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3DBackpropInputV2-2', nodes) |
| self._assert_trans_ncdhw_to_ndhwc('Conv3DBackpropInputV2-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testConv3DBackpropFilter(self): |
| if not test.is_gpu_available(cuda_only=True): |
| self.skipTest('GPU required') |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([2, 2, 14, 14, 1], seed=0) |
| dy = random_ops.truncated_normal([2, 2, 14, 14, 1], seed=0) |
| strides = [1, 1, 1, 1, 1] |
| w_shape = constant_op.constant([2, 2, 2, 1, 1], shape=[5]) |
| dw = gen_nn_ops.conv3d_backprop_filter_v2(x, w_shape, dy, strides, 'SAME') |
| output = array_ops.identity(dw) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3DBackpropFilterV2-0', nodes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3DBackpropFilterV2-2', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testBiasAddFor5DTensor(self): |
| if not test.is_gpu_available(cuda_only=True): |
| self.skipTest('GPU required') |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([2, 2, 14, 14, 1], seed=0) |
| w = random_ops.truncated_normal([2, 2, 2, 1, 2], seed=0) |
| b = random_ops.truncated_normal([2], seed=0) |
| strides = [1, 1, 1, 1, 1] |
| y = gen_nn_ops.conv3d(x, w, strides, 'SAME') |
| y = gen_nn_ops.bias_add(y, b, 'NHWC') |
| output = array_ops.identity(y) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3D-0', nodes) |
| self._assert_trans_ncdhw_to_ndhwc('BiasAdd-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testBiasAddGradFor5DTensor(self): |
| if not test.is_gpu_available(cuda_only=True): |
| self.skipTest('GPU required') |
| random_seed.set_random_seed(0) |
| dy = random_ops.truncated_normal([2, 2, 14, 14, 1], seed=0) |
| w = random_ops.truncated_normal([2, 2, 2, 1, 1], seed=0) |
| strides = [1, 1, 1, 1, 1] |
| dy_shape = array_ops.shape(dy) |
| dx = gen_nn_ops.conv3d_backprop_input_v2(dy_shape, w, dy, strides, 'SAME') |
| db = gen_nn_ops.bias_add_grad(dx, 'NHWC') |
| output = array_ops.identity(db) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # The output of Conv3DBackpropInputV2 won't be converted back to NDHWC |
| # because of the BiasAddGrad. |
| expected_num_transposes = 1 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_vec_ndhwc_to_ncdhw('Conv3DBackpropInputV2-0', nodes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3DBackpropInputV2-2', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testSliceWithNonConstAxis(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| size = array_ops.placeholder(dtype='int32') |
| s = array_ops.slice(conv, [0, 0, 0, 0], size) |
| output = array_ops.identity(s) |
| |
| size_val = [1, 2, 3, 4] |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={size: size_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={ |
| size: size_val |
| }) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('Slice-0-0', nodes) |
| self._assert_vec_nhwc_to_nchw('Slice-2', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testSliceWithNonConstAxisFor5DTensor(self): |
| if not test.is_gpu_available(cuda_only=True): |
| self.skipTest('GPU required') |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([2, 2, 14, 14, 1], seed=0) |
| w = random_ops.truncated_normal([2, 2, 2, 1, 2], seed=0) |
| strides = [1, 1, 1, 1, 1] |
| y = gen_nn_ops.conv3d(x, w, strides, 'SAME') |
| size = array_ops.placeholder(dtype='int32') |
| s = array_ops.slice(y, [0, 0, 0, 0, 0], size) |
| output = array_ops.identity(s) |
| |
| size_val = [1, 1, 2, 2, 1] |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={size: size_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={size: size_val}) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3D-0', nodes) |
| self._assert_trans_ncdhw_to_ndhwc('Slice-0-0', nodes) |
| self._assert_vec_ndhwc_to_ncdhw('Slice-2', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testStridedSliceWithNonConstAxis(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| end = array_ops.placeholder(dtype='int32') |
| s = array_ops.strided_slice(conv, [0, 0, 0, 0], end, strides=[1, 2, 3, 1]) |
| output = array_ops.identity(s) |
| |
| end_val = [1, 2, 3, 4] |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={end: end_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={ |
| end: end_val |
| }) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('StridedSlice-0-0', nodes) |
| self._assert_vec_nhwc_to_nchw('StridedSlice-2', nodes) |
| self.assertIn('StridedSlice-1-LayoutOptimizer', nodes) |
| self.assertIn('StridedSlice-3-LayoutOptimizer', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testStridedSliceWithMask1011(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| # This will generate a StridedSlice op with begin mask and |
| # end mask 11(1011). |
| s = conv[:, :, 1:-1, :] |
| output = array_ops.identity(s) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('strided_slice-0-0', nodes) |
| self.assertIn('strided_slice-1-LayoutOptimizer', nodes) |
| self.assertIn('strided_slice-2-LayoutOptimizer', nodes) |
| self.assertIn('strided_slice-3-LayoutOptimizer', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testStridedSliceWithMask0111(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| # This will generate a StridedSlice op with begin mask and |
| # end mask 7(0111). |
| s = conv[:, :, :, 1:-1] |
| output = array_ops.identity(s) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('strided_slice-0-0', nodes) |
| self.assertIn('strided_slice-1-LayoutOptimizer', nodes) |
| self.assertIn('strided_slice-2-LayoutOptimizer', nodes) |
| self.assertIn('strided_slice-3-LayoutOptimizer', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testStridedSliceGradWithNonConstAxis(self): |
| if test.is_gpu_available(cuda_only=True): |
| random_seed.set_random_seed(0) |
| x = random_ops.truncated_normal([1, 784], seed=0) |
| conv = _two_layer_model(x) |
| end = array_ops.placeholder(dtype='int32') |
| shape = array_ops.shape(conv) |
| end_val = [1, 2, 3, 4] |
| s = array_ops.strided_slice( |
| conv, [0, 0, 0, 0], end_val, strides=[1, 2, 3, 1]) |
| s_grad = array_ops.strided_slice_grad(shape, [0, 0, 0, 0], end, |
| [1, 2, 3, 1], s) |
| output = array_ops.identity(s_grad) |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={end: end_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={ |
| end: end_val |
| }) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('StridedSliceGrad-0-0', nodes) |
| self._assert_vec_nhwc_to_nchw('StridedSliceGrad-2', nodes) |
| self.assertIn('StridedSlice-1-LayoutOptimizer', nodes) |
| self.assertIn('StridedSlice-2-LayoutOptimizer', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testShapeN(self): |
| if test.is_gpu_available(cuda_only=True): |
| x = array_ops.placeholder(dtype='float32') |
| conv = _two_layer_model(x) |
| shapen = array_ops.shape_n([conv, conv]) |
| output = math_ops.add(shapen[0], shapen[1]) |
| |
| x_val = [1.7] * 784 |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={x: x_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={ |
| x: x_val |
| }) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 1 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_vec_nchw_to_nhwc('ShapeN-0-0', nodes) |
| self.assertAllEqual(output_val_ref, output_val) |
| |
| @test_util.deprecated_graph_mode_only |
| def testShapeNFor5DTensor(self): |
| if not test.is_gpu_available(cuda_only=True): |
| self.skipTest('GPU required') |
| h = array_ops.placeholder(dtype='float32') |
| x = array_ops.reshape(h, [-1, 2, 14, 14, 1]) |
| w = random_ops.truncated_normal([2, 2, 2, 1, 2], seed=0) |
| strides = [1, 1, 1, 1, 1] |
| y = gen_nn_ops.conv3d(x, w, strides, 'SAME') |
| shapen = array_ops.shape_n([y, y]) |
| output = math_ops.add(shapen[0], shapen[1]) |
| |
| x_val = [1.7] * 784 |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={h: x_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata, feed_dict={h: x_val}) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 1 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3D-0', nodes) |
| self._assert_vec_ncdhw_to_ndhwc('ShapeN-0-0', nodes) |
| self._assert_vec_ncdhw_to_ndhwc('ShapeN-1-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testIdentityNFor4DAnd5DTensors(self): |
| if not test.is_gpu_available(cuda_only=True): |
| self.skipTest('GPU required') |
| h = array_ops.placeholder(dtype='float32') |
| x = array_ops.reshape(h, [-1, 2, 14, 14, 1]) |
| w = random_ops.truncated_normal([2, 2, 2, 1, 4], seed=0) |
| strides = [1, 1, 1, 1, 1] |
| y = gen_nn_ops.conv3d(x, w, strides, 'SAME') |
| x1 = array_ops.reshape(h, [-1, 784]) |
| y1 = _two_layer_model(x1) |
| outputs = array_ops.identity_n([y1, y]) |
| new_x0 = array_ops.reshape(outputs[0], [-1, 2, 14, 14, 1]) |
| new_x1 = array_ops.reshape(outputs[1], [-1, 2, 14, 14, 1]) |
| output = math_ops.add(new_x0, new_x1) |
| |
| x_val = [1.7] * 784 |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={h: x_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata, feed_dict={h: x_val}) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 4 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_ndhwc_to_ncdhw('Conv3D-0', nodes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self._assert_trans_ncdhw_to_ndhwc('IdentityN-1-0', nodes) |
| self._assert_trans_nchw_to_nhwc('IdentityN-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testShapeNFollowedByNotConvertibleNodeReshape(self): |
| if test.is_gpu_available(cuda_only=True): |
| x = array_ops.placeholder(dtype='float32') |
| conv = _two_layer_model(x) |
| conv_reshape = array_ops.reshape(conv, [1, 1, 1, -1]) |
| shapen = array_ops.shape_n([conv, conv_reshape]) |
| shape = array_ops.identity(shapen[1]) |
| ones = array_ops.ones(shape) |
| output = math_ops.add_n([conv_reshape, ones]) |
| |
| x_val = [1.7] * 784 |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = sess.run(output, feed_dict={x: x_val}) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run( |
| output, run_metadata=metadata, feed_dict={x: x_val}) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('Conv2D-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testLoop(self): |
| if test.is_gpu_available(cuda_only=True): |
| output = _loop() |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| # Four transposes were initially added in the Expand phase of |
| # LayoutOptimizer; two of them are cancelled out in the Collapse phase. |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('map/while/Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('map/while/MaxPool_1-0-2', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testLoopWithBranch(self): |
| if test.is_gpu_available(cuda_only=True): |
| output = _loop_with_branch() |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 3 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('map/while/Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('map/while/Add_1-0-2', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testLoopWithVecAnd4D(self): |
| if test.is_gpu_available(cuda_only=True): |
| output = _loop_with_vec_and_4d() |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('map/while/Conv2D-0', nodes) |
| self._assert_trans_nchw_to_nhwc('map/while/Add_1-0-2', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testBinaryOpSecondPort(self): |
| if test.is_gpu_available(cuda_only=True): |
| output = _model_with_second_port() |
| |
| with session.Session(config=_get_config(False)) as sess: |
| output_val_ref = self.evaluate(output) |
| |
| with session.Session(config=_get_config()) as sess: |
| metadata = config_pb2.RunMetadata() |
| output_val = sess.run(output, run_metadata=metadata) |
| |
| nodes = [] |
| num_transposes = 0 |
| for node in metadata.cost_graph.node: |
| if _is_transpose(node.name): |
| num_transposes += 1 |
| nodes.append(node.name) |
| |
| expected_num_transposes = 2 |
| self.assertEqual(expected_num_transposes, num_transposes) |
| self._assert_trans_nhwc_to_nchw('FusedBatchNormV3-0', nodes) |
| self._assert_trans_nchw_to_nhwc('Add-0-0', nodes) |
| self.assertAllClose(output_val_ref, output_val, atol=1e-3) |
| |
| @test_util.deprecated_graph_mode_only |
| def testGradient(self): |
| meta_graph = _simple_metagraph() |
| config = config_pb2.ConfigProto() |
| config.graph_options.rewrite_options.CopyFrom( |
| rewriter_config_pb2.RewriterConfig( |
| layout_optimizer=rewriter_config_pb2.RewriterConfig.ON, |
| min_graph_nodes=-1)) |
| optimized_graph = tf_optimizer.OptimizeGraph( |
| config, meta_graph, cluster=_get_cluster()) |
| |
| found = 0 |
| for node in optimized_graph.node: |
| if node.op in ['Conv2D', 'Conv2DBackpropFilter', 'Conv2DBackpropInput']: |
| found += 1 |
| self.assertEqual(node.attr['data_format'].s, b'NCHW') |
| self.assertEqual(found, 5) |
| |
| @test_util.deprecated_graph_mode_only |
| def testDepthwise(self): |
| meta_graph = _simple_metagraph(depthwise=True) |
| config = config_pb2.ConfigProto() |
| config.graph_options.rewrite_options.CopyFrom( |
| rewriter_config_pb2.RewriterConfig( |
| layout_optimizer=rewriter_config_pb2.RewriterConfig.ON, |
| min_graph_nodes=-1)) |
| optimized_graph = tf_optimizer.OptimizeGraph( |
| config, meta_graph, cluster=_get_cluster()) |
| |
| found = 0 |
| for node in optimized_graph.node: |
| if node.op in [ |
| 'DepthwiseConv2dNative', 'DepthwiseConv2dNativeBackpropFilter', |
| 'DepthwiseConv2dNativeBackpropInput' |
| ]: |
| found += 1 |
| self.assertEqual(node.attr['data_format'].s, b'NCHW') |
| self.assertEqual(found, 6) |
| |
| def testCheckpointCompatibility(self): |
| if not test.is_gpu_available(cuda_only=True): |
| self.skipTest('GPU required') |
| |
| checkpoint_path = self.get_temp_dir() |
| self._train(checkpoint_path) |
| vars_expected = self._train(checkpoint_path, restore=True) |
| vars_layout_optimized = self._train( |
| checkpoint_path, restore=True, layout_optimizer=True) |
| |
| for var_expected, var_layout_optimized in zip(vars_expected, |
| vars_layout_optimized): |
| self.assertAllClose(var_expected, var_layout_optimized, atol=1e-6) |
| |
| |
| if __name__ == '__main__': |
| test.main() |