From a7af12e6ea9bbe3c240bb512c96494573c785904 Mon Sep 17 00:00:00 2001 From: Jayanth Koushik Date: Mon, 23 Oct 2017 15:58:17 -0400 Subject: [PATCH] fix: dev: cython import errors This commit fixes issues observed in Windows where some cython modules are successfully imported, and some are not. This causes the global config cython.working to be inconsistent, which causes import errors when unavailable cython modules are tried to be imported (example https://github.com/SheffieldML/GPy/issues/266). This commit uses a separate flag for each module to fix the issue. --- GPy/kern/src/coregionalize.py | 11 +++++++---- GPy/kern/src/stationary.py | 7 ++++--- GPy/testing/cython_tests.py | 18 +++++++++++------- GPy/testing/kernel_tests.py | 8 ++++---- GPy/util/choleskies.py | 9 ++++++--- 5 files changed, 32 insertions(+), 21 deletions(-) diff --git a/GPy/kern/src/coregionalize.py b/GPy/kern/src/coregionalize.py index 197d7ece..704d0370 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') + cython_coregionalize_working = True except ImportError: - config.set('cython', 'working', 'False') + print('warning in coregionalize: failed to import cython module: falling back to numpy') + cython_coregionalize_working = 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 cython_coregionalize_working and config.getboolean('cython', 'working'): 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 cython_coregionalize_working and config.getboolean('cython', 'working'): 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 4e8ddb77..81681d60 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 + cython_stationary_working = True except ImportError: print('warning in stationary: failed to import cython module: falling back to numpy') - config.set('cython', 'working', 'false') + cython_stationary_working = False class Stationary(Kern): @@ -196,7 +197,7 @@ class Stationary(Kern): tmp = dL_dr*self._inv_dist(X, X2) if X2 is None: X2 = X - if config.getboolean('cython', 'working'): + if cython_stationary_working and config.getboolean('cython', 'working'): self.lengthscale.gradient = self._lengthscale_grads_cython(tmp, X, X2) else: self.lengthscale.gradient = self._lengthscale_grads_pure(tmp, X, X2) @@ -239,7 +240,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 cython_stationary_working and config.getboolean('cython', 'working'): 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..c777aae0 100644 --- a/GPy/testing/cython_tests.py +++ b/GPy/testing/cython_tests.py @@ -2,21 +2,25 @@ import numpy as np import scipy as sp from GPy.util import choleskies import GPy -from ..util.config import config import unittest try: - from ..util import linalg_cython from ..util import choleskies_cython - config.set('cython', 'working', 'True') + choleskies_cython_working = True except ImportError: - config.set('cython', 'working', 'False') + choleskies_cython_working = False + +try: + from ..kern.src import stationary_cython + stationary_cython_working = True +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 +34,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 +64,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 053fce35..e5bc5683 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 ..util import choleskies_cython + cython_choleskies_working = True except ImportError: - config.set('cython', 'working', 'False') + cython_choleskies_working = False class Kern_check_model(GPy.core.Model): @@ -618,7 +618,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_choleskies_working,"Cython choleskies 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 diff --git a/GPy/util/choleskies.py b/GPy/util/choleskies.py index 2676b6e6..54a7ea74 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') + cython_choleskies_working = True except ImportError: - config.set('cython', 'working', 'False') + print('warning in choleskies: failed to import cython module: falling back to numpy') + cython_choleskies_working = 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 cython_choleskies_working and config.getboolean('cython', 'working'): triang_to_flat = _triang_to_flat_cython flat_to_triang = _flat_to_triang_cython backprop_gradient = choleskies_cython.backprop_gradient_par_c