diff --git a/GPy/kern/src/coregionalize.py b/GPy/kern/src/coregionalize.py index 197d7ece..0c471cb3 100644 --- a/GPy/kern/src/coregionalize.py +++ b/GPy/kern/src/coregionalize.py @@ -6,11 +6,14 @@ import numpy as np from ...core.parameterization import Param from paramz.transformations import Logexp from ...util.config import config # for assesing whether to use cython + try: from . import coregionalize_cython - config.set('cython', 'working', 'True') + use_coregionalize_cython = config.getboolean('cython', 'working') except ImportError: - config.set('cython', 'working', 'False') + print('warning in coregionalize: failed to import cython module: falling back to numpy') + use_coregionalize_cython = False + class Coregionalize(Kern): """ @@ -61,7 +64,7 @@ class Coregionalize(Kern): self.B = np.dot(self.W, self.W.T) + np.diag(self.kappa) def K(self, X, X2=None): - if config.getboolean('cython', 'working'): + if use_coregionalize_cython: return self._K_cython(X, X2) else: return self._K_numpy(X, X2) @@ -92,7 +95,7 @@ class Coregionalize(Kern): index2 = np.asarray(X2, dtype=np.int) #attempt to use cython for a nasty double indexing loop: fall back to numpy - if config.getboolean('cython', 'working'): + if use_coregionalize_cython: dL_dK_small = self._gradient_reduce_cython(dL_dK, index, index2) else: dL_dK_small = self._gradient_reduce_numpy(dL_dK, index, index2) diff --git a/GPy/kern/src/stationary.py b/GPy/kern/src/stationary.py index cf3f5dff..9fa3273d 100644 --- a/GPy/kern/src/stationary.py +++ b/GPy/kern/src/stationary.py @@ -14,9 +14,10 @@ from paramz.transformations import Logexp try: from . import stationary_cython + use_stationary_cython = config.getboolean('cython', 'working') except ImportError: print('warning in stationary: failed to import cython module: falling back to numpy') - config.set('cython', 'working', 'false') + use_stationary_cython = False class Stationary(Kern): @@ -203,7 +204,7 @@ class Stationary(Kern): tmp = dL_dr*self._inv_dist(X, X2) if X2 is None: X2 = X - if config.getboolean('cython', 'working'): + if use_stationary_cython: self.lengthscale.gradient = self._lengthscale_grads_cython(tmp, X, X2) else: self.lengthscale.gradient = self._lengthscale_grads_pure(tmp, X, X2) @@ -246,7 +247,7 @@ class Stationary(Kern): """ Given the derivative of the objective wrt K (dL_dK), compute the derivative wrt X """ - if config.getboolean('cython', 'working'): + if use_stationary_cython: return self._gradients_X_cython(dL_dK, X, X2) else: return self._gradients_X_pure(dL_dK, X, X2) diff --git a/GPy/testing/cython_tests.py b/GPy/testing/cython_tests.py index c4bca5cd..dc41c44a 100644 --- a/GPy/testing/cython_tests.py +++ b/GPy/testing/cython_tests.py @@ -2,21 +2,27 @@ import numpy as np import scipy as sp from GPy.util import choleskies import GPy -from ..util.config import config import unittest +from ..util.config import config + try: - from ..util import linalg_cython from ..util import choleskies_cython - config.set('cython', 'working', 'True') + choleskies_cython_working = config.getboolean('cython', 'working') except ImportError: - config.set('cython', 'working', 'False') + choleskies_cython_working = False + +try: + from ..kern.src import stationary_cython + stationary_cython_working = config.getboolean('cython', 'working') +except ImportError: + stationary_cython_working = False """ These tests make sure that the pure python and cython codes work the same """ -@unittest.skipIf(not config.getboolean('cython', 'working'),"Cython modules have not been built on this machine") +@unittest.skipIf(not choleskies_cython_working,"Cython cholesky module has not been built on this machine") class CythonTestChols(np.testing.TestCase): def setUp(self): self.flat = np.random.randn(45,5) @@ -30,7 +36,7 @@ class CythonTestChols(np.testing.TestCase): A2 = choleskies._triang_to_flat_cython(self.triang) np.testing.assert_allclose(A1, A2) -@unittest.skipIf(not config.getboolean('cython', 'working'),"Cython modules have not been built on this machine") +@unittest.skipIf(not stationary_cython_working,"Cython stationary module has not been built on this machine") class test_stationary(np.testing.TestCase): def setUp(self): self.k = GPy.kern.RBF(10) @@ -60,7 +66,7 @@ class test_stationary(np.testing.TestCase): g2 = self.k._lengthscale_grads_cython(self.dKxz, self.X, self.Z) np.testing.assert_allclose(g1, g2) -@unittest.skipIf(not config.getboolean('cython', 'working'),"Cython modules have not been built on this machine") +@unittest.skipIf(not choleskies_cython_working,"Cython cholesky module has not been built on this machine") class test_choleskies_backprop(np.testing.TestCase): def setUp(self): a =np.random.randn(10,12) diff --git a/GPy/testing/kernel_tests.py b/GPy/testing/kernel_tests.py index 02186c62..1e11f6a6 100644 --- a/GPy/testing/kernel_tests.py +++ b/GPy/testing/kernel_tests.py @@ -14,10 +14,10 @@ from ..util.config import config verbose = 0 try: - from ..util import linalg_cython - config.set('cython', 'working', 'True') + from ..kern.src import coregionalize_cython + cython_coregionalize_working = config.getboolean('cython', 'working') except ImportError: - config.set('cython', 'working', 'False') + cython_coregionalize_working = False class Kern_check_model(GPy.core.Model): @@ -641,7 +641,7 @@ class KernelTestsNonContinuous(unittest.TestCase): kern = GPy.kern.Coregionalize(1, output_dim=3, active_dims=[-1]) self.assertTrue(check_kernel_gradient_functions(kern, X=self.X, X2=self.X2, verbose=verbose, fixed_X_dims=-1)) -@unittest.skipIf(not config.getboolean('cython', 'working'),"Cython modules have not been built on this machine") +@unittest.skipIf(not cython_coregionalize_working,"Cython coregionalize module has not been built on this machine") class Coregionalize_cython_test(unittest.TestCase): """ Make sure that the coregionalize kernel work with and without cython enabled @@ -654,42 +654,44 @@ class Coregionalize_cython_test(unittest.TestCase): def test_sym(self): dL_dK = np.random.randn(self.N1, self.N1) - GPy.util.config.config.set('cython', 'working', 'True') - K_cython = self.k.K(self.X) + K_cython = self.k._K_cython(self.X) self.k.update_gradients_full(dL_dK, self.X) grads_cython = self.k.gradient.copy() - GPy.util.config.config.set('cython', 'working', 'False') - K_numpy = self.k.K(self.X) + K_numpy = self.k._K_numpy(self.X) + # Nasty hack to ensure the numpy version is used for update_gradients + # If this test is running, cython is working, so override the cython + # function with the numpy function + _gradient_reduce_cython = self.k._gradient_reduce_cython + self.k._gradient_reduce_cython = self.k._gradient_reduce_numpy self.k.update_gradients_full(dL_dK, self.X) + # Undo hack + self.k._gradient_reduce_cython = _gradient_reduce_cython grads_numpy = self.k.gradient.copy() self.assertTrue(np.allclose(K_numpy, K_cython)) self.assertTrue(np.allclose(grads_numpy, grads_cython)) - #reset the cython state for any other tests - GPy.util.config.config.set('cython', 'working', 'true') - def test_nonsym(self): dL_dK = np.random.randn(self.N1, self.N2) - GPy.util.config.config.set('cython', 'working', 'True') - K_cython = self.k.K(self.X, self.X2) + K_cython = self.k._K_cython(self.X, self.X2) self.k.gradient = 0. self.k.update_gradients_full(dL_dK, self.X, self.X2) grads_cython = self.k.gradient.copy() - GPy.util.config.config.set('cython', 'working', 'False') - K_numpy = self.k.K(self.X, self.X2) + K_numpy = self.k._K_numpy(self.X, self.X2) self.k.gradient = 0. + # Same hack as in test_sym (Line 639) + _gradient_reduce_cython = self.k._gradient_reduce_cython + self.k._gradient_reduce_cython = self.k._gradient_reduce_numpy self.k.update_gradients_full(dL_dK, self.X, self.X2) + # Undo hack + self.k._gradient_reduce_cython = _gradient_reduce_cython grads_numpy = self.k.gradient.copy() self.assertTrue(np.allclose(K_numpy, K_cython)) self.assertTrue(np.allclose(grads_numpy, grads_cython)) - #reset the cython state for any other tests - GPy.util.config.config.set('cython', 'working', 'true') - class KernelTestsProductWithZeroValues(unittest.TestCase): diff --git a/GPy/util/choleskies.py b/GPy/util/choleskies.py index 2676b6e6..acc4ad7a 100644 --- a/GPy/util/choleskies.py +++ b/GPy/util/choleskies.py @@ -4,11 +4,14 @@ import numpy as np from . import linalg from .config import config + try: from . import choleskies_cython - config.set('cython', 'working', 'True') + use_choleskies_cython = config.getboolean('cython', 'working') except ImportError: - config.set('cython', 'working', 'False') + print('warning in choleskies: failed to import cython module: falling back to numpy') + use_choleskies_cython = False + def safe_root(N): i = np.sqrt(N) @@ -100,7 +103,7 @@ def indexes_to_fix_for_low_rank(rank, size): return np.setdiff1d(np.arange((size**2+size)/2), keep) -if config.getboolean('cython', 'working'): +if use_choleskies_cython: triang_to_flat = _triang_to_flat_cython flat_to_triang = _flat_to_triang_cython backprop_gradient = choleskies_cython.backprop_gradient_par_c diff --git a/GPy/util/linalg.py b/GPy/util/linalg.py index ab6f61ff..8fb9c1ce 100644 --- a/GPy/util/linalg.py +++ b/GPy/util/linalg.py @@ -11,8 +11,11 @@ from scipy.linalg import lapack, blas from .config import config import logging -if config.getboolean('cython', 'working'): +try: from . import linalg_cython + use_linalg_cython = config.getboolean('cython', 'working') +except ImportError: + use_linalg_cython = False def force_F_ordered_symmetric(A): """ @@ -359,7 +362,7 @@ def symmetrify(A, upper=False): note: tries to use cython, falls back to a slower numpy version """ - if config.getboolean('cython', 'working'): + if use_linalg_cython: _symmetrify_cython(A, upper) else: _symmetrify_numpy(A, upper)