提交 9036e6dd authored 作者: Thomas George's avatar Thomas George

more test cases + some small changes

上级 a8996904
......@@ -284,8 +284,6 @@ class GpuCholesky(Op):
# Input matrix.
A = inputs[0]
assert(len(A.shape) == 2)
l, n = A.shape
if l != n:
raise ValueError('A must be a square matrix')
......@@ -333,7 +331,6 @@ class GpuCholesky(Op):
# cusolver leaves the elements in the matrix outside the considered
# upper or lower triangle unchanged, so we need to put zeros outside
# the triangle
# Note : we should probably check for c or f order in triu instead of here
if self.lower:
tril(L)
else:
......
......@@ -120,14 +120,14 @@ class TestGpuCholesky(unittest.TestCase):
utt.seed_rng()
def get_gpu_cholesky_func(self, lower=True, inplace=False):
""" Helper function to compile function from GPU Cholesky op. """
# Helper function to compile function from GPU Cholesky op.
A = theano.tensor.matrix("A", dtype="float32")
cholesky_op = GpuCholesky(lower=lower, inplace=inplace)
chol_A = cholesky_op(A)
return theano.function([A], chol_A, accept_inplace=inplace, mode=mode_with_gpu)
def compare_gpu_cholesky_to_numpy(self, A_val, lower=True, inplace=False):
""" Helper function to compare op output to numpy.cholesky output. """
# Helper function to compare op output to numpy.cholesky output.
chol_A_val = numpy.linalg.cholesky(A_val)
if not lower:
chol_A_val = chol_A_val.T
......@@ -137,77 +137,55 @@ class TestGpuCholesky(unittest.TestCase):
utt.assert_allclose(chol_A_res, chol_A_val)
def test_invalid_input_fail_non_square(self):
""" Invalid Cholesky input test with non-square matrix as input. """
# Invalid Cholesky input test with non-square matrix as input.
A_val = numpy.random.normal(size=(3, 2)).astype("float32")
fn = self.get_gpu_cholesky_func(True, False)
self.assertRaises(ValueError, fn, A_val)
def test_invalid_input_fail_vector(self):
""" Invalid Cholesky input test with vector as input. """
# Invalid Cholesky input test with vector as input.
def invalid_input_func():
A = theano.tensor.vector("A", dtype="float32")
GpuCholesky(lower=True, inplace=False)(A)
self.assertRaises(AssertionError, invalid_input_func)
def test_invalid_input_fail_tensor3(self):
""" Invalid Cholesky input test with 3D tensor as input. """
# Invalid Cholesky input test with 3D tensor as input.
def invalid_input_func():
A = theano.tensor.tensor3("A", dtype="float32")
GpuCholesky(lower=True, inplace=False)(A)
self.assertRaises(AssertionError, invalid_input_func)
def test_diag_chol(self):
""" Diagonal matrix input Cholesky test. """
# Diagonal matrix input Cholesky test.
# make sure all diagonal elements are positive so positive-definite
A_val = numpy.diag(numpy.random.uniform(size=5).astype("float32") + 1)
self.compare_gpu_cholesky_to_numpy(A_val, lower=True, inplace=False)
for lower in [True, False]:
for inplace in [True, False]:
A_val = numpy.diag(numpy.random.uniform(size=5).astype("float32") + 1)
self.compare_gpu_cholesky_to_numpy(A_val, lower=lower, inplace=inplace)
def test_dense_chol_lower(self):
""" Dense matrix input lower-triangular Cholesky test. """
M_val = numpy.random.normal(size=(3, 3)).astype("float32")
# A = M.dot(M) will be positive definite for all non-singular M
A_val = M_val.dot(M_val.T)
self.compare_gpu_cholesky_to_numpy(A_val, lower=True, inplace=False)
def test_dense_chol_upper(self):
""" Dense matrix input upper-triangular Cholesky test. """
M_val = numpy.random.normal(size=(3, 3)).astype("float32")
# A = M.dot(M) will be positive definite for all non-singular M
A_val = M_val.dot(M_val.T)
self.compare_gpu_cholesky_to_numpy(A_val, lower=False, inplace=False)
def test_diag_chol_inplace(self):
""" Diagonal matrix input inplace Cholesky test. """
# make sure all diagonal elements are positive so positive-definite
A_val = numpy.diag(numpy.random.uniform(size=5).astype("float32") + 1)
self.compare_gpu_cholesky_to_numpy(A_val, lower=True, inplace=True)
def test_dense_chol_lower_inplace(self):
""" Dense matrix input lower-triangular inplace Cholesky test. """
M_val = numpy.random.normal(size=(3, 3)).astype("float32")
# A = M.dot(M) will be positive definite for all non-singular M
A_val = M_val.dot(M_val.T)
self.compare_gpu_cholesky_to_numpy(A_val, lower=True, inplace=True)
def test_dense_chol_upper_inplace(self):
""" Dense matrix input upper-triangular inplace Cholesky test. """
M_val = numpy.random.normal(size=(3, 3)).astype("float32")
# A = M.dot(M) will be positive definite for all non-singular M
A_val = M_val.dot(M_val.T)
self.compare_gpu_cholesky_to_numpy(A_val, lower=False, inplace=True)
# Dense matrix input lower-triangular Cholesky test.
for lower in [True, False]:
for inplace in [True, False]:
M_val = numpy.random.normal(size=(3, 3)).astype("float32")
# A = M.dot(M) will be positive definite for all non-singular M
A_val = M_val.dot(M_val.T)
self.compare_gpu_cholesky_to_numpy(A_val, lower=lower, inplace=inplace)
def test_invalid_input_fail_non_symmetric(self):
""" Invalid Cholesky input test with non-symmetric input.
(Non-symmetric real input must also be non-positive definite). """
A_val = numpy.random.normal(size=(3, 3)).astype("float32")
# double-check random A_val is asymmetric - the probability of this
# not being the case even with finite precision should be negligible
assert not numpy.allclose(A_val, A_val.T)
# Invalid Cholesky input test with non-symmetric input.
# (Non-symmetric real input must also be non-positive definite).
A_val = None
while True:
A_val = numpy.random.normal(size=(3, 3)).astype("float32")
if not numpy.allclose(A_val, A_val.T):
break
fn = self.get_gpu_cholesky_func(True, False)
self.assertRaises(LinAlgError, fn, A_val)
def test_invalid_input_fail_negative_definite(self):
""" Invalid Cholesky input test with negative-definite input. """
# Invalid Cholesky input test with negative-definite input.
M_val = numpy.random.normal(size=(3, 3)).astype("float32")
# A = -M.dot(M) will be negative definite for all non-singular M
A_val = -M_val.dot(M_val.T)
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论