Skip to content

Instantly share code, notes, and snippets.

@kwmsmith
Last active August 12, 2022 04:25
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kwmsmith/5826432 to your computer and use it in GitHub Desktop.
Save kwmsmith/5826432 to your computer and use it in GitHub Desktop.
Numba vs. Cython: Parallel Cython with OMP
#cython:boundscheck=False
#cython:wraparound=False
import numpy as np
from cython.parallel cimport prange
from libc.math cimport sqrt
cdef inline double dotp(int i, int j, int N, double[:, ::1] X) nogil:
cdef:
int k
double d=0.0
for k in range(N):
d += (X[i,k] - X[j,k])**2
return sqrt(d)
def pairwise_cython_omp(double[:, ::1] X):
cdef:
int i, j
int M = X.shape[0], N = X.shape[1]
double[:, ::1] D = np.empty((M, M), dtype=np.float64)
for i in prange(M, nogil=True):
for j in range(M):
D[i, j] = dotp(i, j, N, X)
return np.asarray(D)
def pairwise_cython(double[:, ::1] X):
cdef:
int i, j
int M = X.shape[0], N = X.shape[1]
double[:, ::1] D = np.empty((M, M), dtype=np.float64)
for i in range(M):
for j in range(M):
D[i, j] = dotp(i, j, N, X)
return np.asarray(D)
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext = Extension("pairwise_cython", ['pairwise_cython.pyx'],
extra_compile_args=['-fopenmp'],
extra_link_args=['-fopenmp'],
)
setup(
cmdclass = {'build_ext': build_ext},
ext_modules = [ext],
)
import numpy as np
from pairwise_cython import pairwise_cython_omp, pairwise_cython
X = np.random.random((1000, 3))
%timeit pairwise_cython_omp(X)
%timeit pairwise_cython(X)
# pairwise_cython_omp: 3.43ms per loop
# pairwise_cython: 9.96ms per loop
# ~2.9x speedup over serial Cython and Numba
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment