Package: kde-ocl
This repository implements GaussianKernel Density Estimationusing
OpenCL to achieve important performance gains.The Python interface is based on theScipy'sgaussian_kdeclass,
so it should be pretty easy to replace the CPU implementation ofgaussian_kdewith the
OpenCL implementation in this repositorygaussian_kde_ocl.Example Codeimportnumpyasnpfromkde_oclimportgaussian_kde_ocl# Generate dummy training data (10000 instances of 2D data)train=np.random.multivariate_normal([0,0],[[1,0],[0,1]],10000)# Generate dummy test data (10000 instances of 2D data)test=np.random.multivariate_normal([0,0],[[1,0],[0,1]],100)# Train the KDE modelkde=gaussian_kde_ocl(train)# Get the pdf of each test point. This is equivalent to kde.pdf(test)pdf=kde(test)# Get the logpdf of each test point. This is equivalent to kde.pdf(test)logpdf=kde.logpdf(test)The interface is mostly the same as Scipy'sgaussian_kde, but the axis order is changed. For example, training a
Scipy'sgaussian_kdewith a numpy array of shape (10000, 2) is interpreted as two instances of 10000 dimensions. Ingaussian_kde_ocl, this data is interpreted as 10000 instances of 2 dimensions. This change makes easier to work withpandasdataframes:importpandasaspdimportnumpyasnpfromkde_oclimportgaussian_kde_ocl# Create pandas dataframea=np.random.normal(0,1,5000)b=np.random.normal(3.2,np.sqrt(1.8),5000)data=pd.DataFrame({'a':a,'b':b})# Train KDE modelkde=gaussian_kde_ocl(data.values)# Evaluate one pointlogpdf=kde.logpdf([1.1,2.3])PerformanceThis is a comparison of thegaussian_kde_ocland Scipy'sgaussian_kdewith 2D data and the following configuration:CPU: Intel i7-6700K.GPU: AMD RX 460.Python 3.7.3Ubuntu 16.04pdf()methodTraining instances / Test instancesgaussian_kde_ocl.pdf()gaussian_kde.pdf()Speedup100,000 / 1,000218.6474 ± 1.5901 ms1,911.0764 ± 50.8762 ms8.74x1,000 / 10,000,00018.8643 ± 0.07322 s237.3429 ± 1.1765 s12.58x100 / 10,0004.4533 ± 0.7297 ms18.0684 ± 0.3302 ms4.46xlogpdf()methodTraining instances / Test instancesgaussian_kde_ocl.logpdf()gaussian_kde.logpdf()Speedup100,000 / 1,000261.1466 ± 6.3932 ms6,798.4730 ± 420.2878 ms26.03x1,000 / 10,000,00036.3143 ± 0.02916 sMemoryErrorNA100 / 10,0008.827 ± 0.7442 ms34.1114 ± 1.3060 ms3.86xCurrent LimitationsOnly C order (the default) numpy arrays can be used as traning/test datasets.Only Gaussian kernels are implemented.OpenCL device is selected automatically.DependenciesThe library is Python 2/3 compatible. Currently, is tested in Ubuntu 16.04, but should be compatible with other operating systems where
there are OpenCL GPU support.Python DependenciesThe project has the following Python dependencies:cffi numpy sixYou can install them with:pip install cffi numpy sixRustTheRustcompiler must be installed in the system. Check outhttps://www.rust-lang.org/tools/installfor more information.The default Rust toolchain is used to compile the library, somake sure to install a Rust toolchain (32 vs 64 bits) compatible with the Python interpreter version (32 vs 64 bits).OpenCLThe GPU drivers that enable OpenCL should be installed.InstallationUse pip:pip install kde_oclAlternatively, clone the repository and use the setup script:python setup.py installTestingTests are run using pytest and requiresscipyto comparegaussian_kde_oclwith Scipy'sgaussian_kde. Install them:pip pytest scipyRun the tests with:pytestBenchmarksTo run the benchmarks,pytest-benchmarkis needed:pip pytest-benchmarkThen, execute the tests with benchmarks enabled:pytest --timesTo run only the OpenCL benchmarks:pytest --times-oclTo run only the Scipy'sgaussian_kdebenchmarks:pytest --times-scipy