1# Copyright 2016 The TensorFlow Authors. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14# ============================================================================== 15"""Functional tests for basic component wise operations using a GPU device.""" 16 17from __future__ import absolute_import 18from __future__ import division 19from __future__ import print_function 20 21import itertools 22import threading 23 24import numpy as np 25from six.moves import xrange # pylint: disable=redefined-builtin 26 27from tensorflow.python.framework import dtypes 28from tensorflow.python.framework import ops 29from tensorflow.python.framework import random_seed 30from tensorflow.python.framework import test_util 31from tensorflow.python.ops import array_ops 32from tensorflow.python.ops import gradient_checker 33from tensorflow.python.ops import math_ops 34from tensorflow.python.ops import random_ops 35from tensorflow.python.ops import variables 36from tensorflow.python.ops.gen_array_ops import _broadcast_gradient_args 37from tensorflow.python.platform import test 38 39 40class GPUBinaryOpsTest(test.TestCase): 41 42 def _compareGPU(self, x, y, np_func, tf_func): 43 with self.test_session(use_gpu=True) as sess: 44 inx = ops.convert_to_tensor(x) 45 iny = ops.convert_to_tensor(y) 46 out = tf_func(inx, iny) 47 tf_gpu = sess.run(out) 48 49 with self.test_session(use_gpu=False) as sess: 50 inx = ops.convert_to_tensor(x) 51 iny = ops.convert_to_tensor(y) 52 out = tf_func(inx, iny) 53 tf_cpu = sess.run(out) 54 55 self.assertAllClose(tf_cpu, tf_gpu) 56 57 def testFloatBasic(self): 58 x = np.linspace(-5, 20, 15).reshape(1, 3, 5).astype(np.float32) 59 y = np.linspace(20, -5, 15).reshape(1, 3, 5).astype(np.float32) 60 self._compareGPU(x, y, np.add, math_ops.add) 61 self._compareGPU(x, y, np.subtract, math_ops.subtract) 62 self._compareGPU(x, y, np.multiply, math_ops.multiply) 63 self._compareGPU(x, y + 0.1, np.true_divide, math_ops.truediv) 64 self._compareGPU(x, y + 0.1, np.floor_divide, math_ops.floordiv) 65 self._compareGPU(x, y, np.power, math_ops.pow) 66 67 def testFloatWithBCast(self): 68 x = np.linspace(-5, 20, 15).reshape(3, 5).astype(np.float32) 69 y = np.linspace(20, -5, 30).reshape(2, 3, 5).astype(np.float32) 70 self._compareGPU(x, y, np.add, math_ops.add) 71 self._compareGPU(x, y, np.subtract, math_ops.subtract) 72 self._compareGPU(x, y, np.multiply, math_ops.multiply) 73 self._compareGPU(x, y + 0.1, np.true_divide, math_ops.truediv) 74 75 def testDoubleBasic(self): 76 x = np.linspace(-5, 20, 15).reshape(1, 3, 5).astype(np.float64) 77 y = np.linspace(20, -5, 15).reshape(1, 3, 5).astype(np.float64) 78 self._compareGPU(x, y, np.add, math_ops.add) 79 self._compareGPU(x, y, np.subtract, math_ops.subtract) 80 self._compareGPU(x, y, np.multiply, math_ops.multiply) 81 self._compareGPU(x, y + 0.1, np.true_divide, math_ops.truediv) 82 83 def testDoubleWithBCast(self): 84 x = np.linspace(-5, 20, 15).reshape(3, 5).astype(np.float64) 85 y = np.linspace(20, -5, 30).reshape(2, 3, 5).astype(np.float64) 86 self._compareGPU(x, y, np.add, math_ops.add) 87 self._compareGPU(x, y, np.subtract, math_ops.subtract) 88 self._compareGPU(x, y, np.multiply, math_ops.multiply) 89 self._compareGPU(x, y + 0.1, np.true_divide, math_ops.truediv) 90 91 92class MathBuiltinUnaryTest(test.TestCase): 93 94 def _compare(self, x, np_func, tf_func, use_gpu): 95 np_out = np_func(x) 96 with self.test_session(use_gpu=use_gpu) as sess: 97 inx = ops.convert_to_tensor(x) 98 ofunc = tf_func(inx) 99 tf_out = sess.run(ofunc) 100 self.assertAllClose(np_out, tf_out) 101 102 def _inv(self, x): 103 return 1.0 / x 104 105 def _rsqrt(self, x): 106 return self._inv(np.sqrt(x)) 107 108 def _testDtype(self, dtype, use_gpu): 109 data = (np.arange(-3, 3) / 4.).reshape([1, 3, 2]).astype(dtype) 110 data_gt_1 = data + 2 # for x > 1 111 self._compare(data, np.abs, math_ops.abs, use_gpu) 112 self._compare(data, np.arccos, math_ops.acos, use_gpu) 113 self._compare(data, np.arcsin, math_ops.asin, use_gpu) 114 self._compare(data, np.arcsinh, math_ops.asinh, use_gpu) 115 self._compare(data_gt_1, np.arccosh, math_ops.acosh, use_gpu) 116 self._compare(data, np.arctan, math_ops.atan, use_gpu) 117 self._compare(data, np.ceil, math_ops.ceil, use_gpu) 118 self._compare(data, np.cos, math_ops.cos, use_gpu) 119 self._compare(data, np.cosh, math_ops.cosh, use_gpu) 120 self._compare(data, np.exp, math_ops.exp, use_gpu) 121 self._compare(data, np.floor, math_ops.floor, use_gpu) 122 self._compare(data, np.log, math_ops.log, use_gpu) 123 self._compare(data, np.log1p, math_ops.log1p, use_gpu) 124 self._compare(data, np.negative, math_ops.negative, use_gpu) 125 self._compare(data, self._rsqrt, math_ops.rsqrt, use_gpu) 126 self._compare(data, np.sin, math_ops.sin, use_gpu) 127 self._compare(data, np.sinh, math_ops.sinh, use_gpu) 128 self._compare(data, np.sqrt, math_ops.sqrt, use_gpu) 129 self._compare(data, np.square, math_ops.square, use_gpu) 130 self._compare(data, np.tan, math_ops.tan, use_gpu) 131 self._compare(data, np.tanh, math_ops.tanh, use_gpu) 132 self._compare(data, np.arctanh, math_ops.atanh, use_gpu) 133 134 def testTypes(self): 135 for dtype in [np.float32]: 136 self._testDtype(dtype, use_gpu=True) 137 138 def testFloorDivide(self): 139 x = (1 + np.linspace(0, 5, np.prod([1, 3, 2]))).astype(np.float32).reshape( 140 [1, 3, 2]) 141 y = (1 + np.linspace(0, 5, np.prod([1, 3, 2]))).astype(np.float32).reshape( 142 [1, 3, 2]) 143 144 np_out = np.floor_divide(x, y + 0.1) 145 146 with self.test_session(use_gpu=True) as sess: 147 inx = ops.convert_to_tensor(x) 148 iny = ops.convert_to_tensor(y + 0.1) 149 ofunc = inx / iny 150 out_func2 = math_ops.floor(ofunc) 151 tf_out = sess.run(out_func2) 152 153 self.assertAllClose(np_out, tf_out) 154 155 156class BroadcastSimpleTest(test.TestCase): 157 158 def _GetGradientArgs(self, xs, ys): 159 with self.test_session(use_gpu=True) as sess: 160 return sess.run(_broadcast_gradient_args(xs, ys)) 161 162 def testBroadcast(self): 163 r0, r1 = self._GetGradientArgs([2, 3, 5], [1]) 164 self.assertAllEqual(r0, []) 165 self.assertAllEqual(r1, [0, 1, 2]) 166 167 _GRAD_TOL = {dtypes.float32: 1e-3} 168 169 def _compareGradientX(self, 170 x, 171 y, 172 np_func, 173 tf_func, 174 numeric_gradient_type=None): 175 z = np_func(x, y) 176 zs = list(z.shape) 177 with self.test_session(): 178 inx = ops.convert_to_tensor(x) 179 iny = ops.convert_to_tensor(y) 180 if x.dtype in (np.float32, np.float64): 181 out = 1.1 * tf_func(inx, iny) 182 else: 183 out = tf_func(inx, iny) 184 xs = list(x.shape) 185 jacob_t, jacob_n = gradient_checker.compute_gradient( 186 inx, xs, out, zs, x_init_value=x) 187 tol = self._GRAD_TOL[dtypes.as_dtype(x.dtype)] 188 self.assertAllClose(jacob_t, jacob_n, rtol=tol, atol=tol) 189 190 def _compareGradientY(self, 191 x, 192 y, 193 np_func, 194 tf_func, 195 numeric_gradient_type=None): 196 z = np_func(x, y) 197 zs = list(z.shape) 198 with self.test_session(): 199 inx = ops.convert_to_tensor(x) 200 iny = ops.convert_to_tensor(y) 201 if x.dtype in (np.float32, np.float64): 202 out = 1.1 * tf_func(inx, iny) 203 else: 204 out = tf_func(inx, iny) 205 ys = list(np.shape(y)) 206 jacob_t, jacob_n = gradient_checker.compute_gradient( 207 iny, ys, out, zs, x_init_value=y) 208 tol = self._GRAD_TOL[dtypes.as_dtype(x.dtype)] 209 self.assertAllClose(jacob_t, jacob_n, rtol=tol, atol=tol) 210 211 def _compareGpu(self, x, y, np_func, tf_func): 212 np_ans = np_func(x, y) 213 with self.test_session(use_gpu=True): 214 inx = ops.convert_to_tensor(x) 215 iny = ops.convert_to_tensor(y) 216 out = tf_func(inx, iny) 217 tf_gpu = out.eval() 218 self.assertAllClose(np_ans, tf_gpu) 219 self.assertShapeEqual(np_ans, out) 220 # TODO(zhifengc/ke): make gradient checker work on GPU. 221 222 def testGradient(self): 223 x = (1 + np.linspace(0, 5, np.prod([1, 3, 2]))).astype(np.float32).reshape( 224 [1, 3, 2]) 225 y = (1 + np.linspace(0, 5, np.prod([1, 3, 2]))).astype(np.float32).reshape( 226 [1, 3, 2]) 227 228 self._compareGradientX(x, y, np.true_divide, math_ops.truediv) 229 self._compareGradientY(x, y, np.true_divide, math_ops.truediv) 230 self._compareGpu(x, y, np.true_divide, math_ops.truediv) 231 self._compareGpu(x, y + 0.1, np.floor_divide, math_ops.floordiv) 232 233 234class GpuMultiSessionMemoryTest(test_util.TensorFlowTestCase): 235 """Tests concurrent sessions executing on the same GPU.""" 236 237 def _run_session(self, session, results): 238 n_iterations = 500 239 with session as s: 240 data = variables.Variable(1.0) 241 with ops.device('/device:GPU:0'): 242 random_seed.set_random_seed(1) 243 matrix1 = variables.Variable( 244 random_ops.truncated_normal([1024, 1]), name='matrix1') 245 matrix2 = variables.Variable( 246 random_ops.truncated_normal([1, 1024]), name='matrix2') 247 x1 = math_ops.multiply(data, matrix1, name='x1') 248 x3 = math_ops.matmul(x1, math_ops.matmul(matrix2, matrix1)) 249 x4 = math_ops.matmul(array_ops.transpose(x3), x3, name='x4') 250 s.run(variables.global_variables_initializer()) 251 252 for _ in xrange(n_iterations): 253 value = s.run(x4) 254 results.add(value.flat[0]) 255 if len(results) != 1: 256 break 257 258 def testConcurrentSessions(self): 259 n_threads = 4 260 threads = [] 261 results = [] 262 for _ in xrange(n_threads): 263 session = self.test_session(graph=ops.Graph(), use_gpu=True) 264 results.append(set()) 265 args = (session, results[-1]) 266 threads.append(threading.Thread(target=self._run_session, args=args)) 267 268 for thread in threads: 269 thread.start() 270 for thread in threads: 271 thread.join() 272 273 flat_results = set([x for x in itertools.chain(*results)]) 274 self.assertEqual(1, 275 len(flat_results), 276 'Expected single value, got %r' % flat_results) 277 278 279if __name__ == '__main__': 280 test.main() 281