Home | History | Annotate | Download | only in kernel_tests
      1 # Copyright 2015 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 various tensorflow.ops.tf."""
     16 
     17 from __future__ import absolute_import
     18 from __future__ import division
     19 from __future__ import print_function
     20 
     21 from absl.testing import parameterized
     22 import numpy as np
     23 
     24 from tensorflow.core.framework import node_def_pb2
     25 from tensorflow.python.framework import constant_op
     26 from tensorflow.python.framework import dtypes
     27 from tensorflow.python.framework import errors_impl
     28 from tensorflow.python.framework import importer
     29 from tensorflow.python.framework import sparse_tensor
     30 from tensorflow.python.framework import test_util
     31 from tensorflow.python.ops import array_ops
     32 from tensorflow.python.ops import gradient_checker
     33 from tensorflow.python.ops import gradients_impl
     34 from tensorflow.python.platform import test
     35 
     36 
     37 # TODO(zongheng): it'd be great to factor out this function and various random
     38 # SparseTensor gen funcs.
     39 def _sparsify(x, thresh=0.5, index_dtype=np.int64):
     40   x[x < thresh] = 0
     41 
     42   non_zero = np.where(x)
     43   x_indices = np.vstack(non_zero).astype(index_dtype).T
     44   x_values = x[non_zero]
     45   x_shape = x.shape
     46 
     47   return sparse_tensor.SparseTensor(
     48       indices=x_indices, values=x_values, dense_shape=x_shape), len(x_values)
     49 
     50 
     51 class ShapeOpsTest(test.TestCase):
     52 
     53   def _compareShape(self, x, use_gpu=False):
     54     np_ans = np.array(np.shape(x))
     55     with self.cached_session(use_gpu=use_gpu):
     56       tf_ans = array_ops.shape(x)
     57       tf_ans_64 = array_ops.shape(x, out_type=dtypes.int64)
     58       result = self.evaluate(tf_ans)
     59       result_64 = self.evaluate(tf_ans_64)
     60     self.assertAllEqual(np_ans, result)
     61     self.assertAllEqual(np_ans, result_64)
     62     self.assertShapeEqual(np_ans, tf_ans)
     63 
     64   def _compareShapeSparse(self, x_np, use_gpu=False):
     65     np_ans = np.array(np.shape(x_np))
     66     x_tf, unused_nnz = _sparsify(x_np)
     67     with self.cached_session(use_gpu=use_gpu):
     68       tf_ans = array_ops.shape(x_tf)
     69       result = self.evaluate(tf_ans)
     70     self.assertAllEqual(np_ans, result)
     71     self.assertShapeEqual(np_ans, tf_ans)
     72 
     73   def _compareShapeN(self, x, use_gpu=False):
     74     np_ans = np.array(np.shape(x))
     75     with self.cached_session(use_gpu=use_gpu) as sess:
     76       tf_ans = array_ops.shape_n([x, x, x])
     77       tf_ans_64 = array_ops.shape_n([x, x, x], out_type=dtypes.int64)
     78       result = self.evaluate(tf_ans)
     79       result_64 = self.evaluate(tf_ans_64)
     80     for i in range(3):
     81       self.assertAllEqual(np_ans, result[i])
     82       self.assertAllEqual(np_ans, result_64[i])
     83       self.assertShapeEqual(np_ans, tf_ans[i])
     84 
     85   def _compareRank(self, x, use_gpu=False):
     86     np_ans = np.asarray(np.ndim(x))
     87     with self.cached_session(use_gpu=use_gpu):
     88       tf_ans = array_ops.rank(x)
     89       result = self.evaluate(tf_ans)
     90     self.assertAllEqual(np_ans, result)
     91     self.assertShapeEqual(np_ans, tf_ans)
     92 
     93   def _compareRankSparse(self, x_np, use_gpu=False):
     94     np_ans = np.asarray(np.ndim(x_np))
     95     x_tf, unused_nnz = _sparsify(x_np)
     96     with self.cached_session(use_gpu=use_gpu):
     97       tf_ans = array_ops.rank(x_tf)
     98       result = self.evaluate(tf_ans)
     99     self.assertAllEqual(np_ans, result)
    100     self.assertShapeEqual(np_ans, tf_ans)
    101 
    102   def _compareSize(self, x, use_gpu=False):
    103     np_ans = np.asarray(np.size(x))
    104     with self.cached_session(use_gpu=use_gpu):
    105       tf_ans = array_ops.size(x)
    106       result = self.evaluate(tf_ans)
    107       tf_ans_64 = array_ops.size(x, out_type=dtypes.int64)
    108       result_64 = self.evaluate(tf_ans_64)
    109     self.assertAllEqual(np_ans, result)
    110     self.assertAllEqual(np_ans, result_64)
    111     self.assertShapeEqual(np_ans, tf_ans)
    112 
    113   def _compareSizeSparse(self, x_np, use_gpu=False):
    114     np_ans = np.asarray(np.size(x_np))
    115     x_tf, unused_nnz = _sparsify(x_np)
    116     with self.cached_session(use_gpu=use_gpu):
    117       tf_ans = array_ops.size(x_tf)
    118       result = self.evaluate(tf_ans)
    119     self.assertAllEqual(np_ans, result)
    120     self.assertShapeEqual(np_ans, tf_ans)
    121 
    122   def _testCpu(self, x):
    123     self._compareShape(x, use_gpu=False)
    124     self._compareShapeN(x, use_gpu=False)
    125     self._compareRank(x, use_gpu=False)
    126     self._compareSize(x, use_gpu=False)
    127     self._compareShapeSparse(x, use_gpu=False)
    128     self._compareRankSparse(x, use_gpu=False)
    129     self._compareSizeSparse(x, use_gpu=False)
    130 
    131   def _testGpu(self, x):
    132     self._compareShape(x, use_gpu=True)
    133     self._compareShapeN(x, use_gpu=True)
    134     self._compareRank(x, use_gpu=True)
    135     self._compareSize(x, use_gpu=True)
    136     self._compareShapeSparse(x, use_gpu=True)
    137     self._compareRankSparse(x, use_gpu=True)
    138     self._compareSizeSparse(x, use_gpu=True)
    139 
    140   def _testAll(self, x):
    141     self._testCpu(x)
    142     self._testGpu(x)
    143 
    144   def testBasic(self):
    145     self._testAll(np.random.randn(2))
    146     self._testAll(np.random.randn(2, 3))
    147     self._testAll(np.random.randn(2, 3, 5))
    148     self._testAll(np.random.randn(2, 3, 5, 7))
    149     self._testAll(np.random.randn(2, 3, 5, 7, 11))
    150     self._testAll(np.random.randn(2, 3, 5, 7, 11, 13))
    151 
    152   def testBool(self):
    153     self._testAll(np.random.choice((False, True), size=(2,)))
    154     self._testAll(np.random.choice((False, True), size=(2, 3)))
    155     self._testAll(np.random.choice((False, True), size=(2, 3, 5)))
    156     self._testAll(np.random.choice((False, True), size=(2, 3, 5, 7)))
    157     self._testAll(np.random.choice((False, True), size=(2, 3, 5, 7, 11)))
    158     self._testAll(np.random.choice((False, True), size=(2, 3, 5, 7, 11, 13)))
    159 
    160   # Disabled because it takes too long to run, but manually verified
    161   # as passing at time of writing.
    162   def _test64BitOutput(self):
    163     with self.cached_session():
    164       inp = array_ops.zeros([2**31])
    165       num_elements = array_ops.size_internal(
    166           inp, optimize=False, out_type=dtypes.int64)
    167       self.assertEqual(2**31, self.evaluate(num_elements))
    168 
    169     # Too large for tf.int32 output.
    170     with self.assertRaises(errors_impl.InvalidArgumentError):
    171       with self.cached_session():
    172         inp = array_ops.zeros([2**31])
    173         num_elements = array_ops.size_internal(
    174             inp, optimize=False, out_type=dtypes.int32)
    175         self.assertEqual(2**31, self.evaluate(num_elements))
    176 
    177   def _compareExpandDims(self, x, dim, use_gpu):
    178     np_ans = np.expand_dims(x, axis=dim)
    179     with self.cached_session(use_gpu=use_gpu):
    180       tensor = array_ops.expand_dims(x, dim)
    181       tf_ans = self.evaluate(tensor)
    182     self.assertShapeEqual(np_ans, tensor)
    183     self.assertAllEqual(np_ans, tf_ans)
    184 
    185   def _compareExpandDimsAll(self, x, dim):
    186     self._compareExpandDims(x, dim, False)
    187     self._compareExpandDims(x, dim, True)
    188 
    189   def testExpandDims(self):
    190     self._compareExpandDimsAll(np.zeros([2]), 0)
    191     self._compareExpandDimsAll(np.zeros([2]), 1)
    192     self._compareExpandDimsAll(np.zeros([2]), -1)
    193 
    194     self._compareExpandDimsAll(np.zeros([2, 3]), 0)
    195     self._compareExpandDimsAll(np.zeros([2, 3]), 1)
    196     self._compareExpandDimsAll(np.zeros([2, 3]), 2)
    197     self._compareExpandDimsAll(np.zeros([2, 3]), -1)
    198     self._compareExpandDimsAll(np.zeros([2, 3]), -2)
    199 
    200     self._compareExpandDimsAll(np.zeros([2, 3, 5]), 0)
    201     self._compareExpandDimsAll(np.zeros([2, 3, 5]), 1)
    202     self._compareExpandDimsAll(np.zeros([2, 3, 5]), 2)
    203     self._compareExpandDimsAll(np.zeros([2, 3, 5]), 3)
    204 
    205     self._compareExpandDimsAll(np.zeros([2, 3, 5]), -1)
    206     self._compareExpandDimsAll(np.zeros([2, 3, 5]), -2)
    207     self._compareExpandDimsAll(np.zeros([2, 3, 5]), -3)
    208     self._compareExpandDimsAll(np.zeros([2, 3, 5]), -4)
    209 
    210   def testExpandDimsBool(self):
    211     choice = lambda s: np.random.choice((False, True), size=s)
    212     self._compareExpandDimsAll(choice([2]), 0)
    213     self._compareExpandDimsAll(choice([2]), 1)
    214     self._compareExpandDimsAll(choice([2]), -1)
    215 
    216     self._compareExpandDimsAll(choice([2, 3]), 0)
    217     self._compareExpandDimsAll(choice([2, 3]), 1)
    218     self._compareExpandDimsAll(choice([2, 3]), 2)
    219     self._compareExpandDimsAll(choice([2, 3]), -1)
    220     self._compareExpandDimsAll(choice([2, 3]), -2)
    221 
    222     self._compareExpandDimsAll(choice([2, 3, 5]), 0)
    223     self._compareExpandDimsAll(choice([2, 3, 5]), 1)
    224     self._compareExpandDimsAll(choice([2, 3, 5]), 2)
    225     self._compareExpandDimsAll(choice([2, 3, 5]), 3)
    226 
    227     self._compareExpandDimsAll(choice([2, 3, 5]), -1)
    228     self._compareExpandDimsAll(choice([2, 3, 5]), -2)
    229     self._compareExpandDimsAll(choice([2, 3, 5]), -3)
    230     self._compareExpandDimsAll(choice([2, 3, 5]), -4)
    231 
    232   @test_util.run_deprecated_v1
    233   def testExpandDimsErrors(self):
    234     with self.cached_session():
    235       self.assertRaises(ValueError, array_ops.expand_dims,
    236                         np.zeros([2, 3, 5]), -5)
    237       self.assertRaises(ValueError, array_ops.expand_dims,
    238                         [False, True, True], -5)
    239       self.assertRaises(ValueError, array_ops.expand_dims,
    240                         np.zeros([2, 3, 5]), 4)
    241       self.assertRaises(ValueError, array_ops.expand_dims,
    242                         [False, True, True], 4)
    243 
    244   @test_util.run_deprecated_v1
    245   def testExpandDimsGradient(self):
    246     with self.cached_session():
    247       inp = constant_op.constant(
    248           np.random.rand(4, 2).astype("f"), dtype=dtypes.float32)
    249       squeezed = array_ops.expand_dims(inp, 1)
    250 
    251       err = gradient_checker.compute_gradient_error(inp, [4, 2], squeezed,
    252                                                     [4, 1, 2])
    253     self.assertLess(err, 1e-3)
    254 
    255   @test_util.run_deprecated_v1
    256   def testExpandDimsScalar(self):
    257     with self.cached_session():
    258       inp = constant_op.constant(7)
    259       self.assertAllEqual([7], array_ops.expand_dims(inp, 0).eval())
    260       self.assertAllEqual([7], array_ops.expand_dims(inp, -1).eval())
    261 
    262       inp = constant_op.constant(True)
    263       self.assertAllEqual([True], array_ops.expand_dims(inp, 0).eval())
    264       self.assertAllEqual([True], array_ops.expand_dims(inp, -1).eval())
    265 
    266   def testExpandDimsDimType(self):
    267     for dtype in [dtypes.int32, dtypes.int64]:
    268       x = np.zeros([2])
    269       np_ans = np.expand_dims(x, axis=0)
    270       with self.cached_session(use_gpu=True):
    271         tensor = array_ops.expand_dims(x, constant_op.constant(0, dtype))
    272         tf_ans = self.evaluate(tensor)
    273       self.assertShapeEqual(np_ans, tensor)
    274       self.assertAllEqual(np_ans, tf_ans)
    275 
    276   def _compareSqueeze(self, x, squeeze_dims, use_gpu):
    277     with self.cached_session(use_gpu=use_gpu):
    278       if squeeze_dims:
    279         np_ans = np.squeeze(x, axis=tuple(squeeze_dims))
    280         tensor = array_ops.squeeze(x, squeeze_dims)
    281         tf_ans = self.evaluate(tensor)
    282       else:
    283         np_ans = np.squeeze(x)
    284         tensor = array_ops.squeeze(x)
    285         tf_ans = self.evaluate(tensor)
    286     self.assertShapeEqual(np_ans, tensor)
    287     self.assertAllEqual(np_ans, tf_ans)
    288 
    289   def _compareSqueezeAll(self, x, squeeze_dims=None):
    290     if squeeze_dims is None:
    291       squeeze_dims = []
    292     self._compareSqueeze(x, squeeze_dims, False)
    293     self._compareSqueeze(x, squeeze_dims, True)
    294 
    295   def testSqueeze(self):
    296     # Nothing to squeeze.
    297     self._compareSqueezeAll(np.zeros([2]))
    298     self._compareSqueezeAll(np.zeros([2, 3]))
    299 
    300     # Squeeze the middle element away.
    301     self._compareSqueezeAll(np.zeros([2, 1, 2]))
    302 
    303     # Squeeze on both ends.
    304     self._compareSqueezeAll(np.zeros([1, 2, 1, 3, 1]))
    305 
    306   def testSqueezeBool(self):
    307     choice = lambda s: np.random.choice((False, True), size=s)
    308     # Nothing to squeeze.
    309     self._compareSqueezeAll(choice([2]))
    310     self._compareSqueezeAll(choice([2, 3]))
    311 
    312     # Squeeze the middle element away.
    313     self._compareSqueezeAll(choice([2, 1, 2]))
    314 
    315     # Squeeze on both ends.
    316     self._compareSqueezeAll(choice([1, 2, 1, 3, 1]))
    317 
    318   def testSqueezeSpecificDimension(self):
    319     # Positive squeeze dim index.
    320     self._compareSqueezeAll(np.zeros([1, 2, 1, 3, 1]), [0])
    321     self._compareSqueezeAll(np.zeros([1, 2, 1, 3, 1]), [2, 4])
    322     self._compareSqueezeAll(np.zeros([1, 2, 1, 3, 1]), [0, 4, 2])
    323 
    324     # Negative squeeze dim index.
    325     self._compareSqueezeAll(np.zeros([1, 2, 1, 3, 1]), [-1])
    326     self._compareSqueezeAll(np.zeros([1, 2, 1, 3, 1]), [-3, -5])
    327     self._compareSqueezeAll(np.zeros([1, 2, 1, 3, 1]), [-3, -5, -1])
    328 
    329   def testSqueezeSpecificDimensionBool(self):
    330     choice = lambda s: np.random.choice((False, True), size=s)
    331     # Positive squeeze dim index.
    332     self._compareSqueezeAll(choice([1, 2, 1, 3, 1]), [0])
    333     self._compareSqueezeAll(choice([1, 2, 1, 3, 1]), [2, 4])
    334     self._compareSqueezeAll(choice([1, 2, 1, 3, 1]), [0, 4, 2])
    335 
    336     # Negative squeeze dim index.
    337     self._compareSqueezeAll(choice([1, 2, 1, 3, 1]), [-1])
    338     self._compareSqueezeAll(choice([1, 2, 1, 3, 1]), [-3, -5])
    339     self._compareSqueezeAll(choice([1, 2, 1, 3, 1]), [-3, -5, -1])
    340 
    341   def testSqueezeAllOnes(self):
    342     # Numpy squeezes a 1 element tensor into a zero dimensional tensor.
    343     # Verify that we do the same.
    344     for use_gpu in [False, True]:
    345       with self.cached_session(use_gpu=use_gpu):
    346         tensor = array_ops.squeeze(np.zeros([1, 1, 1]), [])
    347         self.assertEqual(np.shape(1), tensor.get_shape())
    348         tf_ans = self.evaluate(tensor)
    349         self.assertEqual(np.shape(1), tf_ans.shape)
    350 
    351   def testSqueezeAllOnesBool(self):
    352     # Numpy squeezes a 1 element tensor into a zero dimensional tensor.
    353     # Verify that we do the same.
    354     for use_gpu in [False, True]:
    355       with self.cached_session(use_gpu=use_gpu):
    356         tensor = array_ops.squeeze([[[False]]], [])
    357         self.assertEqual(np.shape(1), tensor.get_shape())
    358         tf_ans = self.evaluate(tensor)
    359         self.assertEqual(np.shape(1), tf_ans.shape)
    360 
    361   @test_util.run_deprecated_v1
    362   def testSqueezeOnlyOnes(self):
    363     for use_gpu in [False, True]:
    364       with self.cached_session(use_gpu=use_gpu):
    365         input_1x1x3 = np.zeros([1, 1, 3])
    366         self._compareSqueezeAll(input_1x1x3)
    367         self._compareSqueezeAll(input_1x1x3, [0])
    368         self._compareSqueezeAll(input_1x1x3, [1])
    369         self.assertRaises(ValueError, array_ops.squeeze, input_1x1x3, [2])
    370 
    371   @test_util.run_deprecated_v1
    372   def testSqueezeErrors(self):
    373     for use_gpu in [False, True]:
    374       with self.cached_session(use_gpu=use_gpu):
    375         self.assertRaises(ValueError, array_ops.squeeze,
    376                           np.zeros([1, 2, 1]), [-4])
    377         self.assertRaises(ValueError, array_ops.squeeze,
    378                           np.zeros([1, 2, 1]), [0, -4])
    379         self.assertRaises(ValueError, array_ops.squeeze,
    380                           np.zeros([1, 2, 1]), [3])
    381         self.assertRaises(ValueError, array_ops.squeeze,
    382                           np.zeros([1, 2, 1]), [2, 3])
    383 
    384   @test_util.run_deprecated_v1
    385   def testSqueezeGradient(self):
    386     with self.cached_session():
    387       inp = np.random.rand(4, 2).astype("f")
    388       a = array_ops.reshape(inp, [4, 1, 2])
    389       squeezed = array_ops.squeeze(a, [])
    390 
    391       err = gradient_checker.compute_gradient_error(a, [4, 1, 2], squeezed,
    392                                                     [4, 2])
    393     self.assertLess(err, 1e-3)
    394 
    395   @test_util.run_deprecated_v1
    396   def testSqueezeGradientWithSqueezeDims(self):
    397     with self.cached_session():
    398       inp = np.random.rand(4, 2).astype("f")
    399       a = array_ops.reshape(inp, [4, 1, 2, 1])
    400       squeezed = array_ops.squeeze(a, [1])
    401 
    402       err = gradient_checker.compute_gradient_error(a, [4, 1, 2, 1], squeezed,
    403                                                     [4, 2, 1])
    404     self.assertLess(err, 1e-3)
    405 
    406   @test_util.run_deprecated_v1
    407   def testSqueezeWithUnknownShape(self):
    408     with self.cached_session():
    409       a = array_ops.placeholder(dtypes.float32, shape=[2, None])
    410 
    411       squeezed = array_ops.squeeze(a, [1])
    412       self.assertEqual([2], squeezed.get_shape().as_list())
    413 
    414       squeezed = array_ops.squeeze(a)
    415       self.assertEqual(None, squeezed.get_shape())
    416 
    417       self.assertRaises(ValueError, array_ops.squeeze, a, [0])
    418       self.assertRaises(ValueError, array_ops.squeeze, a, [100])
    419 
    420 
    421 class TileTest(test.TestCase, parameterized.TestCase):
    422 
    423   def testScalar(self):
    424     for use_gpu in False, True:
    425       with self.cached_session(use_gpu=use_gpu):
    426         a = constant_op.constant(7, shape=[], dtype=dtypes.float32)
    427         tiled = array_ops.tile(a, [])
    428         result = self.evaluate(tiled)
    429       self.assertEqual(result.shape, ())
    430       self.assertEqual([], tiled.get_shape())
    431       self.assertEqual(7, result)
    432 
    433   def testSimple(self):
    434     # multiples could be int32 or int64
    435     for dtype in [dtypes.int32, dtypes.int64]:
    436       with self.cached_session(use_gpu=True):
    437         inp = np.random.rand(4, 1).astype(np.float32)
    438         a = constant_op.constant(inp)
    439         tiled = array_ops.tile(a, constant_op.constant([1, 4], dtype=dtype))
    440         result = self.evaluate(tiled)
    441       self.assertEqual(result.shape, (4, 4))
    442       self.assertEqual([4, 4], tiled.get_shape())
    443       self.assertTrue((result == np.tile(inp, (1, 4))).all())
    444 
    445   def testIdentityTileAndGrad(self):
    446     with self.cached_session():
    447       inp = np.random.rand(4, 1).astype(np.float32)
    448       a = constant_op.constant(inp)
    449       tiled = array_ops.tile(a, [1, 1])
    450       result = self.evaluate(tiled)
    451     self.assertEqual(result.shape, (4, 1))
    452     self.assertEqual([4, 1], tiled.get_shape())
    453     self.assertTrue((result == np.tile(inp, (1, 1))).all())
    454 
    455   def testEmpty(self):
    456     with self.cached_session():
    457       inp = np.random.rand(2, 3).astype(np.float32)
    458       a = constant_op.constant(inp)
    459       tiled = array_ops.tile(a, [5, 0])
    460       result = self.evaluate(tiled)
    461     self.assertEqual(result.shape, (10, 0))
    462     self.assertEqual([10, 0], tiled.get_shape())
    463 
    464   @test_util.run_deprecated_v1
    465   def testUnknownInputShape(self):
    466     """Importing can call _TileShape without shape of <multiples> known."""
    467     with self.cached_session():
    468       inp = array_ops.placeholder(dtypes.float32)  # unknown shape
    469       multiples = constant_op.constant([1, 2, 3, 4], dtype=np.int32)
    470       tiled = array_ops.tile(inp, multiples)
    471       gdef = tiled.graph.as_graph_def()
    472 
    473       # Move the tile op to the start of the graph so that shapes of its inputs
    474       # are not available when the shape function runs on import.
    475       swapped = False
    476       for i, n in enumerate(gdef.node):
    477         if n.op == "Tile":
    478           # Swap tile op to be first in gdef.node
    479           assert i != 0
    480           new_node = node_def_pb2.NodeDef()
    481           new_node.CopyFrom(gdef.node[i])
    482           gdef.node[i].CopyFrom(gdef.node[0])
    483           gdef.node[0].CopyFrom(new_node)
    484           swapped = True
    485       assert swapped
    486 
    487       tiled_imported, = importer.import_graph_def(
    488           gdef, return_elements=[tiled.name])
    489       self.assertEqual(4, tiled_imported.get_shape().ndims)
    490 
    491   def testTypes(self):
    492     types_to_test = {
    493         "bool": (dtypes.bool, bool),
    494         "float32": (dtypes.float32, float),
    495         "float64": (dtypes.float64, float),
    496         "complex64": (dtypes.complex64, complex),
    497         "complex128": (dtypes.complex128, complex),
    498         "uint8": (dtypes.uint8, int),
    499         "int32": (dtypes.int32, int),
    500         "int64": (dtypes.int64, int),
    501         bytes: (dtypes.string, bytes)
    502     }
    503     for dtype_np, (dtype_tf, cast) in types_to_test.items():
    504       with self.cached_session(use_gpu=True):
    505         inp = np.random.rand(4, 1).astype(dtype_np)
    506         a = constant_op.constant(
    507             [cast(x) for x in inp.ravel(order="C")],
    508             shape=[4, 1],
    509             dtype=dtype_tf)
    510         tiled = array_ops.tile(a, [1, 4])
    511         result = self.evaluate(tiled)
    512       self.assertEqual(result.shape, (4, 4))
    513       self.assertEqual([4, 4], tiled.get_shape())
    514       self.assertAllEqual(result, np.tile(inp, (1, 4)))
    515 
    516   @test_util.run_deprecated_v1
    517   def testInvalidDim(self):
    518     with self.cached_session():
    519       inp = np.random.rand(4, 1).astype("f")
    520       a = constant_op.constant(
    521           [float(x) for x in inp.ravel(order="C")],
    522           shape=[4, 1],
    523           dtype=dtypes.float32)
    524       # Wrong length of multiples.
    525       with self.assertRaises(ValueError):
    526         array_ops.tile(a, [1, 4, 2])
    527       # Wrong rank for multiples.
    528       with self.assertRaises(ValueError):
    529         array_ops.tile(a, [[2, 3], [3, 4]]).eval()
    530 
    531   def _RunAndVerifyResult(self, rank, use_gpu):
    532     with self.cached_session(use_gpu=use_gpu):
    533       # Random dims of given rank
    534       input_shape = np.random.randint(1, 4, size=rank)
    535       inp = np.random.rand(*input_shape).astype("f")
    536       a = constant_op.constant(
    537           [float(x) for x in inp.ravel(order="C")],
    538           shape=input_shape,
    539           dtype=dtypes.float32)
    540       multiples = np.random.randint(1, 4, size=rank).astype(np.int32)
    541       tiled = array_ops.tile(a, multiples)
    542       result = self.evaluate(tiled)
    543     self.assertTrue((np.array(multiples) * np.array(inp.shape) == np.array(
    544         result.shape)).all())
    545     self.assertAllEqual(result, np.tile(inp, tuple(multiples)))
    546     self.assertShapeEqual(result, tiled)
    547 
    548   def testRandom(self):
    549     # test low rank, like 5
    550     for _ in range(5):
    551       self._RunAndVerifyResult(5, use_gpu=False)
    552     for _ in range(5):
    553       self._RunAndVerifyResult(5, use_gpu=True)
    554     # test high rank, like 10
    555     for _ in range(5):
    556       self._RunAndVerifyResult(10, use_gpu=False)
    557     for _ in range(5):
    558       self._RunAndVerifyResult(10, use_gpu=True)
    559 
    560   @parameterized.parameters(dtypes.int32, dtypes.int64)
    561   @test_util.run_deprecated_v1
    562   def testGradientSimpleReduction(self, multiples_dtype):
    563     with self.cached_session():
    564       inp = np.random.rand(4, 1).astype("f")
    565       a = constant_op.constant(
    566           [float(x) for x in inp.flatten()], shape=[4, 1], dtype=dtypes.float32)
    567       multiples = constant_op.constant([1, 4], dtype=multiples_dtype)
    568       tiled = array_ops.tile(a, multiples)
    569       grad_shape = [4, 4]
    570       grad_inp = np.random.rand(*grad_shape).astype("f")
    571       grad_tensor = constant_op.constant(
    572           [float(x) for x in grad_inp.flatten()], shape=grad_shape)
    573       grad = gradients_impl.gradients([tiled], [a], [grad_tensor])[0]
    574       self.assertShapeEqual(inp, grad)
    575       result = self.evaluate(grad)
    576     self.assertAllClose(np.sum(grad_inp, axis=1).reshape(4, 1), result, 1e-3)
    577 
    578   @test_util.run_deprecated_v1
    579   def testGradientStridedReduction(self):
    580     with self.cached_session():
    581       inp = np.random.rand(4, 2).astype("f")
    582       a = constant_op.constant(
    583           [float(x) for x in inp.flatten()], shape=[4, 2], dtype=dtypes.float32)
    584       tiled = array_ops.tile(a, [1, 2])
    585       grad_shape = [4, 4]
    586       grad_inp = np.random.rand(*grad_shape).astype("f")
    587       grad_tensor = constant_op.constant(
    588           [float(x) for x in grad_inp.flatten()], shape=grad_shape)
    589       grad = gradients_impl.gradients([tiled], [a], [grad_tensor])[0]
    590       self.assertShapeEqual(inp, grad)
    591       result = self.evaluate(grad)
    592     expected_shape = [4, 2]
    593     expected = np.zeros(expected_shape)
    594     expected[:, 0] = grad_inp[:, 0] + grad_inp[:, 2]
    595     expected[:, 1] = grad_inp[:, 1] + grad_inp[:, 3]
    596     self.assertTrue((np.abs(expected - result) < 1e-3).all())
    597 
    598   @test_util.run_deprecated_v1
    599   def testGradientSimpleReductionOnGPU(self):
    600     with self.session(use_gpu=True):
    601       inp = np.random.rand(4, 1).astype("f")
    602       a = constant_op.constant(
    603           [float(x) for x in inp.flatten()], shape=[4, 1], dtype=dtypes.float32)
    604       tiled = array_ops.tile(a, [1, 4])
    605       grad_shape = [4, 4]
    606       grad_inp = np.random.rand(*grad_shape).astype("f")
    607       grad_tensor = constant_op.constant(
    608           [float(x) for x in grad_inp.flatten()], shape=grad_shape)
    609       grad = gradients_impl.gradients([tiled], [a], [grad_tensor])[0]
    610       result = self.evaluate(grad)
    611     self.assertAllClose(np.sum(grad_inp, axis=1).reshape(4, 1), result, 1e-3)
    612 
    613   @test_util.run_deprecated_v1
    614   def testGradientStridedReductionOnGPU(self):
    615     with self.session(use_gpu=True):
    616       inp = np.random.rand(4, 2).astype("f")
    617       a = constant_op.constant(
    618           [float(x) for x in inp.flatten()], shape=[4, 2], dtype=dtypes.float32)
    619       tiled = array_ops.tile(a, [1, 2])
    620       grad_shape = [4, 4]
    621       grad_inp = np.random.rand(*grad_shape).astype("f")
    622       grad_tensor = constant_op.constant(
    623           [float(x) for x in grad_inp.flatten()], shape=grad_shape)
    624       grad = gradients_impl.gradients([tiled], [a], [grad_tensor])[0]
    625       result = self.evaluate(grad)
    626     expected_shape = [4, 2]
    627     expected = np.zeros(expected_shape)
    628     expected[:, 0] = grad_inp[:, 0] + grad_inp[:, 2]
    629     expected[:, 1] = grad_inp[:, 1] + grad_inp[:, 3]
    630     self.assertAllClose(expected, result, 1e-3)
    631 
    632   def _RunAndVerifyGradientResult(self, input_shape, multiples):
    633     for use_gpu in False, True:
    634       with self.cached_session(use_gpu=use_gpu):
    635         # Random values
    636         inp = np.asarray(np.random.rand(*input_shape))
    637         a = constant_op.constant(inp, dtype=dtypes.float64)
    638         tiled = array_ops.tile(a, multiples)
    639         grad_shape = list(np.array(multiples) * np.array(inp.shape))
    640         err = gradient_checker.compute_gradient_error(
    641             a, list(input_shape), tiled, grad_shape, x_init_value=inp)
    642       print("tile(float) error = ", err)
    643       self.assertLess(err, 1e-3)
    644 
    645   @test_util.run_deprecated_v1
    646   def testGradientRandomScalar(self):
    647     self._RunAndVerifyGradientResult([], [])
    648 
    649   @test_util.run_deprecated_v1
    650   def testGradientRandom(self):
    651     self._RunAndVerifyGradientResult([2, 2, 1, 1, 3], [1, 1, 1, 1, 1])
    652     self._RunAndVerifyGradientResult([2, 2, 1, 1, 3], [1, 2, 1, 3, 1])
    653     self._RunAndVerifyGradientResult([2, 3, 1, 1, 3], [3, 1, 1, 2, 2])
    654     self._RunAndVerifyGradientResult([2, 1, 3, 3, 2], [1, 3, 3, 1, 2])
    655 
    656   @test_util.run_deprecated_v1
    657   def testGradientStridedReductionGC(self):
    658     with self.cached_session():
    659       inp = np.random.rand(4, 2).astype("f")
    660       a = constant_op.constant(
    661           [float(x) for x in inp.flatten()], shape=[4, 2], dtype=dtypes.float32)
    662       tiled = array_ops.tile(a, [1, 2])
    663       err = gradient_checker.compute_gradient_error(a, [4, 2], tiled, [4, 4])
    664     self.assertLess(err, 1e-3)
    665 
    666   @parameterized.parameters(dtypes.int32, dtypes.int64)
    667   @test_util.run_deprecated_v1
    668   def testGradientWithSparseGradWithRank1(self, multiples_dtype):
    669     inputs = constant_op.constant([1.0, 2.0, 3.0, 4.0],
    670                                   dtype=dtypes.float32)
    671     multiples = constant_op.constant([3], dtype=dtypes.int64)
    672     outputs = array_ops.gather(array_ops.tile(inputs, multiples),
    673                                [1, 5, 9, 3, 7, 2, 2, 2])
    674     with self.cached_session():
    675       error = gradient_checker.compute_gradient_error(
    676           inputs, inputs.get_shape().as_list(),
    677           outputs, outputs.get_shape().as_list())
    678       self.assertLess(error, 1e-4)
    679 
    680   @test_util.run_deprecated_v1
    681   def testGradientWithSparseGradWithRank3(self):
    682     inputs = constant_op.constant([1.0, 2.0, 3.0, 4.0],
    683                                   dtype=dtypes.float32)
    684     inputs = array_ops.reshape(inputs, [-1, 1, 1])
    685     outputs = array_ops.gather(array_ops.tile(inputs, [3, 4, 2]),
    686                                [1, 5, 9, 3, 7, 2, 2, 2])
    687     with self.cached_session():
    688       error = gradient_checker.compute_gradient_error(
    689           inputs, inputs.get_shape().as_list(),
    690           outputs, outputs.get_shape().as_list())
    691       self.assertLess(error, 1e-4)
    692 
    693   @test_util.run_deprecated_v1
    694   def testShapeFunctionEdgeCases(self):
    695     # Unknown multiples shape.
    696     inp = constant_op.constant(0.0, shape=[4, 4, 4, 4])
    697     tiled = array_ops.tile(inp, array_ops.placeholder(dtypes.int32))
    698     self.assertEqual([None, None, None, None], tiled.get_shape().as_list())
    699 
    700     # Unknown input shape.
    701     inp = array_ops.placeholder(dtypes.float32)
    702     tiled = array_ops.tile(inp, [2, 2, 2, 2])
    703     self.assertEqual([None, None, None, None], tiled.get_shape().as_list())
    704 
    705     # Unknown input and multiples shape.
    706     inp = array_ops.placeholder(dtypes.float32)
    707     tiled = array_ops.tile(inp, array_ops.placeholder(dtypes.int32))
    708     self.assertIs(None, tiled.get_shape().ndims)
    709 
    710     # Known input and partially known multiples.
    711     inp = constant_op.constant(0.0, shape=[1, 1])
    712     tiled = array_ops.tile(inp, [array_ops.placeholder(dtypes.int32), 7])
    713     self.assertEqual([None, 7], tiled.get_shape().as_list())
    714 
    715     # Mismatched input rank and multiples length.
    716     inp = array_ops.placeholder(dtypes.float32, shape=[None, None])
    717     with self.assertRaises(ValueError):
    718       tiled = array_ops.tile(
    719           inp, array_ops.placeholder(
    720               dtypes.int32, shape=[3]))
    721 
    722 
    723 if __name__ == "__main__":
    724   test.main()
    725