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 tensorflow.ops.numerics."""
16
17from __future__ import absolute_import
18from __future__ import division
19from __future__ import print_function
20
21import numpy as np
22
23from tensorflow.python.framework import constant_op
24from tensorflow.python.framework import dtypes
25from tensorflow.python.framework import ops
26from tensorflow.python.ops import array_ops
27from tensorflow.python.ops import control_flow_ops
28from tensorflow.python.ops import math_ops
29from tensorflow.python.ops import numerics
30from tensorflow.python.platform import test
31
32
33class VerifyTensorAllFiniteTest(test.TestCase):
34
35  def testVerifyTensorAllFiniteSucceeds(self):
36    x_shape = [5, 4]
37    x = np.random.random_sample(x_shape).astype(np.float32)
38    with self.test_session(use_gpu=True):
39      t = constant_op.constant(x, shape=x_shape, dtype=dtypes.float32)
40      t_verified = numerics.verify_tensor_all_finite(t,
41                                                     "Input is not a number.")
42      self.assertAllClose(x, t_verified.eval())
43
44  def testVerifyTensorAllFiniteFails(self):
45    x_shape = [5, 4]
46    x = np.random.random_sample(x_shape).astype(np.float32)
47    my_msg = "Input is not a number."
48
49    # Test NaN.
50    x[0] = np.nan
51    with self.test_session(use_gpu=True):
52      with self.assertRaisesOpError(my_msg):
53        t = constant_op.constant(x, shape=x_shape, dtype=dtypes.float32)
54        t_verified = numerics.verify_tensor_all_finite(t, my_msg)
55        t_verified.eval()
56
57    # Test Inf.
58    x[0] = np.inf
59    with self.test_session(use_gpu=True):
60      with self.assertRaisesOpError(my_msg):
61        t = constant_op.constant(x, shape=x_shape, dtype=dtypes.float32)
62        t_verified = numerics.verify_tensor_all_finite(t, my_msg)
63        t_verified.eval()
64
65
66class NumericsTest(test.TestCase):
67
68  def testInf(self):
69    with self.test_session(graph=ops.Graph()):
70      t1 = constant_op.constant(1.0)
71      t2 = constant_op.constant(0.0)
72      a = math_ops.div(t1, t2)
73      check = numerics.add_check_numerics_ops()
74      a = control_flow_ops.with_dependencies([check], a)
75      with self.assertRaisesOpError("Inf"):
76        a.eval()
77
78  def testNaN(self):
79    with self.test_session(graph=ops.Graph()):
80      t1 = constant_op.constant(0.0)
81      t2 = constant_op.constant(0.0)
82      a = math_ops.div(t1, t2)
83      check = numerics.add_check_numerics_ops()
84      a = control_flow_ops.with_dependencies([check], a)
85      with self.assertRaisesOpError("NaN"):
86        a.eval()
87
88  def testBoth(self):
89    with self.test_session(graph=ops.Graph()):
90      t1 = constant_op.constant([1.0, 0.0])
91      t2 = constant_op.constant([0.0, 0.0])
92      a = math_ops.div(t1, t2)
93      check = numerics.add_check_numerics_ops()
94      a = control_flow_ops.with_dependencies([check], a)
95      with self.assertRaisesOpError("Inf and NaN"):
96        a.eval()
97
98  def testPassThrough(self):
99    with self.test_session(graph=ops.Graph()):
100      t1 = constant_op.constant([1.0, 2.0, 3.0, 4.0, 5.0, 6.0], shape=[2, 3])
101      checked = array_ops.check_numerics(t1, message="pass through test")
102      value = checked.eval()
103      self.assertAllEqual(np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]]), value)
104      self.assertEqual([2, 3], checked.get_shape())
105
106  def testControlFlowCond(self):
107    predicate = array_ops.placeholder(dtypes.bool, shape=[])
108    _ = control_flow_ops.cond(predicate,
109                              lambda: constant_op.constant([37.]),
110                              lambda: constant_op.constant([42.]))
111    with self.assertRaisesRegexp(
112        ValueError,
113        r"`tf\.add_check_numerics_ops\(\) is not compatible with "
114        r"TensorFlow control flow operations such as `tf\.cond\(\)` "
115        r"or `tf.while_loop\(\)`\."):
116      numerics.add_check_numerics_ops()
117
118  def testControlFlowWhile(self):
119    predicate = array_ops.placeholder(dtypes.bool, shape=[])
120    _ = control_flow_ops.while_loop(lambda _: predicate,
121                                    lambda _: constant_op.constant([37.]),
122                                    [constant_op.constant([42.])])
123    with self.assertRaisesRegexp(
124        ValueError,
125        r"`tf\.add_check_numerics_ops\(\) is not compatible with "
126        r"TensorFlow control flow operations such as `tf\.cond\(\)` "
127        r"or `tf.while_loop\(\)`\."):
128      numerics.add_check_numerics_ops()
129
130
131if __name__ == "__main__":
132  test.main()
133