From b837525baa9fb9b3d337fb603ed57da539b019d8 Mon Sep 17 00:00:00 2001 From: Mike Croucher Date: Mon, 7 Sep 2015 16:22:42 +0100 Subject: [PATCH 1/5] Fixed typos --- GPy/testing/cython_tests.py | 2 +- GPy/testing/kernel_tests.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/GPy/testing/cython_tests.py b/GPy/testing/cython_tests.py index 30e27fbb..8cdb08be 100644 --- a/GPy/testing/cython_tests.py +++ b/GPy/testing/cython_tests.py @@ -6,7 +6,7 @@ from ..util.config import config import unittest try: - from . import linalg_cython + from ..util import linalg_cython config.set('cython', 'working', 'True') except ImportError: config.set('cython', 'working', 'False') diff --git a/GPy/testing/kernel_tests.py b/GPy/testing/kernel_tests.py index ec005b6c..50a5aed8 100644 --- a/GPy/testing/kernel_tests.py +++ b/GPy/testing/kernel_tests.py @@ -11,7 +11,7 @@ from ..util.config import config verbose = 0 try: - from . import linalg_cython + from ..util import linalg_cython config.set('cython', 'working', 'True') except ImportError: config.set('cython', 'working', 'False') From fb444d893354a5c82c0ab3030204c14c8759e6ff Mon Sep 17 00:00:00 2001 From: Mike Croucher Date: Mon, 7 Sep 2015 16:23:10 +0100 Subject: [PATCH 2/5] Used scipy.log1p since it gives more consistent results cross-platform --- GPy/likelihoods/link_functions.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/GPy/likelihoods/link_functions.py b/GPy/likelihoods/link_functions.py index 3d753395..30ad32ad 100644 --- a/GPy/likelihoods/link_functions.py +++ b/GPy/likelihoods/link_functions.py @@ -2,6 +2,7 @@ # Licensed under the BSD 3-clause license (see LICENSE.txt) import numpy as np +import scipy from ..util.univariate_Gaussian import std_norm_cdf, std_norm_pdf import scipy as sp from ..util.misc import safe_exp, safe_square, safe_cube, safe_quad, safe_three_times @@ -67,7 +68,7 @@ class Probit(GPTransformation): .. math:: g(f) = \\Phi^{-1} (mu) - + """ def transf(self,f): return std_norm_cdf(f) @@ -140,7 +141,7 @@ class Log_ex_1(GPTransformation): """ def transf(self,f): - return np.log1p(safe_exp(f)) + return scipy.log1p(safe_exp(f)) def dtransf_df(self,f): ef = safe_exp(f) From 607c21428454f0af11839cb8d72b76cba569a5d6 Mon Sep 17 00:00:00 2001 From: Zhenwen Dai Date: Mon, 7 Sep 2015 16:27:31 +0100 Subject: [PATCH 3/5] changed gpu interface for mpi --- GPy/kern/_src/psi_comp/rbf_psi_comp.py | 32 --------------- GPy/kern/_src/psi_comp/rbf_psi_gpucomp.py | 25 ++++++------ GPy/kern/_src/psi_comp/sslinear_psi_comp.py | 2 +- GPy/kern/_src/psi_comp/ssrbf_psi_gpucomp.py | 24 +++++------ GPy/util/__init__.py | 1 - GPy/util/gpu_init.py | 44 +++++++++------------ GPy/util/linalg_gpu.py | 7 ---- 7 files changed, 46 insertions(+), 89 deletions(-) diff --git a/GPy/kern/_src/psi_comp/rbf_psi_comp.py b/GPy/kern/_src/psi_comp/rbf_psi_comp.py index 892eb1a0..735a354d 100644 --- a/GPy/kern/_src/psi_comp/rbf_psi_comp.py +++ b/GPy/kern/_src/psi_comp/rbf_psi_comp.py @@ -6,12 +6,6 @@ import numpy as np from GPy.util.caching import Cacher def psicomputations(variance, lengthscale, Z, variational_posterior, return_psi2_n=False): - """ - Z - MxQ - mu - NxQ - S - NxQ - gamma - NxQ - """ # here are the "statistics" for psi0, psi1 and psi2 # Produced intermediate results: # _psi1 NxM @@ -26,12 +20,6 @@ def psicomputations(variance, lengthscale, Z, variational_posterior, return_psi2 return psi0, psi1, psi2 def __psi1computations(variance, lengthscale, Z, mu, S): - """ - Z - MxQ - mu - NxQ - S - NxQ - gamma - NxQ - """ # here are the "statistics" for psi1 # Produced intermediate results: # _psi1 NxM @@ -46,12 +34,6 @@ def __psi1computations(variance, lengthscale, Z, mu, S): return _psi1 def __psi2computations(variance, lengthscale, Z, mu, S): - """ - Z - MxQ - mu - NxQ - S - NxQ - gamma - NxQ - """ # here are the "statistics" for psi2 # Produced intermediate results: # _psi2 MxM @@ -86,13 +68,6 @@ def psiDerivativecomputations(dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscal return dL_dvar, dL_dlengscale, dL_dZ, dL_dmu, dL_dS def _psi1compDer(dL_dpsi1, variance, lengthscale, Z, mu, S): - """ - dL_dpsi1 - NxM - Z - MxQ - mu - NxQ - S - NxQ - gamma - NxQ - """ # here are the "statistics" for psi1 # Produced intermediate results: dL_dparams w.r.t. psi1 # _dL_dvariance 1 @@ -118,13 +93,6 @@ def _psi1compDer(dL_dpsi1, variance, lengthscale, Z, mu, S): return _dL_dvar, _dL_dl, _dL_dZ, _dL_dmu, _dL_dS def _psi2compDer(dL_dpsi2, variance, lengthscale, Z, mu, S): - """ - Z - MxQ - mu - NxQ - S - NxQ - gamma - NxQ - dL_dpsi2 - MxM - """ # here are the "statistics" for psi2 # Produced the derivatives w.r.t. psi2: # _dL_dvariance 1 diff --git a/GPy/kern/_src/psi_comp/rbf_psi_gpucomp.py b/GPy/kern/_src/psi_comp/rbf_psi_gpucomp.py index 03c4c8af..b3de8363 100644 --- a/GPy/kern/_src/psi_comp/rbf_psi_gpucomp.py +++ b/GPy/kern/_src/psi_comp/rbf_psi_gpucomp.py @@ -7,13 +7,6 @@ from ....util.caching import Cache_this from . import PSICOMP_RBF from ....util import gpu_init -try: - import pycuda.gpuarray as gpuarray - from pycuda.compiler import SourceModule - from ....util.linalg_gpu import sum_axis -except: - pass - gpu_code = """ // define THREADNUM @@ -242,6 +235,10 @@ gpu_code = """ class PSICOMP_RBF_GPU(PSICOMP_RBF): def __init__(self, threadnum=256, blocknum=30, GPU_direct=False): + from pycuda.compiler import SourceModule + from ....util.gpu_init import initGPU + initGPU() + self.GPU_direct = GPU_direct self.gpuCache = None @@ -264,7 +261,8 @@ class PSICOMP_RBF_GPU(PSICOMP_RBF): memo[id(self)] = s return s - def _initGPUCache(self, N, M, Q): + def _initGPUCache(self, N, M, Q): + import pycuda.gpuarray as gpuarray if self.gpuCache == None: self.gpuCache = { 'l_gpu' :gpuarray.empty((Q,),np.float64,order='F'), @@ -320,13 +318,14 @@ class PSICOMP_RBF_GPU(PSICOMP_RBF): def get_dimensions(self, Z, variational_posterior): return variational_posterior.mean.shape[0], Z.shape[0], Z.shape[1] - @Cache_this(limit=1, ignore_args=(0,)) - def psicomputations(self, variance, lengthscale, Z, variational_posterior): + @Cache_this(limit=5, ignore_args=(0,)) + def psicomputations(self, kern, Z, variational_posterior, return_psi2_n=False): """ Z - MxQ mu - NxQ S - NxQ """ + variance, lengthscale = kern.variance, kern.lengthscale N,M,Q = self.get_dimensions(Z, variational_posterior) self._initGPUCache(N,M,Q) self.sync_params(lengthscale, Z, variational_posterior.mean, variational_posterior.variance) @@ -355,8 +354,10 @@ class PSICOMP_RBF_GPU(PSICOMP_RBF): else: return psi0, psi1_gpu.get(), psi2_gpu.get() - @Cache_this(limit=1, ignore_args=(0,1,2,3)) - def psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior): + @Cache_this(limit=5, ignore_args=(0,2,3,4)) + def psiDerivativecomputations(self, kern, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + variance, lengthscale = kern.variance, kern.lengthscale + from ....util.linalg_gpu import sum_axis ARD = (len(lengthscale)!=1) N,M,Q = self.get_dimensions(Z, variational_posterior) diff --git a/GPy/kern/_src/psi_comp/sslinear_psi_comp.py b/GPy/kern/_src/psi_comp/sslinear_psi_comp.py index d431cd61..7e9b4fdc 100644 --- a/GPy/kern/_src/psi_comp/sslinear_psi_comp.py +++ b/GPy/kern/_src/psi_comp/sslinear_psi_comp.py @@ -9,7 +9,7 @@ from ....util.linalg import tdot import numpy as np -def psicomputations(variance, Z, variational_posterior): +def psicomputations(variance, Z, variational_posterior, return_psi2_n=False): """ Compute psi-statistics for ss-linear kernel """ diff --git a/GPy/kern/_src/psi_comp/ssrbf_psi_gpucomp.py b/GPy/kern/_src/psi_comp/ssrbf_psi_gpucomp.py index 1a9d2058..46f4a06e 100644 --- a/GPy/kern/_src/psi_comp/ssrbf_psi_gpucomp.py +++ b/GPy/kern/_src/psi_comp/ssrbf_psi_gpucomp.py @@ -6,14 +6,7 @@ The module for psi-statistics for RBF kernel for Spike-and-Slab GPLVM import numpy as np from ....util.caching import Cache_this from . import PSICOMP_RBF -from ....util import gpu_init -try: - import pycuda.gpuarray as gpuarray - from pycuda.compiler import SourceModule - from ....util.linalg_gpu import sum_axis -except: - pass gpu_code = """ // define THREADNUM @@ -292,6 +285,11 @@ gpu_code = """ class PSICOMP_SSRBF_GPU(PSICOMP_RBF): def __init__(self, threadnum=128, blocknum=15, GPU_direct=False): + + from pycuda.compiler import SourceModule + from ....util.gpu_init import initGPU + initGPU() + self.GPU_direct = GPU_direct self.gpuCache = None @@ -314,7 +312,8 @@ class PSICOMP_SSRBF_GPU(PSICOMP_RBF): memo[id(self)] = s return s - def _initGPUCache(self, N, M, Q): + def _initGPUCache(self, N, M, Q): + import pycuda.gpuarray as gpuarray if self.gpuCache == None: self.gpuCache = { 'l_gpu' :gpuarray.empty((Q,),np.float64,order='F'), @@ -377,12 +376,13 @@ class PSICOMP_SSRBF_GPU(PSICOMP_RBF): return variational_posterior.mean.shape[0], Z.shape[0], Z.shape[1] @Cache_this(limit=1, ignore_args=(0,)) - def psicomputations(self, variance, lengthscale, Z, variational_posterior): + def psicomputations(self, kern, Z, variational_posterior, return_psi2_n=False): """ Z - MxQ mu - NxQ S - NxQ """ + variance, lengthscale = kern.variance, kern.lengthscale N,M,Q = self.get_dimensions(Z, variational_posterior) self._initGPUCache(N,M,Q) self.sync_params(lengthscale, Z, variational_posterior.mean, variational_posterior.variance, variational_posterior.binary_prob) @@ -409,8 +409,10 @@ class PSICOMP_SSRBF_GPU(PSICOMP_RBF): else: return psi0, psi1_gpu.get(), psi2_gpu.get() - @Cache_this(limit=1, ignore_args=(0,1,2,3)) - def psiDerivativecomputations(self, dL_dpsi0, dL_dpsi1, dL_dpsi2, variance, lengthscale, Z, variational_posterior): + @Cache_this(limit=1, ignore_args=(0,2,3,4)) + def psiDerivativecomputations(self, kern, dL_dpsi0, dL_dpsi1, dL_dpsi2, Z, variational_posterior): + variance, lengthscale = kern.variance, kern.lengthscale + from ....util.linalg_gpu import sum_axis ARD = (len(lengthscale)!=1) N,M,Q = self.get_dimensions(Z, variational_posterior) diff --git a/GPy/util/__init__.py b/GPy/util/__init__.py index a21dc84e..6919f1a8 100644 --- a/GPy/util/__init__.py +++ b/GPy/util/__init__.py @@ -15,6 +15,5 @@ from . import caching from . import diag from . import initialization from . import multioutput -from . import linalg_gpu from . import parallel diff --git a/GPy/util/gpu_init.py b/GPy/util/gpu_init.py index 26dff0b3..0c496db3 100644 --- a/GPy/util/gpu_init.py +++ b/GPy/util/gpu_init.py @@ -16,33 +16,27 @@ try: except: pass -try: - if MPI_enabled and MPI.COMM_WORLD.size>1: - from .parallel import get_id_within_node - gpuid = get_id_within_node() - import pycuda.driver - pycuda.driver.init() - if gpuid>=pycuda.driver.Device.count(): - print('['+MPI.Get_processor_name()+'] more processes than the GPU numbers!') - #MPI.COMM_WORLD.Abort() - raise - gpu_device = pycuda.driver.Device(gpuid) - gpu_context = gpu_device.make_context() - gpu_initialized = True - else: - import pycuda.autoinit - gpu_initialized = True -except: - pass -try: - from scikits.cuda import cublas - import scikits.cuda.linalg as culinalg - culinalg.init() - cublas_handle = cublas.cublasCreate() -except: - pass +def initGPU(): + try: + if MPI_enabled and MPI.COMM_WORLD.size>1: + from .parallel import get_id_within_node + gpuid = get_id_within_node() + import pycuda.driver + pycuda.driver.init() + if gpuid>=pycuda.driver.Device.count(): + print('['+MPI.Get_processor_name()+'] more processes than the GPU numbers!') + raise + gpu_device = pycuda.driver.Device(gpuid) + gpu_context = gpu_device.make_context() + gpu_initialized = True + else: + import pycuda.autoinit + gpu_initialized = True + except: + pass + def closeGPU(): if gpu_context is not None: gpu_context.detach() diff --git a/GPy/util/linalg_gpu.py b/GPy/util/linalg_gpu.py index cba09dd3..db1c5317 100644 --- a/GPy/util/linalg_gpu.py +++ b/GPy/util/linalg_gpu.py @@ -61,12 +61,5 @@ try: except: pass -try: - import scikits.cuda.linalg as culinalg - from scikits.cuda import cublas - from scikits.cuda.cula import culaExceptions -except: - pass - From d3321251ef0fcaf1d995dea69ed7374cd77db9a0 Mon Sep 17 00:00:00 2001 From: Mike Croucher Date: Mon, 7 Sep 2015 16:34:53 +0100 Subject: [PATCH 4/5] Switched to scipy.special.log1p@ --- GPy/likelihoods/link_functions.py | 2 +- GPy/testing/link_function_tests.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/GPy/likelihoods/link_functions.py b/GPy/likelihoods/link_functions.py index 30ad32ad..4947fdb8 100644 --- a/GPy/likelihoods/link_functions.py +++ b/GPy/likelihoods/link_functions.py @@ -141,7 +141,7 @@ class Log_ex_1(GPTransformation): """ def transf(self,f): - return scipy.log1p(safe_exp(f)) + return scipy.special.log1p(safe_exp(f)) def dtransf_df(self,f): ef = safe_exp(f) diff --git a/GPy/testing/link_function_tests.py b/GPy/testing/link_function_tests.py index a4b631f8..2f8fc5a8 100644 --- a/GPy/testing/link_function_tests.py +++ b/GPy/testing/link_function_tests.py @@ -1,5 +1,5 @@ import numpy as np -import scipy as sp +import scipy from scipy.special import cbrt from GPy.models import GradientChecker _lim_val = np.finfo(np.float64).max @@ -92,8 +92,8 @@ class LinkFunctionTests(np.testing.TestCase): link = Log_ex_1() lim_of_inf = _lim_val_exp - np.testing.assert_almost_equal(np.log1p(np.exp(self.mid_f)), link.transf(self.mid_f)) - assert np.isinf(np.log1p(np.exp(np.log(self.f_upper_lim)))) + np.testing.assert_almost_equal(scipy.special.log1p(np.exp(self.mid_f)), link.transf(self.mid_f)) + assert np.isinf(scipy.special.log1p(np.exp(np.log(self.f_upper_lim)))) #Check the clipping works np.testing.assert_almost_equal(link.transf(self.f_lower_lim), 0, decimal=5) #Need to look at most significant figures here rather than the decimals From 415d99d62d820211bc0afdcfe969f912f8fbcc91 Mon Sep 17 00:00:00 2001 From: Mike Croucher Date: Mon, 7 Sep 2015 16:41:14 +0100 Subject: [PATCH 5/5] Used scipy.log1p since it gives more consistent results cross-platform --- GPy/testing/link_function_tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/GPy/testing/link_function_tests.py b/GPy/testing/link_function_tests.py index 2f8fc5a8..9f41f736 100644 --- a/GPy/testing/link_function_tests.py +++ b/GPy/testing/link_function_tests.py @@ -97,13 +97,13 @@ class LinkFunctionTests(np.testing.TestCase): #Check the clipping works np.testing.assert_almost_equal(link.transf(self.f_lower_lim), 0, decimal=5) #Need to look at most significant figures here rather than the decimals - np.testing.assert_approx_equal(link.transf(self.f_upper_lim), np.log1p(_lim_val), significant=5) + np.testing.assert_approx_equal(link.transf(self.f_upper_lim), scipy.special.log1p(_lim_val), significant=5) self.check_overflow(link, lim_of_inf) #Check that it would otherwise fail beyond_lim_of_inf = lim_of_inf + 10.0 old_err_state = np.seterr(over='ignore') - self.assertTrue(np.isinf(np.log1p(np.exp(beyond_lim_of_inf)))) + self.assertTrue(np.isinf(scipy.special.log1p(np.exp(beyond_lim_of_inf)))) np.seterr(**old_err_state)