PageRenderTime 53ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/theano/sandbox/gpuarray/tests/test_basic_ops.py

https://github.com/goodfeli/Theano
Python | 327 lines | 262 code | 59 blank | 6 comment | 50 complexity | adf953e9ad42e1cd486572b6b07784d3 MD5 | raw file
  1. import unittest
  2. from itertools import izip
  3. from copy import copy, deepcopy
  4. import numpy
  5. import theano
  6. import theano.tensor as T
  7. from theano.compile import DeepCopyOp
  8. from theano.tensor.tests.test_basic import safe_make_node
  9. from theano.tests.unittest_tools import SkipTest
  10. from numpy.testing.noseclasses import KnownFailureTest
  11. import theano.sandbox.gpuarray
  12. import theano.sandbox.cuda as cuda_ndarray
  13. if cuda_ndarray.cuda_available and not theano.sandbox.gpuarray.pygpu_activated:
  14. if not cuda_ndarray.use.device_number:
  15. #We should not enable all the use like the flag device=gpu,
  16. #as many tests don't work in that setup.
  17. cuda_ndarray.use('gpu',
  18. default_to_move_computation_to_gpu=False,
  19. move_shared_float32_to_gpu=False,
  20. enable_cuda=False)
  21. theano.sandbox.gpuarray.init_dev('cuda')
  22. if not theano.sandbox.gpuarray.pygpu_activated:
  23. raise SkipTest("pygpu disabled")
  24. from theano.sandbox.gpuarray.type import (GpuArrayType,
  25. gpuarray_shared_constructor)
  26. from theano.sandbox.gpuarray.basic_ops import (host_from_gpu, gpu_from_host,
  27. gpu_alloc, gpu_from_cuda,
  28. cuda_from_gpu)
  29. from theano.tests import unittest_tools as utt
  30. utt.seed_rng()
  31. rng = numpy.random.RandomState(seed=utt.fetch_seed())
  32. from pygpu import gpuarray
  33. if theano.config.mode == 'FAST_COMPILE':
  34. mode_with_gpu = theano.compile.mode.get_mode('FAST_RUN').including('gpuarray')
  35. mode_without_gpu = theano.compile.mode.get_mode('FAST_RUN').excluding('gpuarray'\
  36. )
  37. else:
  38. mode_with_gpu = theano.compile.mode.get_default_mode().including('gpuarray')
  39. mode_without_gpu = theano.compile.mode.get_default_mode().excluding('gpuarray')
  40. def may_fail(msg, EClass):
  41. """Mark a test that requires very specific conditions to work to
  42. mask a specific exception class."""
  43. def test_decorator(f):
  44. def wrapper():
  45. try:
  46. f()
  47. except Exception, e:
  48. if isinstance(e, EClass):
  49. raise KnownFailureTest(msg, e)
  50. raise
  51. wrapper.__name__ = f.__name__
  52. return wrapper
  53. return test_decorator
  54. def inplace_func(inputs, outputs, mode=None, allow_input_downcast=False,
  55. on_unused_input='raise', name=None):
  56. if mode is None:
  57. mode = mode_with_gpu
  58. return theano.function(inputs, outputs, mode=mode,
  59. allow_input_downcast=allow_input_downcast,
  60. accept_inplace=True,
  61. on_unused_input=on_unused_input, name=name)
  62. def fake_shared(value, name=None, strict=False, allow_downcast=None, **kwargs):
  63. from theano.tensor.sharedvar import tensor_constructor, scalar_constructor
  64. for c in (gpuarray_shared_constructor, tensor_constructor,
  65. scalar_constructor):
  66. try:
  67. return c(value, name=name, strict=strict,
  68. allow_downcast=allow_downcast, **kwargs)
  69. except TypeError:
  70. continue
  71. def rand_gpuarray(*shape, **kwargs):
  72. r = rng.rand(*shape) * 2 - 1
  73. dtype = kwargs.pop('dtype', theano.config.floatX)
  74. if len(kwargs) != 0:
  75. raise TypeError('Unexpected argument %s', kwargs.keys()[0])
  76. return gpuarray.array(r, dtype=dtype)
  77. def makeTester(name, op, expected, good=None, bad_build=None, checks=None,
  78. bad_runtime=None, mode=None, skip=False, eps=1e-10):
  79. if good is None:
  80. good = {}
  81. if bad_build is None:
  82. bad_build = {}
  83. if bad_runtime is None:
  84. bad_runtime = {}
  85. if checks is None:
  86. checks = {}
  87. _op = op
  88. _expected = expected
  89. _good = good
  90. _bad_build = bad_build
  91. _bad_runtime = bad_runtime
  92. _skip = skip
  93. _checks = checks
  94. class Checker(unittest.TestCase):
  95. op = staticmethod(_op)
  96. expected = staticmethod(_expected)
  97. good = _good
  98. bad_build = _bad_build
  99. bad_runtime = _bad_runtime
  100. skip = _skip
  101. checks = _checks
  102. def setUp(self):
  103. eval(self.__class__.__module__ + '.' + self.__class__.__name__)
  104. def test_good(self):
  105. if skip:
  106. raise SkipTest(skip)
  107. for testname, inputs in good.items():
  108. inputs = [copy(input) for input in inputs]
  109. inputrs = [fake_shared(input) for input in inputs]
  110. try:
  111. node = safe_make_node(self.op, *inputrs)
  112. except Exception, exc:
  113. err_msg = ("Test %s::%s: Error occured while making "
  114. "a node with inputs %s") % (self.op, testname,
  115. inputs)
  116. exc.args += (err_msg,)
  117. raise
  118. try:
  119. f = inplace_func([], node.outputs, mode=mode,
  120. name='test_good')
  121. except Exception, exc:
  122. err_msg = ("Test %s::%s: Error occured while trying to "
  123. "make a Function") % (self.op, testname)
  124. exc.args += (err_msg,)
  125. raise
  126. if isinstance(self.expected, dict) and \
  127. testname in self.expected:
  128. expecteds = self.expected[testname]
  129. else:
  130. expecteds = self.expected(*inputs)
  131. if not isinstance(expecteds, (list, tuple)):
  132. expecteds = (expecteds,)
  133. try:
  134. variables = f()
  135. except Exception, exc:
  136. err_msg = ("Test %s::%s: Error occured while calling "
  137. "the Function on the inputs %s") % (self.op,
  138. testname,
  139. inputs)
  140. exc.args += (err_msg,)
  141. raise
  142. for i, (variable, expected) in \
  143. enumerate(izip(variables, expecteds)):
  144. if variable.dtype != expected.dtype or \
  145. variable.shape != expected.shape or \
  146. not GpuArrayType.values_eq_approx(variable,
  147. expected):
  148. self.fail(("Test %s::%s: Output %s gave the wrong "
  149. "value. With inputs %s, expected %s "
  150. "(dtype %s), got %s (dtype %s).") % (
  151. self.op, testname, i, inputs, expected,
  152. expected.dtype, variable, variable.dtype))
  153. for description, check in self.checks.items():
  154. if not check(inputs, variables):
  155. self.fail(("Test %s::%s: Failed check: %s "
  156. "(inputs were %s, ouputs were %s)") %
  157. (self.op, testname, description,
  158. inputs, variables))
  159. def test_bad_build(self):
  160. if skip:
  161. raise SkipTest(skip)
  162. for testname, inputs in self.bad_build.items():
  163. inputs = [copy(input) for input in inputs]
  164. inputrs = [fake_shared(input) for input in inputs]
  165. self.assertRaises(Exception, safe_make_node, self.op, *inputrs)
  166. def test_bad_runtime(self):
  167. if skip:
  168. raise SkipTest(skip)
  169. for testname, inputs in self.bad_runtime.items():
  170. inputrs = [fake_shared(input) for input in inputs]
  171. try:
  172. node = safe_make_node(self.op, *inputrs)
  173. except Exception, exc:
  174. err_msg = ("Test %s::%s: Error occured while trying to "
  175. "make a node with inputs %s") % (self.op,
  176. testname,
  177. inputs)
  178. exc.args += (err_msg,)
  179. raise
  180. try:
  181. f = inplace_func([], node.outputs, mode=mode,
  182. name="test_bad_runtime")
  183. except Exception, exc:
  184. err_msg = ("Test %s::%s: Error occured while trying to "
  185. "make a Function") % (self.op, testname)
  186. exc.args += (err_msg,)
  187. raise
  188. self.assertRaises(Exception, f, [])
  189. Checker.__name__ = name
  190. return Checker
  191. def test_transfer_cpu_gpu():
  192. a = T.fmatrix('a')
  193. g = GpuArrayType(dtype='float32', broadcastable=(False, False))('g')
  194. av = numpy.asarray(rng.rand(5, 4), dtype='float32')
  195. gv = gpuarray.array(av)
  196. f = theano.function([a], gpu_from_host(a))
  197. fv = f(av)
  198. assert GpuArrayType.values_eq(fv, gv)
  199. f = theano.function([g], host_from_gpu(g))
  200. fv = f(gv)
  201. assert numpy.all(fv == av)
  202. def test_transfer_strided():
  203. # This is just to ensure that it works in theano
  204. # compyte has a much more comprehensive suit of tests to ensure correctness
  205. a = T.fmatrix('a')
  206. g = GpuArrayType(dtype='float32', broadcastable=(False, False))('g')
  207. av = numpy.asarray(rng.rand(5, 8), dtype='float32')
  208. gv = gpuarray.array(av)
  209. av = av[:,::2]
  210. gv = gv[:,::2]
  211. f = theano.function([a], gpu_from_host(a))
  212. fv = f(av)
  213. assert GpuArrayType.values_eq(fv, gv)
  214. f = theano.function([g], host_from_gpu(g))
  215. fv = f(gv)
  216. assert numpy.all(fv == av)
  217. @may_fail("Op fails if both contexts are not the same and it's rare "
  218. "that the tests will be run this way", ValueError)
  219. def test_transfer_cuda_gpu():
  220. import theano.sandbox.cuda as cuda_ndarray
  221. if cuda_ndarray.cuda_available == False:
  222. raise SkipTest("Can't test interaction with cuda if cuda not present")
  223. g = GpuArrayType(dtype='float32', broadcastable=(False, False))('g')
  224. c = cuda_ndarray.CudaNdarrayType((False, False))('c')
  225. av = theano._asarray(rng.rand(5, 4), dtype='float32')
  226. gv = gpuarray.array(av)
  227. cv = cuda_ndarray.CudaNdarray(av)
  228. gvs = gv[:,::-2]
  229. cvs = cv[:,::-2]
  230. f = theano.function([c], gpu_from_cuda(c))
  231. fv = f(cv)
  232. assert GpuArrayType.values_eq_approx(fv, gv)
  233. fvs = f(cvs)
  234. assert GpuArrayType.values_eq_approx(fvs, gvs)
  235. f = theano.function([g], cuda_from_gpu(g))
  236. fv = f(gv)
  237. assert cuda_ndarray.CudaNdarrayType.values_eq_approx(fv, cv)
  238. fvs = f(gvs)
  239. assert cuda_ndarray.CudaNdarrayType.values_eq_approx(fvs, cvs)
  240. def gpu_alloc_expected(x, *shp):
  241. g = gpuarray.empty(shp, dtype=x.dtype)
  242. g[:] = x
  243. return g
  244. GpuAllocTester = makeTester(
  245. name="GpuAllocTester",
  246. op=gpu_alloc,
  247. expected=gpu_alloc_expected,
  248. good=dict(
  249. correct01=(rand_gpuarray(), numpy.int32(7)),
  250. correct01_bcast=(rand_gpuarray(1), numpy.int32(7)),
  251. correct02=(rand_gpuarray(), numpy.int32(4), numpy.int32(7)),
  252. correct12=(rand_gpuarray(7), numpy.int32(4), numpy.int32(7)),
  253. correct13=(rand_gpuarray(7), numpy.int32(2), numpy.int32(4),
  254. numpy.int32(7)),
  255. correct23=(rand_gpuarray(4, 7), numpy.int32(2), numpy.int32(4),
  256. numpy.int32(7))
  257. ),
  258. bad_runtime=dict(
  259. bad_shape12=(rand_gpuarray(7), numpy.int32(7), numpy.int32(5)),
  260. )
  261. )
  262. def test_deep_copy():
  263. a = rand_gpuarray(20, dtype='float32')
  264. g = GpuArrayType(dtype='float32', broadcastable=(False,))('g')
  265. f = theano.function([g], g)
  266. assert isinstance(f.maker.fgraph.toposort()[0].op, DeepCopyOp)
  267. res = f(a)
  268. assert GpuArrayType.values_eq(res, a)