PageRenderTime 69ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/tensorflow/python/kernel_tests/sparse_tensor_dense_matmul_op_test.py

https://gitlab.com/github-cloud-corporation/tensorflow
Python | 262 lines | 201 code | 36 blank | 25 comment | 25 complexity | 61f7380f7f7e80be5e9cbafeaf9dd23b MD5 | raw file
  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 sparse_ops.sparse_tensor_dense_matmul."""
  16. from __future__ import absolute_import
  17. from __future__ import division
  18. from __future__ import print_function
  19. import sys
  20. import time
  21. import numpy as np
  22. import tensorflow as tf
  23. from tensorflow.python.ops import sparse_ops
  24. # pylint: enable=g-bad-import-order,unused-import
  25. def _maybe_complex(x):
  26. if x.dtype.kind == "c": # complex
  27. return (x + 1j*x) / 2
  28. return x
  29. class SparseTensorDenseMatMulTest(tf.test.TestCase):
  30. def _testMatmul(self, x, y, adjoint_a=False, adjoint_b=False, use_gpu=False):
  31. x_mat = np.matrix(x)
  32. if adjoint_a:
  33. x_mat = x_mat.H
  34. y_mat = np.matrix(y)
  35. if adjoint_b:
  36. y_mat = y_mat.H
  37. np_ans = x_mat * y_mat
  38. x_indices = np.vstack(np.where(x)).astype(np.int64).T
  39. x_values = x[np.where(x)]
  40. x_shape = x.shape
  41. with self.test_session(use_gpu=use_gpu):
  42. sp_x = tf.SparseTensor(indices=x_indices, values=x_values, shape=x_shape)
  43. tf_ans = sparse_ops.sparse_tensor_dense_matmul(
  44. sp_x, y, adjoint_a=adjoint_a, adjoint_b=adjoint_b)
  45. out = tf_ans.eval()
  46. # Ensure that the RHS shape is known at least.
  47. self.assertEqual(tf_ans.get_shape()[1], np_ans.shape[1])
  48. if x.dtype == np.float32:
  49. self.assertAllClose(np_ans, out, rtol=1e-4, atol=1e-4)
  50. elif x.dtype == np.float64:
  51. self.assertAllClose(np_ans, out, rtol=1e-6, atol=1e-6)
  52. else:
  53. self.assertAllClose(np_ans, out, rtol=1e-4, atol=1e-4)
  54. def _testBasic(self, np_dtype):
  55. x = _maybe_complex(np.random.rand(10, 10).astype(np_dtype))
  56. x[np.abs(x) < 0.5] = 0 # Make it sparse
  57. y = _maybe_complex(np.random.randn(10, 20).astype(np_dtype))
  58. self._testMatmul(x, y, use_gpu=True)
  59. self._testMatmul(x, y, use_gpu=False)
  60. def testBasic(self):
  61. np.random.seed(127) # Repeatable results
  62. self._testBasic(np.int32)
  63. self._testBasic(np.float32)
  64. self._testBasic(np.float64)
  65. self._testBasic(np.complex64)
  66. self._testBasic(np.complex128)
  67. # Tests setting one dimension to be a high value.
  68. def _testLarge(self, np_dtype):
  69. r1 = np.random.randint(6000, 20000)
  70. r2 = np.random.randint(1, 10)
  71. r3 = np.random.randint(1, 10)
  72. for m, k, n in [(r1, r2, r3),
  73. (r2, r1, r3),
  74. (r2, r3, r1)]:
  75. x = _maybe_complex(np.random.rand(m, k).astype(np_dtype))
  76. x[np.abs(x) < 0.8] = 0
  77. y = _maybe_complex(np.random.randn(k, n).astype(np_dtype))
  78. self._testMatmul(x, y, use_gpu=False)
  79. self._testMatmul(x, y, use_gpu=True)
  80. def testLarge(self):
  81. np.random.seed(127) # Repeatable results
  82. self._testLarge(np.float32)
  83. self._testLarge(np.float64)
  84. self._testLarge(np.complex64)
  85. self._testLarge(np.complex128)
  86. # Tests random sized matrices.
  87. def testFloatRandom(self):
  88. np.random.seed(127) # Repeatable results
  89. for _ in range(8):
  90. for adjoint_a in [True, False]:
  91. for adjoint_b in [True, False]:
  92. for thresh in [0.0, 0.2, 0.8, 1.0]:
  93. n, k, m = np.random.randint(1, 100, size=3)
  94. x = np.random.rand(n, k).astype(np.float32)
  95. x[x < thresh] = 0 # Make it sparse
  96. y = np.random.randn(k, m).astype(np.float32)
  97. x = x.transpose() if adjoint_a else x
  98. y = y.transpose() if adjoint_b else y
  99. self._testMatmul(x, y, adjoint_a, adjoint_b, use_gpu=False)
  100. self._testMatmul(x, y, adjoint_a, adjoint_b, use_gpu=True)
  101. def _sparse_tensor_dense_vs_dense_matmul_benchmark_dense(
  102. x, y, adjoint_a, adjoint_b):
  103. def body(t, prev):
  104. with tf.control_dependencies([prev]):
  105. return (t + 1, tf.matmul(
  106. x, y, transpose_a=adjoint_a, transpose_b=adjoint_b,
  107. a_is_sparse=True, b_is_sparse=False))
  108. t0 = tf.constant(0)
  109. v0 = tf.constant(0.0)
  110. def _timeit(iterations, _):
  111. (_, final) = tf.while_loop(
  112. lambda t, _: t < iterations, body, (t0, v0),
  113. parallel_iterations=1, back_prop=False)
  114. return [final]
  115. return _timeit
  116. def _sparse_tensor_dense_vs_dense_matmul_benchmark_sparse(
  117. x_ind, x_val, x_shape, y, adjoint_a, adjoint_b):
  118. sp_x = tf.SparseTensor(indices=x_ind, values=x_val, shape=x_shape)
  119. def body(t, prev):
  120. with tf.control_dependencies([prev]):
  121. return (t + 1,
  122. sparse_ops.sparse_tensor_dense_matmul(
  123. sp_x, y, adjoint_a=adjoint_a, adjoint_b=adjoint_b))
  124. t0 = tf.constant(0)
  125. v0 = tf.constant(0.0)
  126. def _timeit(iterations, _):
  127. (_, final) = tf.while_loop(
  128. lambda t, _: t < iterations, body, (t0, v0),
  129. parallel_iterations=1, back_prop=False)
  130. return [final]
  131. return _timeit
  132. def sparse_tensor_dense_vs_dense_matmul_benchmark(
  133. thresh, m, k, n, adjoint_a, adjoint_b, use_gpu, skip_dense=False):
  134. config = tf.ConfigProto()
  135. config.allow_soft_placement = True
  136. # Configurable for benchmarking:
  137. # config.intra_op_parallelism_threads = 100
  138. # config.gpu_options.per_process_gpu_memory_fraction = 0.3
  139. np.random.seed([6, 117]) # Reproducibility
  140. x = np.random.rand(m, k).astype(np.float32)
  141. x[x < thresh] = 0
  142. y = np.random.randn(k, n).astype(np.float32)
  143. if adjoint_a: x = x.T
  144. if adjoint_b: y = y.T
  145. def _timer(sess, ops_fn, iterations):
  146. # Warm in
  147. sess.run(ops_fn(10, sess))
  148. # Timing run
  149. start = time.time()
  150. sess.run(ops_fn(iterations, sess))
  151. end = time.time()
  152. return (end - start)/(1.0 * iterations) # Average runtime per iteration
  153. # Using regular matmul, marking one of the matrices as dense.
  154. if skip_dense:
  155. delta_dense = float("nan")
  156. else:
  157. with tf.Session("", config=config, graph=tf.Graph()) as sess:
  158. if not use_gpu:
  159. with tf.device("/cpu:0"):
  160. x_t = tf.constant(x)
  161. y_t = tf.constant(y)
  162. ops_fn = _sparse_tensor_dense_vs_dense_matmul_benchmark_dense(
  163. x_t, y_t, adjoint_a, adjoint_b)
  164. else:
  165. x_t = tf.constant(x)
  166. y_t = tf.constant(y)
  167. ops_fn = _sparse_tensor_dense_vs_dense_matmul_benchmark_dense(
  168. x_t, y_t, adjoint_a, adjoint_b)
  169. delta_dense = _timer(sess, ops_fn, 1000)
  170. # Using sparse_tensor_dense_matmul.
  171. with tf.Session("", config=config, graph=tf.Graph()) as sess:
  172. if not use_gpu:
  173. with tf.device("/cpu:0"):
  174. x_ind = tf.constant(np.vstack(np.where(x)).astype(np.int64).T)
  175. x_val = tf.constant(x[np.where(x)])
  176. x_shape = tf.constant(np.array(x.shape).astype(np.int64))
  177. y_t = tf.constant(y)
  178. ops_fn = _sparse_tensor_dense_vs_dense_matmul_benchmark_sparse(
  179. x_ind, x_val, x_shape, y_t, adjoint_a, adjoint_b)
  180. else:
  181. x_ind = tf.constant(np.vstack(np.where(x)).astype(np.int64).T)
  182. x_val = tf.constant(x[np.where(x)])
  183. x_shape = tf.constant(np.array(x.shape).astype(np.int64))
  184. y_t = tf.constant(y)
  185. ops_fn = _sparse_tensor_dense_vs_dense_matmul_benchmark_sparse(
  186. x_ind, x_val, x_shape, y_t, adjoint_a, adjoint_b)
  187. delta_sparse = _timer(sess, ops_fn, 1000)
  188. print(
  189. "%g \t %d \t %s \t %d \t %d \t %g \t %g \t %g"
  190. % (1 - thresh, n, use_gpu, m, k, delta_dense, delta_sparse,
  191. delta_sparse/delta_dense))
  192. def main(_):
  193. print("DenseDense MatMul (w/ Sparse Flag) vs. SparseTensorDense MatMul")
  194. print("Matrix sizes:")
  195. print(" A sparse [m, k] with % nonzero values between 1% and 80%")
  196. print(" B dense [k, n]")
  197. print("")
  198. print("% nnz \t n \t gpu \t m \t k \t dt(dense) \t dt(sparse) "
  199. "\t dt(sparse)/dt(dense)")
  200. for thresh in (0.99, 0.8, 0.5, 0.2):
  201. for n in (1, 10, 25):
  202. for use_gpu in (True, False):
  203. for m in (100, 1000):
  204. for k in (100, 1000):
  205. sparse_tensor_dense_vs_dense_matmul_benchmark(
  206. thresh, m, k, n, False, False, use_gpu=use_gpu)
  207. # Enable for large scale benchmarks, these ones take a long time to run.
  208. #
  209. # for use_gpu in (True, False):
  210. # sparse_tensor_dense_vs_dense_matmul_benchmark(
  211. # thresh=0.99, m=1000000, k=1000, n=100, adjoint_a=False,
  212. # adjoint_b=False, use_gpu=use_gpu, skip_dense=True)
  213. if __name__ == "__main__":
  214. if "--benchmarks" in sys.argv:
  215. sys.argv.remove("--benchmarks")
  216. tf.app.run()
  217. else:
  218. tf.test.main()