aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/python/kernel_tests/cwise_ops_test.py
diff options
context:
space:
mode:
Diffstat (limited to 'tensorflow/python/kernel_tests/cwise_ops_test.py')
-rw-r--r--tensorflow/python/kernel_tests/cwise_ops_test.py1187
1 files changed, 1187 insertions, 0 deletions
diff --git a/tensorflow/python/kernel_tests/cwise_ops_test.py b/tensorflow/python/kernel_tests/cwise_ops_test.py
new file mode 100644
index 0000000000..22491f231a
--- /dev/null
+++ b/tensorflow/python/kernel_tests/cwise_ops_test.py
@@ -0,0 +1,1187 @@
+"""Functional tests for coefficient-wise operations.
+"""
+import tensorflow.python.platform
+
+import numpy as np
+import tensorflow as tf
+
+from tensorflow.python.kernel_tests import gradient_checker as gc
+
+_ADD = lambda x, y: x + y
+_SUB = lambda x, y: x - y
+_MUL = lambda x, y: x * y
+_DIV = lambda x, y: x / y
+_MOD = lambda x, y: x % y
+_NEG = lambda x: -x
+_ABS = abs
+
+_LT = lambda x, y: x < y
+_LE = lambda x, y: x <= y
+_GT = lambda x, y: x > y
+_GE = lambda x, y: x >= y
+
+_AND = lambda x, y: x & y
+_OR = lambda x, y: x | y
+_XOR = lambda x, y: x ^ y
+_INV = lambda x: ~x
+
+
+class UnaryOpTest(tf.test.TestCase):
+
+ def _compareCpu(self, x, np_func, tf_func):
+ np_ans = np_func(x)
+ with self.test_session(use_gpu=False):
+ inx = tf.convert_to_tensor(x)
+ y = tf_func(inx)
+ tf_cpu = y.eval()
+ self.assertShapeEqual(np_ans, y)
+ self.assertAllClose(np_ans, tf_cpu)
+ if x.dtype == np.float32:
+ s = list(np.shape(x))
+ jacob_t, jacob_n = gc.ComputeGradient(inx, s, y, s, x_init_value=x)
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-3, atol=1e-3)
+ elif x.dtype == np.float64:
+ s = list(np.shape(x))
+ jacob_t, jacob_n = gc.ComputeGradient(inx, s, y, s, x_init_value=x)
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-5, atol=1e-5)
+
+ def _compareGpu(self, x, np_func, tf_func):
+ np_ans = np_func(x)
+ with self.test_session(use_gpu=True):
+ result = tf_func(tf.convert_to_tensor(x))
+ tf_gpu = result.eval()
+ self.assertShapeEqual(np_ans, result)
+ self.assertAllClose(np_ans, tf_gpu)
+ # TODO(zhifengc/ke): make gradient checker work on GPU.
+
+ def _compareBoth(self, x, np_func, tf_func):
+ self._compareCpu(x, np_func, tf_func)
+ self._compareGpu(x, np_func, tf_func)
+
+ def _inv(self, x):
+ return 1.0 / x
+
+ def _rsqrt(self, x):
+ return self._inv(np.sqrt(x))
+
+ def _sigmoid(self, x):
+ return 1.0 / (1.0 + np.exp(-x))
+
+ def testFloatBasic(self):
+ x = np.arange(-3, 3).reshape(1, 3, 2).astype(np.float32)
+ y = (x + .5).astype(np.float32) # no zero
+ z = (x + 15.5).astype(np.float32) # all positive
+ self._compareBoth(x, np.abs, tf.abs)
+ self._compareBoth(x, np.abs, _ABS)
+ self._compareBoth(x, np.negative, tf.neg)
+ self._compareBoth(x, np.negative, _NEG)
+ self._compareBoth(y, self._inv, tf.inv)
+ self._compareBoth(x, np.square, tf.square)
+ self._compareBoth(z, np.sqrt, tf.sqrt)
+ self._compareBoth(z, self._rsqrt, tf.rsqrt)
+ self._compareBoth(x, np.exp, tf.exp)
+ self._compareBoth(z, np.log, tf.log)
+ self._compareBoth(x, np.tanh, tf.tanh)
+ self._compareBoth(x, self._sigmoid, tf.sigmoid)
+ self._compareBoth(y, np.sign, tf.sign)
+ self._compareBoth(x, np.sin, tf.sin)
+ self._compareBoth(x, np.cos, tf.cos)
+
+ def testFloatTanhEdge(self):
+ x = np.arange(40, 40 + 6).reshape(6).astype(np.float32)
+ self._compareBoth(x, np.tanh, tf.tanh)
+ x = np.arange(-40, -40 + 6).reshape(6).astype(np.float32)
+ self._compareBoth(x, np.tanh, tf.tanh)
+
+ def testFloatEmpty(self):
+ x = np.empty((2, 0, 5), dtype=np.float32)
+ self._compareBoth(x, np.abs, tf.abs)
+ self._compareBoth(x, np.abs, _ABS)
+ self._compareBoth(x, np.negative, tf.neg)
+ self._compareBoth(x, np.negative, _NEG)
+ self._compareBoth(x, self._inv, tf.inv)
+ self._compareBoth(x, np.square, tf.square)
+ self._compareBoth(x, np.sqrt, tf.sqrt)
+ self._compareBoth(x, self._rsqrt, tf.rsqrt)
+ self._compareBoth(x, np.exp, tf.exp)
+ self._compareBoth(x, np.log, tf.log)
+ self._compareBoth(x, np.tanh, tf.tanh)
+ self._compareBoth(x, self._sigmoid, tf.sigmoid)
+ self._compareBoth(x, np.sign, tf.sign)
+ self._compareBoth(x, np.sin, tf.sin)
+ self._compareBoth(x, np.cos, tf.cos)
+
+ def testDoubleBasic(self):
+ x = np.arange(-3, 3).reshape(1, 3, 2).astype(np.float64)
+ y = (x + .5).astype(np.float64) # no zero
+ z = (x + 15.5).astype(np.float64) # all positive
+ self._compareBoth(x, np.abs, tf.abs)
+ self._compareBoth(x, np.abs, _ABS)
+ self._compareBoth(x, np.negative, tf.neg)
+ self._compareBoth(x, np.negative, _NEG)
+ self._compareBoth(y, self._inv, tf.inv)
+ self._compareBoth(x, np.square, tf.square)
+ self._compareBoth(z, np.sqrt, tf.sqrt)
+ self._compareBoth(z, self._rsqrt, tf.rsqrt)
+ self._compareBoth(x, np.exp, tf.exp)
+ self._compareBoth(z, np.log, tf.log)
+ self._compareBoth(x, np.tanh, tf.tanh)
+ self._compareBoth(x, self._sigmoid, tf.sigmoid)
+ self._compareBoth(y, np.sign, tf.sign)
+ self._compareBoth(x, np.sin, tf.sin)
+ self._compareBoth(x, np.cos, tf.cos)
+
+ def testInt32Basic(self):
+ x = np.arange(-6, 6, 2).reshape(1, 3, 2).astype(np.int32)
+ self._compareCpu(x, np.abs, tf.abs)
+ self._compareCpu(x, np.abs, _ABS)
+ self._compareCpu(x, np.negative, tf.neg)
+ self._compareCpu(x, np.negative, _NEG)
+ self._compareCpu(x, np.square, tf.square)
+ self._compareCpu(x, np.sign, tf.sign)
+
+ def testInt64Basic(self):
+ x = np.arange(
+ -6 << 40, 6 << 40, 2 << 40).reshape(1, 3, 2).astype(np.int64)
+ self._compareCpu(x, np.abs, tf.abs)
+ self._compareCpu(x, np.abs, _ABS)
+ self._compareCpu(x, np.negative, tf.neg)
+ self._compareCpu(x, np.negative, _NEG)
+ self._compareCpu(x, np.square, tf.square)
+ self._compareCpu(x, np.sign, tf.sign)
+
+ def testComplex64Basic(self):
+ x = np.complex(1, 1) * np.arange(-3, 3).reshape(1, 3, 2).astype(
+ np.complex64)
+ y = x + 0.5 # no zeros
+ self._compareCpu(x, np.abs, tf.abs)
+ self._compareCpu(x, np.abs, _ABS)
+ self._compareCpu(x, np.negative, tf.neg)
+ self._compareCpu(x, np.negative, _NEG)
+ self._compareCpu(y, self._inv, tf.inv)
+ self._compareCpu(x, np.square, tf.square)
+ self._compareCpu(x, np.sqrt, tf.sqrt)
+ self._compareCpu(y, self._rsqrt, tf.rsqrt)
+ self._compareCpu(x, np.exp, tf.exp)
+ self._compareCpu(y, np.log, tf.log)
+ self._compareCpu(x, np.tanh, tf.tanh)
+ self._compareCpu(x, self._sigmoid, tf.sigmoid)
+ self._compareCpu(x, np.sin, tf.sin)
+ self._compareCpu(x, np.cos, tf.cos)
+
+
+class BinaryOpTest(tf.test.TestCase):
+
+ def _compareCpu(self, x, y, np_func, tf_func):
+ np_ans = np_func(x, y)
+ with self.test_session(use_gpu=False):
+ inx = tf.convert_to_tensor(x)
+ iny = tf.convert_to_tensor(y)
+ out = tf_func(inx, iny)
+ tf_cpu = out.eval()
+ # Test that the op takes precedence over numpy operators.
+ np_left = tf_func(x, iny).eval()
+ np_right = tf_func(inx, y).eval()
+
+ self.assertAllClose(np_ans, tf_cpu)
+ self.assertAllClose(np_ans, np_left)
+ self.assertAllClose(np_ans, np_right)
+ self.assertShapeEqual(np_ans, out)
+
+ def _compareGradientX(self, x, y, np_func, tf_func):
+ z = np_func(x, y)
+ zs = list(z.shape)
+ with self.test_session():
+ inx = tf.convert_to_tensor(x)
+ iny = tf.convert_to_tensor(y)
+ out = tf_func(inx, iny)
+ xs = list(x.shape)
+ jacob_t, jacob_n = gc.ComputeGradient(inx, xs, out, zs, x_init_value=x)
+ if x.dtype == np.float32:
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-3, atol=1e-3)
+ elif x.dtype == np.float64:
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-5, atol=1e-5)
+
+ def _compareGradientY(self, x, y, np_func, tf_func):
+ z = np_func(x, y)
+ zs = list(z.shape)
+ with self.test_session():
+ inx = tf.convert_to_tensor(x)
+ iny = tf.convert_to_tensor(y)
+ out = tf_func(inx, iny)
+ ys = list(np.shape(y))
+ jacob_t, jacob_n = gc.ComputeGradient(iny, ys, out, zs, x_init_value=y)
+ if x.dtype == np.float32:
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-3, atol=1e-3)
+ elif x.dtype == np.float64:
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-5, atol=1e-5)
+
+ def _compareGpu(self, x, y, np_func, tf_func):
+ np_ans = np_func(x, y)
+ with self.test_session(use_gpu=True):
+ inx = tf.convert_to_tensor(x)
+ iny = tf.convert_to_tensor(y)
+ out = tf_func(inx, iny)
+ tf_gpu = out.eval()
+ self.assertAllClose(np_ans, tf_gpu)
+ self.assertShapeEqual(np_ans, out)
+ # TODO(zhifengc/ke): make gradient checker work on GPU.
+
+ def _compareBoth(self, x, y, np_func, tf_func):
+ self._compareCpu(x, y, np_func, tf_func)
+ if x.dtype == np.float32 or x.dtype == np.float64:
+ self._compareGradientX(x, y, np_func, tf_func)
+ self._compareGradientY(x, y, np_func, tf_func)
+ self._compareGpu(x, y, np_func, tf_func)
+
+ def testFloatBasic(self):
+ x = np.linspace(-10, 10, 6).reshape(1, 3, 2).astype(np.float32)
+ y = np.linspace(20, -20, 6).reshape(1, 3, 2).astype(np.float32)
+ self._compareBoth(x, y, np.add, tf.add)
+ self._compareBoth(x, y, np.subtract, tf.sub)
+ self._compareBoth(x, y, np.multiply, tf.mul)
+ self._compareBoth(x, y + 0.1, np.divide, tf.div)
+ self._compareBoth(x, y, np.add, _ADD)
+ self._compareBoth(x, y, np.subtract, _SUB)
+ self._compareBoth(x, y, np.multiply, _MUL)
+ self._compareBoth(x, y + 0.1, np.divide, _DIV)
+
+ def testFloatDifferentShapes(self):
+ x = np.array([1, 2, 3, 4]).reshape(2, 2).astype(np.float32)
+ y = np.array([1, 2]).reshape(2, 1).astype(np.float32)
+ with self.test_session() as sess:
+ inx = tf.convert_to_tensor(x)
+ iny = tf.convert_to_tensor(y)
+ s = tf.reduce_sum(inx * iny)
+ gx, gy = sess.run(tf.gradients(s, [inx, iny]))
+ # gx is simply the broadcasted y
+ self.assertAllEqual(gx, np.array([1, 1, 2, 2])
+ .reshape(2, 2).astype(np.float32))
+ # gy is x's column summed up
+ self.assertAllEqual(gy, np.array([3, 7]).
+ reshape(2, 1).astype(np.float32))
+
+ def testDoubleBasic(self):
+ x = np.linspace(-10, 10, 6).reshape(1, 3, 2).astype(np.float64)
+ y = np.linspace(20, -20, 6).reshape(1, 3, 2).astype(np.float64)
+ self._compareBoth(x, y, np.add, tf.add)
+ self._compareBoth(x, y, np.subtract, tf.sub)
+ self._compareBoth(x, y, np.multiply, tf.mul)
+ self._compareBoth(x, y + 0.1, np.divide, tf.div)
+ self._compareBoth(x, y, np.add, _ADD)
+ self._compareBoth(x, y, np.subtract, _SUB)
+ self._compareBoth(x, y, np.multiply, _MUL)
+ self._compareBoth(x, y + 0.1, np.divide, _DIV)
+
+ def testInt8Basic(self):
+ x = np.arange(1, 13, 2).reshape(1, 3, 2).astype(np.int8)
+ y = np.arange(1, 7, 1).reshape(1, 3, 2).astype(np.int8)
+ self._compareBoth(x, y, np.multiply, tf.mul)
+ self._compareBoth(x, y, np.multiply, _MUL)
+
+ def testInt16Basic(self):
+ x = np.arange(1, 13, 2).reshape(1, 3, 2).astype(np.int16)
+ y = np.arange(1, 7, 1).reshape(1, 3, 2).astype(np.int16)
+ self._compareBoth(x, y, np.multiply, tf.mul)
+ self._compareBoth(x, y, np.multiply, _MUL)
+
+ def testInt32Basic(self):
+ x = np.arange(1, 13, 2).reshape(1, 3, 2).astype(np.int32)
+ y = np.arange(1, 7, 1).reshape(1, 3, 2).astype(np.int32)
+ self._compareBoth(x, y, np.add, tf.add)
+ self._compareBoth(x, y, np.subtract, tf.sub)
+ self._compareBoth(x, y, np.multiply, tf.mul)
+ # NOTE: int32 division is ill-defined.
+ self._compareBoth(x, y, np.divide, tf.div)
+ self._compareBoth(x, y, np.mod, tf.mod)
+ self._compareBoth(x, y, np.add, _ADD)
+ self._compareBoth(x, y, np.subtract, _SUB)
+ self._compareBoth(x, y, np.multiply, _MUL)
+ # NOTE: int32 division is ill-defined.
+ self._compareBoth(x, y, np.divide, _DIV)
+ self._compareBoth(x, y, np.mod, _MOD)
+
+ def testInt64Basic(self):
+ x = np.arange(1 << 40, 13 << 40, 2 << 40).reshape(1, 3, 2).astype(np.int64)
+ y = np.arange(1, 7, 1).reshape(1, 3, 2).astype(np.int64)
+ self._compareBoth(x, y, np.subtract, tf.sub)
+ self._compareBoth(x, y, np.multiply, tf.mul)
+ # NOTE: int64 division is ill-defined.
+ self._compareBoth(x, y, np.divide, tf.div)
+ self._compareBoth(x, y, np.mod, tf.mod)
+ self._compareBoth(x, y, np.subtract, _SUB)
+ self._compareBoth(x, y, np.multiply, _MUL)
+ # NOTE: int64 division is ill-defined.
+ self._compareBoth(x, y, np.divide, _DIV)
+ self._compareBoth(x, y, np.mod, _MOD)
+
+ def testComplex64Basic(self):
+ x = np.complex(1, 1) * np.linspace(-10, 10, 6).reshape(1, 3, 2).astype(
+ np.complex64)
+ y = np.complex(1, 1) * np.linspace(20, -20, 6).reshape(1, 3, 2).astype(
+ np.complex64)
+ self._compareCpu(x, y, np.add, tf.add)
+ self._compareCpu(x, y, np.subtract, tf.sub)
+ self._compareCpu(x, y, np.multiply, tf.mul)
+ self._compareCpu(x, y + 0.1, np.divide, tf.div)
+ self._compareCpu(x, y, np.add, _ADD)
+ self._compareCpu(x, y, np.subtract, _SUB)
+ self._compareCpu(x, y, np.multiply, _MUL)
+ self._compareCpu(x, y + 0.1, np.divide, _DIV)
+
+ def _compareBCast(self, xs, ys, dtype, np_func, tf_func):
+ x = (1 + np.linspace(0, 5, np.prod(xs))).astype(dtype).reshape(xs)
+ y = (1 + np.linspace(0, 5, np.prod(ys))).astype(dtype).reshape(ys)
+ self._compareCpu(x, y, np_func, tf_func)
+ if x.dtype == np.float32 or x.dtype == np.float64:
+ self._compareGradientX(x, y, np_func, tf_func)
+ self._compareGradientY(x, y, np_func, tf_func)
+ self._compareGpu(x, y, np_func, tf_func)
+
+ # TODO(josh11b,vrv): Refactor this to use parameterized tests.
+ def _testBCastByFunc(self, funcs, xs, ys):
+ dtypes = [
+ np.float32,
+ np.float64,
+ np.int32,
+ np.int64,
+ np.complex64
+ ]
+ for dtype in dtypes:
+ for (np_func, tf_func) in funcs:
+ self._compareBCast(xs, ys, dtype, np_func, tf_func)
+ self._compareBCast(ys, xs, dtype, np_func, tf_func)
+
+ def _testBCastA(self, xs, ys):
+ funcs = [
+ (np.add, tf.add),
+ (np.add, _ADD),
+ ]
+ self._testBCastByFunc(funcs, xs, ys)
+
+ def _testBCastB(self, xs, ys):
+ funcs = [
+ (np.subtract, tf.sub),
+ (np.subtract, _SUB),
+ (np.power, tf.pow),
+ ]
+ self._testBCastByFunc(funcs, xs, ys)
+
+ def _testBCastC(self, xs, ys):
+ funcs = [
+ (np.multiply, tf.mul),
+ (np.multiply, _MUL),
+ ]
+ self._testBCastByFunc(funcs, xs, ys)
+
+ def _testBCastD(self, xs, ys):
+ funcs = [
+ (np.divide, tf.div),
+ (np.divide, _DIV)
+ ]
+ self._testBCastByFunc(funcs, xs, ys)
+
+ def testBCast_0A(self):
+ self._testBCastA([1, 3, 2], [1])
+
+ def testBCast_0B(self):
+ self._testBCastB([1, 3, 2], [1])
+
+ def testBCast_0C(self):
+ self._testBCastC([1, 3, 2], [1])
+
+ def testBCast_0D(self):
+ self._testBCastD([1, 3, 2], [1])
+
+ def testBCast_1A(self):
+ self._testBCastA([1, 3, 2], [2])
+
+ def testBCast_1B(self):
+ self._testBCastB([1, 3, 2], [2])
+
+ def testBCast_1C(self):
+ self._testBCastC([1, 3, 2], [2])
+
+ def testBCast_1D(self):
+ self._testBCastD([1, 3, 2], [2])
+
+ def testBCast_2A(self):
+ self._testBCastA([1, 3, 2], [3, 2])
+
+ def testBCast_2B(self):
+ self._testBCastB([1, 3, 2], [3, 2])
+
+ def testBCast_2C(self):
+ self._testBCastC([1, 3, 2], [3, 2])
+
+ def testBCast_2D(self):
+ self._testBCastD([1, 3, 2], [3, 2])
+
+ def testBCast_3A(self):
+ self._testBCastA([1, 3, 2], [3, 1])
+
+ def testBCast_3B(self):
+ self._testBCastB([1, 3, 2], [3, 1])
+
+ def testBCast_3C(self):
+ self._testBCastC([1, 3, 2], [3, 1])
+
+ def testBCast_3D(self):
+ self._testBCastD([1, 3, 2], [3, 1])
+
+ def testBCast_4A(self):
+ self._testBCastA([1, 3, 2], [1, 3, 2])
+
+ def testBCast_4B(self):
+ self._testBCastB([1, 3, 2], [1, 3, 2])
+
+ def testBCast_4C(self):
+ self._testBCastC([1, 3, 2], [1, 3, 2])
+
+ def testBCast_4D(self):
+ self._testBCastD([1, 3, 2], [1, 3, 2])
+
+ def testBCast_5A(self):
+ self._testBCastA([1, 3, 2], [2, 3, 1])
+
+ def testBCast_5B(self):
+ self._testBCastB([1, 3, 2], [2, 3, 1])
+
+ def testBCast_5C(self):
+ self._testBCastC([1, 3, 2], [2, 3, 1])
+
+ def testBCast_5D(self):
+ self._testBCastD([1, 3, 2], [2, 3, 1])
+
+ def testBCast_6A(self):
+ self._testBCastA([1, 3, 2], [2, 1, 1])
+
+ def testBCast_6B(self):
+ self._testBCastB([1, 3, 2], [2, 1, 1])
+
+ def testBCast_6C(self):
+ self._testBCastC([1, 3, 2], [2, 1, 1])
+
+ def testBCast_6D(self):
+ self._testBCastD([1, 3, 2], [2, 1, 1])
+
+ def testBCast_7A(self):
+ self._testBCastA([1, 3, 2], [1, 3, 1])
+
+ def testBCast_7B(self):
+ self._testBCastB([1, 3, 2], [1, 3, 1])
+
+ def testBCast_7C(self):
+ self._testBCastC([1, 3, 2], [1, 3, 1])
+
+ def testBCast_7D(self):
+ self._testBCastD([1, 3, 2], [1, 3, 1])
+
+ def testBCast_8A(self):
+ self._testBCastA([2, 1, 5], [2, 3, 1])
+
+ def testBCast_8B(self):
+ self._testBCastB([2, 1, 5], [2, 3, 1])
+
+ def testBCast_8C(self):
+ self._testBCastC([2, 1, 5], [2, 3, 1])
+
+ def testBCast_8D(self):
+ self._testBCastD([2, 1, 5], [2, 3, 1])
+
+ def testBCast_9A(self):
+ self._testBCastA([2, 0, 5], [2, 0, 1])
+
+ def testBCast_9B(self):
+ self._testBCastB([2, 0, 5], [2, 0, 1])
+
+ def testBCast_9C(self):
+ self._testBCastC([2, 0, 5], [2, 0, 1])
+
+ def testBCast_9D(self):
+ self._testBCastD([2, 0, 5], [2, 0, 1])
+
+ def testBCast_10A(self):
+ self._testBCastA([2, 3, 0], [2, 3, 1])
+
+ def testBCast_10B(self):
+ self._testBCastB([2, 3, 0], [2, 3, 1])
+
+ def testBCast_10C(self):
+ self._testBCastC([2, 3, 0], [2, 3, 1])
+
+ def testBCast_10D(self):
+ self._testBCastD([2, 3, 0], [2, 3, 1])
+
+ def testBCast_11A(self):
+ self._testBCastA([1, 3, 2], [1, 3, 2])
+
+ def testBCast_11B(self):
+ self._testBCastB([1, 3, 2], [1, 3, 2])
+
+ def testBCast_11C(self):
+ self._testBCastC([1, 3, 2], [1, 3, 2])
+
+ def testBCast_11D(self):
+ self._testBCastD([1, 3, 2], [1, 3, 2])
+
+ def testBCast_12A(self):
+ self._testBCastA([1, 1, 1, 1, 3, 2], [1, 3, 2])
+
+ def testBCast_12B(self):
+ self._testBCastB([1, 1, 1, 1, 3, 2], [1, 3, 2])
+
+ def testBCast_12C(self):
+ self._testBCastC([1, 1, 1, 1, 3, 2], [1, 3, 2])
+
+ def testBCast_12D(self):
+ self._testBCastD([1, 1, 1, 1, 3, 2], [1, 3, 2])
+
+ def testBCast_13A(self):
+ self._testBCastA([1, 3, 2, 1, 1], [1])
+
+ def testBCast_13B(self):
+ self._testBCastB([1, 3, 2, 1, 1], [1])
+
+ def testBCast_13C(self):
+ self._testBCastC([1, 3, 2, 1, 1], [1])
+
+ def testBCast_13D(self):
+ self._testBCastD([1, 3, 2, 1, 1], [1])
+
+ def testBCast_14A(self):
+ self._testBCastA([2, 3, 1, 1, 5], [1])
+
+ def testBCast_14B(self):
+ self._testBCastB([2, 3, 1, 1, 5], [1])
+
+ def testBCast_14C(self):
+ self._testBCastC([2, 3, 1, 1, 5], [1])
+
+ def testBCast_14D(self):
+ self._testBCastD([2, 3, 1, 1, 5], [1])
+
+ def testBCast_15A(self):
+ self._testBCastA([10, 3, 1, 2], [3, 1, 2])
+
+ def testBCast_15B(self):
+ self._testBCastB([10, 3, 1, 2], [3, 1, 2])
+
+ def testBCast_15C(self):
+ self._testBCastC([10, 3, 1, 2], [3, 1, 2])
+
+ def testBCast_15D(self):
+ self._testBCastD([10, 3, 1, 2], [3, 1, 2])
+
+ def testMismatchedDimensions(self):
+ for func in [tf.add, tf.sub, tf.mul, tf.div,
+ _ADD, _SUB, _MUL, _DIV]:
+ with self.assertRaisesWithPredicateMatch(
+ ValueError, lambda e: "Incompatible shapes" in e.message):
+ func(tf.convert_to_tensor([10.0, 20.0, 30.0]),
+ tf.convert_to_tensor([[40.0, 50.0], [60.0, 70.0]]))
+
+
+class ComparisonOpTest(tf.test.TestCase):
+
+ def _compare(self, func, x, y, dtype):
+ with self.test_session(use_gpu=False):
+ out = func(tf.convert_to_tensor(np.array([x]).astype(dtype)),
+ tf.convert_to_tensor(np.array([y]).astype(dtype)))
+ ret = out.eval()
+ return ret[0]
+
+ def testScalarCompareScalar(self):
+ dtypes = [np.float32, np.float64, np.int32, np.int64]
+ data = [-1, 0, 1]
+ for t in dtypes:
+ for x in data:
+ for y in data:
+ self.assertEqual(self._compare(tf.less, x, y, t),
+ x < y)
+ self.assertEqual(self._compare(tf.less_equal, x, y, t),
+ x <= y)
+ self.assertEqual(self._compare(tf.greater, x, y, t),
+ x > y)
+ self.assertEqual(self._compare(tf.greater_equal, x, y, t),
+ x >= y)
+ self.assertEqual(self._compare(tf.equal, x, y, t),
+ x == y)
+ self.assertEqual(self._compare(tf.not_equal, x, y, t),
+ x != y)
+
+ def _compareCpu(self, x, y, np_func, tf_func):
+ np_ans = np_func(x, y)
+ with self.test_session(use_gpu=False):
+ out = tf_func(tf.convert_to_tensor(x), tf.convert_to_tensor(y))
+ tf_cpu = out.eval()
+ self.assertAllEqual(np_ans, tf_cpu)
+
+ def _compareGpu(self, x, y, np_func, tf_func):
+ np_ans = np_func(x, y)
+ with self.test_session(use_gpu=True):
+ out = tf_func(tf.convert_to_tensor(x), tf.convert_to_tensor(y))
+ tf_gpu = out.eval()
+ self.assertAllEqual(np_ans, tf_gpu)
+
+ def _compareBoth(self, x, y, np_func, tf_func):
+ self._compareCpu(x, y, np_func, tf_func)
+ if x.dtype == np.float32 or x.dtype == np.float64:
+ self._compareGpu(x, y, np_func, tf_func)
+
+ def testTensorCompareTensor(self):
+ x = np.linspace(-15, 15, 6).reshape(1, 3, 2)
+ y = np.linspace(20, -10, 6).reshape(1, 3, 2)
+ for t in [np.float32, np.float64, np.int32, np.int64]:
+ xt = x.astype(t)
+ yt = y.astype(t)
+ self._compareBoth(xt, yt, np.less, tf.less)
+ self._compareBoth(xt, yt, np.less_equal, tf.less_equal)
+ self._compareBoth(xt, yt, np.greater, tf.greater)
+ self._compareBoth(xt, yt, np.greater_equal, tf.greater_equal)
+ self._compareBoth(xt, yt, np.equal, tf.equal)
+ self._compareBoth(xt, yt, np.not_equal, tf.not_equal)
+ # TODO(zhifengc): complex64 doesn't work on GPU yet.
+ self._compareCpu(x.astype(np.complex64), y.astype(np.complex64),
+ np.equal, tf.equal)
+ self._compareCpu(x.astype(np.complex64), y.astype(np.complex64),
+ np.not_equal, tf.not_equal)
+
+ def _compareBCast(self, xs, ys, dtype, np_func, tf_func):
+ x = np.linspace(-15, 15, np.prod(xs)).astype(dtype).reshape(xs)
+ y = np.linspace(20, -10, np.prod(ys)).astype(dtype).reshape(ys)
+ self._compareCpu(x, y, np_func, tf_func)
+ self._compareCpu(y, x, np_func, tf_func)
+ if x.dtype == np.float32 or x.dtype == np.float64:
+ self._compareGpu(x, y, np_func, tf_func)
+ self._compareGpu(y, x, np_func, tf_func)
+
+ def _testBCastByFunc(self, np_func, tf_func):
+ shapes = [
+ ([1, 3, 2], [1]),
+ ([1, 3, 2], [2]),
+ ([1, 3, 2], [3, 2]),
+ ([1, 3, 2], [3, 1]),
+ ([1, 3, 2], [1, 3, 2]),
+ ([1, 3, 2], [2, 3, 1]),
+ ([1, 3, 2], [2, 1, 1]),
+ ([1, 3, 2], [1, 3, 1]),
+ ([2, 1, 5], [2, 3, 1]),
+ ([2, 0, 5], [2, 0, 1]),
+ ([2, 3, 0], [2, 3, 1]),
+ ]
+ dtypes = [
+ np.float32,
+ np.float64,
+ np.int32,
+ np.int64,
+ ]
+ for (xs, ys) in shapes:
+ for dtype in dtypes:
+ self._compareBCast(xs, ys, dtype, np_func, tf_func)
+
+ def testBCastLess(self):
+ self._testBCastByFunc(np.less, tf.less)
+
+ def testBCastLessEqual(self):
+ self._testBCastByFunc(np.less_equal, tf.less_equal)
+
+ def testBCastGreater(self):
+ self._testBCastByFunc(np.greater, tf.greater)
+
+ def testBCastGreaterEqual(self):
+ self._testBCastByFunc(np.greater_equal, tf.greater_equal)
+
+ def testBCastEqual(self):
+ self._testBCastByFunc(np.equal, tf.equal)
+
+ def testBCastNotEqual(self):
+ self._testBCastByFunc(np.not_equal, tf.not_equal)
+
+ def testShapeMismatch(self):
+ dtypes = [np.float32, np.float64, np.int32, np.int64]
+ funcs = [tf.less, tf.less_equal, tf.greater,
+ tf.greater_equal, tf.equal, tf.not_equal]
+ x = np.arange(0, 10).reshape([2, 5])
+ y = np.arange(0, 10).reshape([5, 2])
+ for t in dtypes:
+ for f in funcs:
+ with self.assertRaisesWithPredicateMatch(
+ ValueError, lambda e: "Incompatible shapes" in e.message):
+ f(x.astype(t), y.astype(t))
+
+
+class LogicalOpTest(tf.test.TestCase):
+
+ def _compareBinary(self, x, y, np_func, tf_func, use_gpu=False):
+ np_ans = np_func(x, y)
+ with self.test_session(use_gpu=use_gpu):
+ inx = tf.convert_to_tensor(x)
+ iny = tf.convert_to_tensor(y)
+ out = tf_func(inx, iny)
+ tf_val = out.eval()
+ self.assertEqual(out.dtype, tf.bool)
+ self.assertAllEqual(np_ans, tf_val)
+ self.assertShapeEqual(np_ans, out)
+
+ def _not(self, x, use_gpu=False):
+ np_ans = np.logical_not(x)
+ with self.test_session(use_gpu=use_gpu):
+ out = tf.logical_not(tf.convert_to_tensor(x))
+ tf_val = out.eval()
+ self.assertEqual(out.dtype, tf.bool)
+ self.assertAllEqual(np_ans, tf_val)
+ self.assertShapeEqual(np_ans, out)
+
+ def testScalar(self):
+ data = [np.array([True]), np.array([False])]
+ for use_gpu in [True, False]:
+ for x in data:
+ self._not(x, use_gpu)
+ for x in data:
+ for y in data:
+ self._compareBinary(
+ x, y, np.logical_and, tf.logical_and, use_gpu)
+ self._compareBinary(
+ x, y, np.logical_or, tf.logical_or, use_gpu)
+ self._compareBinary(
+ x, y, np.logical_xor, tf.logical_xor, use_gpu)
+
+ def testTensor(self):
+ x = np.random.randint(0, 2, 6).astype(np.bool).reshape(1, 3, 2)
+ y = np.random.randint(0, 2, 6).astype(np.bool).reshape(1, 3, 2)
+ for use_gpu in [True, False]:
+ self._not(x, use_gpu)
+ self._compareBinary(x, y, np.logical_and, tf.logical_and, use_gpu)
+ self._compareBinary(x, y, np.logical_or, tf.logical_or, use_gpu)
+ self._compareBinary(x, y, np.logical_xor, tf.logical_xor, use_gpu)
+
+ def testBCast(self):
+ shapes = [
+ ([1, 3, 2], [1]),
+ ([1, 3, 2], [2]),
+ ([1, 3, 2], [3, 2]),
+ ([1, 3, 2], [3, 1]),
+ ([1, 3, 2], [1, 3, 2]),
+ ([1, 3, 2], [2, 3, 1]),
+ ([1, 3, 2], [2, 1, 1]),
+ ([1, 3, 2], [1, 3, 1]),
+ ([2, 1, 5], [2, 3, 1]),
+ ([2, 0, 5], [2, 0, 1]),
+ ([2, 3, 0], [2, 3, 1]),
+ ]
+ for (xs, ys) in shapes:
+ x = np.random.randint(0, 2, np.prod(xs)).astype(np.bool).reshape(xs)
+ y = np.random.randint(0, 2, np.prod(ys)).astype(np.bool).reshape(ys)
+ for use_gpu in [True, False]:
+ self._compareBinary(x, y, np.logical_and, tf.logical_and, use_gpu)
+ self._compareBinary(x, y, np.logical_or, tf.logical_or, use_gpu)
+ self._compareBinary(x, y, np.logical_xor, tf.logical_xor, use_gpu)
+
+ def testShapeMismatch(self):
+ x = np.random.randint(0, 2, 6).astype(np.bool).reshape(1, 3, 2)
+ y = np.random.randint(0, 2, 6).astype(np.bool).reshape(3, 2, 1)
+ for f in [tf.logical_and, tf.logical_or, tf.logical_xor]:
+ with self.assertRaisesWithPredicateMatch(
+ ValueError, lambda e: "Incompatible shapes" in e.message):
+ f(x, y)
+
+
+class SelectOpTest(tf.test.TestCase):
+
+ def _compare(self, c, x, y, use_gpu):
+ np_ans = np.where(c, x, y)
+ with self.test_session(use_gpu=use_gpu):
+ out = tf.select(c, x, y)
+ tf_ans = out.eval()
+ self.assertAllEqual(np_ans, tf_ans)
+ self.assertShapeEqual(np_ans, out)
+
+ def _compareGradientX(self, c, x, y):
+ with self.test_session():
+ inx = tf.convert_to_tensor(x)
+ iny = tf.convert_to_tensor(y)
+ out = tf.select(c, inx, iny)
+ s = list(np.shape(c))
+ jacob_t, jacob_n = gc.ComputeGradient(inx, s, out, s, x_init_value=x)
+ if x.dtype == np.float32:
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-3, atol=1e-3)
+ elif x.dtype == np.float64:
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-5, atol=1e-5)
+
+ def _compareGradientY(self, c, x, y):
+ with self.test_session():
+ inx = tf.convert_to_tensor(x)
+ iny = tf.convert_to_tensor(y)
+ out = tf.select(c, inx, iny)
+ s = list(np.shape(c))
+ jacob_t, jacob_n = gc.ComputeGradient(iny, s, out, s, x_init_value=y)
+ if x.dtype == np.float32:
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-3, atol=1e-3)
+ elif x.dtype == np.float64:
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-5, atol=1e-5)
+
+ def testBasic(self):
+ c = np.random.randint(0, 2, 6).astype(np.bool).reshape(1, 3, 2)
+ x = np.random.rand(1, 3, 2) * 100
+ y = np.random.rand(1, 3, 2) * 100
+ for t in [np.float32, np.float64, np.int32, np.int64, np.complex64]:
+ xt = x.astype(t)
+ yt = y.astype(t)
+ self._compare(c, xt, yt, use_gpu=False)
+ if t in [np.float32, np.float64]:
+ self._compare(c, xt, yt, use_gpu=True)
+
+ def testGradients(self):
+ c = np.random.randint(0, 2, 6).astype(np.bool).reshape(1, 3, 2)
+ x = np.random.rand(1, 3, 2) * 100
+ y = np.random.rand(1, 3, 2) * 100
+ for t in [np.float32, np.float64]:
+ xt = x.astype(t)
+ yt = y.astype(t)
+ self._compareGradientX(c, xt, yt)
+ self._compareGradientY(c, xt, yt)
+
+ def testShapeMismatch(self):
+ c = np.random.randint(0, 2, 6).astype(np.bool).reshape(1, 3, 2)
+ x = np.random.rand(1, 3, 2) * 100
+ y = np.random.rand(2, 5, 3) * 100
+ for t in [np.float32, np.float64, np.int32, np.int64, np.complex64]:
+ xt = x.astype(t)
+ yt = y.astype(t)
+ with self.assertRaises(ValueError):
+ tf.select(c, xt, yt)
+
+
+class MinMaxOpTest(tf.test.TestCase):
+
+ def _compare(self, x, y, use_gpu):
+ np_min, np_max = np.minimum(x, y), np.maximum(x, y)
+ with self.test_session(use_gpu=use_gpu) as sess:
+ inx = tf.convert_to_tensor(x)
+ iny = tf.convert_to_tensor(y)
+ omin, omax = tf.minimum(inx, iny), tf.maximum(inx, iny)
+ tf_min, tf_max = sess.run([omin, omax])
+ self.assertAllEqual(np_min, tf_min)
+ self.assertAllEqual(np_max, tf_max)
+
+ def testBasic(self):
+ x = np.random.rand(1, 3, 2) * 100.
+ y = np.random.rand(1, 3, 2) * 100.
+ for t in [np.float32, np.float64, np.int32, np.int64]:
+ self._compare(x.astype(t), y.astype(t), use_gpu=False)
+ self._compare(x.astype(t), y.astype(t), use_gpu=True)
+
+ def testDifferentShapes(self):
+ x = np.random.rand(1, 3, 2) * 100.
+ y = np.random.rand(2) * 100. # should broadcast
+ for t in [np.float32, np.float64, np.int32, np.int64]:
+ self._compare(x.astype(t), y.astype(t), use_gpu=False)
+ self._compare(x.astype(t), y.astype(t), use_gpu=True)
+
+ def testScalar(self):
+ x = np.random.rand(1, 3, 2) * 100.
+ y = np.asscalar(np.random.rand(1) * 100.) # should broadcast
+ # dropped np.float64, int64 because TF automatically converts to 32 bit
+ for t in [np.float32, np.int32]:
+ self._compare(x.astype(t), t(y), use_gpu=False)
+ self._compare(x.astype(t), t(y), use_gpu=True)
+
+ def _compareGradientX(self, func, x, y):
+ with self.test_session():
+ inx = tf.convert_to_tensor(x)
+ iny = tf.convert_to_tensor(y)
+ out = func(inx, iny)
+ s = list(np.shape(x))
+ jacob_t, jacob_n = gc.ComputeGradient(inx, s, out, s, x_init_value=x)
+ if x.dtype == np.float32:
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-3, atol=1e-3)
+ elif x.dtype == np.float64:
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-5, atol=1e-5)
+
+ def _compareGradientY(self, func, x, y):
+ with self.test_session():
+ inx = tf.convert_to_tensor(x)
+ iny = tf.convert_to_tensor(y)
+ out = func(inx, iny)
+ s = list(np.shape(x))
+ jacob_t, jacob_n = gc.ComputeGradient(iny, s, out, s, x_init_value=y)
+ if x.dtype == np.float32:
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-3, atol=1e-3)
+ elif x.dtype == np.float64:
+ self.assertAllClose(jacob_t, jacob_n, rtol=1e-5, atol=1e-5)
+
+ def testGradients(self):
+ x = np.random.rand(1, 3, 2) * 100.
+ # ensure x != y
+ y = x + (np.random.randint(2, size=x.shape) - .5) * 2 # -1 or +1
+ self._compareGradientX(tf.maximum, x, y)
+ self._compareGradientY(tf.maximum, x, y)
+ self._compareGradientX(tf.minimum, x, y)
+ self._compareGradientY(tf.minimum, x, y)
+
+
+class MathOpsOverloadTest(tf.test.TestCase):
+
+ def _computeTensorAndLiteral(self, x, y, dtype, func):
+ with self.test_session(use_gpu=False):
+ inx = tf.convert_to_tensor(x, dtype=dtype)
+ z = func(inx, y) # Should use __add__, __sub__, etc.
+ return z.eval()
+
+ def _computeLiteralAndTensor(self, x, y, dtype, func):
+ with self.test_session(use_gpu=False):
+ iny = tf.convert_to_tensor(y, dtype=dtype)
+ z = func(x, iny) # Should use __radd__, __rsub__, etc.
+ return z.eval()
+
+ def _compareBinary(self, x, y, dtype, np_func, tf_func):
+ np_ans = np_func(x, y)
+ self.assertAllClose(np_ans, self._computeTensorAndLiteral(
+ x, y, dtype, tf_func))
+ self.assertAllClose(np_ans, self._computeLiteralAndTensor(
+ x, y, dtype, tf_func))
+
+ def _compareUnary(self, x, dtype, np_func, tf_func):
+ np_ans = np_func(x)
+ with self.test_session(use_gpu=False):
+ self.assertAllClose(np_ans, tf_func(tf.convert_to_tensor(x, dtype=dtype)).eval())
+
+ def testOverload(self):
+ dtypes = [
+ tf.float32,
+ tf.float64,
+ tf.int32,
+ tf.int64,
+ tf.complex64,
+ ]
+ funcs = [
+ (np.add, _ADD),
+ (np.subtract, _SUB),
+ (np.multiply, _MUL),
+ (np.divide, _DIV)
+ ]
+ for dtype in dtypes:
+ for np_func, tf_func in funcs:
+ self._compareBinary(10, 5, dtype, np_func, tf_func)
+ # Mod only works for int32 and int64.
+ for dtype in [tf.int32, tf.int64]:
+ self._compareBinary(10, 3, dtype, np.mod, _MOD)
+
+ def testOverloadComparisons(self):
+ dtypes = [
+ tf.float32,
+ tf.float64,
+ tf.int32,
+ tf.int64,
+ ]
+ funcs = [
+ (np.less, _LT),
+ (np.less_equal, _LE),
+ (np.greater, _GT),
+ (np.greater_equal, _GE),
+ ]
+ for dtype in dtypes:
+ for np_func, tf_func in funcs:
+ self._compareBinary(10, 5, dtype, np_func, tf_func)
+ logical_funcs = [
+ (np.logical_and, _AND),
+ (np.logical_or, _OR),
+ (np.logical_xor, _XOR),
+ ]
+ for np_func, tf_func in logical_funcs:
+ self._compareBinary(True, False, tf.bool, np_func, tf_func)
+ self._compareBinary(True, True, tf.bool, np_func, tf_func)
+ self._compareBinary(False, False, tf.bool, np_func, tf_func)
+ self._compareBinary(False, True, tf.bool, np_func, tf_func)
+ self._compareBinary([True, True, False, False],
+ [True, False, True, False],
+ tf.bool, np_func, tf_func)
+ self._compareUnary(True, tf.bool, np.logical_not, _INV)
+ self._compareUnary(False, tf.bool, np.logical_not, _INV)
+ self._compareUnary([True, False], tf.bool, np.logical_not, _INV)
+
+
+class IsFiniteInfNanTest(tf.test.TestCase):
+
+ def _compare(self, x, use_gpu):
+ np_finite, np_inf, np_nan = np.isfinite(x), np.isinf(x), np.isnan(x)
+ with self.test_session(use_gpu=use_gpu) as sess:
+ inx = tf.convert_to_tensor(x)
+ ofinite, oinf, onan = tf.is_finite(inx), tf.is_inf(
+ inx), tf.is_nan(inx)
+ tf_finite, tf_inf, tf_nan = sess.run([ofinite, oinf, onan])
+ self.assertAllEqual(np_inf, tf_inf)
+ self.assertAllEqual(np_nan, tf_nan)
+ self.assertAllEqual(np_finite, tf_finite)
+ self.assertShapeEqual(np_inf, oinf)
+ self.assertShapeEqual(np_nan, onan)
+ self.assertShapeEqual(np_finite, ofinite)
+
+ def _testDtype(self, dtype):
+ fi = np.finfo(dtype)
+ data = np.array([0, -1, 1, fi.resolution, -fi.resolution, fi.min, fi.max,
+ -np.inf, np.inf, np.nan]).astype(dtype)
+ self._compare(data, use_gpu=False)
+ self._compare(data, use_gpu=True)
+
+ def testFloat(self):
+ self._testDtype(np.float32)
+
+ def testDouble(self):
+ self._testDtype(np.float64)
+
+
+class RoundingTest(tf.test.TestCase):
+
+ def _compare(self, x, use_gpu):
+ np_floor, np_ceil = np.floor(x), np.ceil(x)
+ with self.test_session(use_gpu=use_gpu) as sess:
+ inx = tf.convert_to_tensor(x)
+ ofloor, oceil = tf.floor(inx), tf.ceil(inx)
+ tf_floor, tf_ceil = sess.run([ofloor, oceil])
+ self.assertAllEqual(np_floor, tf_floor)
+ self.assertAllEqual(np_ceil, tf_ceil)
+ self.assertShapeEqual(np_floor, ofloor)
+ self.assertShapeEqual(np_ceil, oceil)
+
+ def _testDtype(self, dtype):
+ data = (np.arange(-3, 3) / 4.).reshape([1, 3, 2]).astype(dtype)
+ self._compare(data, use_gpu=True)
+ self._compare(data, use_gpu=True)
+
+ def testTypes(self):
+ for dtype in [np.float32, np.float64]:
+ self._testDtype(dtype)
+
+
+class ComplexMakeRealImagTest(tf.test.TestCase):
+
+ def _compareMake(self, real, imag, use_gpu):
+ np_ans = real + (1j) * imag
+ with self.test_session(use_gpu=use_gpu):
+ real = tf.convert_to_tensor(real)
+ imag = tf.convert_to_tensor(imag)
+ tf_ans = tf.complex(real, imag)
+ out = tf_ans.eval()
+ self.assertAllEqual(np_ans, out)
+ self.assertShapeEqual(np_ans, tf_ans)
+
+ def testMake(self):
+ real = (np.arange(-3, 3) / 4.).reshape([1, 3, 2]).astype(np.float32)
+ imag = (np.arange(-3, 3) / 5.).reshape([1, 3, 2]).astype(np.float32)
+ for use_gpu in [False, True]:
+ self._compareMake(real, imag, use_gpu)
+ self._compareMake(real, 12.0, use_gpu)
+ self._compareMake(23.0, imag, use_gpu)
+
+ def _compareRealImag(self, cplx, use_gpu):
+ np_real, np_imag = np.real(cplx), np.imag(cplx)
+ with self.test_session(use_gpu=use_gpu) as sess:
+ inx = tf.convert_to_tensor(cplx)
+ tf_real = tf.real(inx)
+ tf_imag = tf.imag(inx)
+ tf_real_val, tf_imag_val = sess.run([tf_real, tf_imag])
+ self.assertAllEqual(np_real, tf_real_val)
+ self.assertAllEqual(np_imag, tf_imag_val)
+ self.assertShapeEqual(np_real, tf_real)
+ self.assertShapeEqual(np_imag, tf_imag)
+
+ def testRealImag(self):
+ real = (np.arange(-3, 3) / 4.).reshape([1, 3, 2]).astype(np.float32)
+ imag = (np.arange(-3, 3) / 5.).reshape([1, 3, 2]).astype(np.float32)
+ cplx = real + (1j) * imag
+ self._compareRealImag(cplx, use_gpu=False)
+ self._compareRealImag(cplx, use_gpu=True)
+
+ def _compareConj(self, cplx, use_gpu):
+ np_ans = np.conj(cplx)
+ with self.test_session(use_gpu=use_gpu):
+ inx = tf.convert_to_tensor(cplx)
+ tf_conj = tf.conj(inx)
+ tf_ans = tf_conj.eval()
+ self.assertAllEqual(np_ans, tf_ans)
+ self.assertShapeEqual(np_ans, tf_conj)
+
+ def testConj(self):
+ real = (np.arange(-3, 3) / 4.).reshape([1, 3, 2]).astype(np.float32)
+ imag = (np.arange(-3, 3) / 5.).reshape([1, 3, 2]).astype(np.float32)
+ cplx = real + (1j) * imag
+ self._compareConj(cplx, use_gpu=False)
+ self._compareConj(cplx, use_gpu=True)
+
+ def _compareGradient(self, x):
+ # x[:, 0] is real, x[:, 1] is imag. We combine real and imag into
+ # complex numbers. Then, we extract real and imag parts and
+ # computes the squared sum. This is obviously the same as sum(real
+ # * real) + sum(imag * imag). We just want to make sure the
+ # gradient function is checked.
+ with self.test_session():
+ inx = tf.convert_to_tensor(x)
+ real, imag = tf.split(1, 2, inx)
+ real, imag = tf.reshape(real, [-1]), tf.reshape(imag, [-1])
+ cplx = tf.complex(real, imag)
+ cplx = tf.conj(cplx)
+ loss = tf.reduce_sum(
+ tf.square(tf.real(cplx))) + tf.reduce_sum(
+ tf.square(tf.imag(cplx)))
+ epsilon = 1e-3
+ jacob_t, jacob_n = gc.ComputeGradient(inx, list(x.shape), loss, [1],
+ x_init_value=x, delta=epsilon)
+ self.assertAllClose(jacob_t, jacob_n, rtol=epsilon, atol=epsilon)
+
+ def testGradient(self):
+ data = np.arange(1, 2, 0.10).reshape([5, 2]).astype(np.float32)
+ self._compareGradient(data)
+
+ def _compareMulGradient(self, data):
+ # data is a float matrix of shape [n, 4]. data[:, 0], data[:, 1],
+ # data[:, 2], data[:, 3] are real parts of x, imaginary parts of
+ # x, real parts of y and imaginary parts of y.
+ with self.test_session():
+ inp = tf.convert_to_tensor(data)
+ xr, xi, yr, yi = tf.split(1, 4, inp)
+
+ def vec(x): # Reshape to a vector
+ return tf.reshape(x, [-1])
+ xr, xi, yr, yi = vec(xr), vec(xi), vec(yr), vec(yi)
+
+ def cplx(r, i): # Combine to a complex vector
+ return tf.complex(r, i)
+ x, y = cplx(xr, xi), cplx(yr, yi)
+ # z is x times y in complex plane.
+ z = x * y
+ # Defines the loss function as the sum of all coefficients of z.
+ loss = tf.reduce_sum(tf.real(z) + tf.imag(z))
+ epsilon = 0.005
+ jacob_t, jacob_n = gc.ComputeGradient(inp, list(data.shape), loss, [1],
+ x_init_value=data, delta=epsilon)
+ self.assertAllClose(jacob_t, jacob_n, rtol=epsilon, atol=epsilon)
+
+ def testMulGradient(self):
+ data = np.arange(1, 2, 0.125).reshape([2, 4]).astype(np.float32)
+ self._compareMulGradient(data)
+
+
+class AccumulateTest(tf.test.TestCase):
+
+ def testSimple(self):
+ with self.test_session():
+ random_arrays = [np.random.rand(16, 16, 16, 16).astype(np.float32)
+ for _ in range(20)]
+ random_tensors = [tf.convert_to_tensor(x, dtype=tf.float32)
+ for x in random_arrays]
+ tf_val = tf.accumulate_n(random_tensors)
+ np_val = random_arrays[0]
+ for random_array in random_arrays[1:]:
+ np_val += random_array
+ self.assertAllClose(np_val, tf_val.eval())
+
+ def testZeroArgs(self):
+ with self.test_session():
+ with self.assertRaises(ValueError):
+ tf_val = tf.accumulate_n([])
+ tf_val.eval()
+
+if __name__ == "__main__":
+ tf.test.main()