Path: blob/master/python/cython/pairwise3.pyx
2574 views
# cython: boundscheck = False1# cython: wraparound = False23cimport cython4import numpy as np5from libc.math cimport sqrt6from cython.parallel import parallel, prange78# up till now we're still utilizing only a single thread9# we can use multiple threads and tap into all available CPU cores10# using the parallel functionality;11# to do this we need to release the GIL (this helps python's memory management,12# but it is also this functionality that does not allow python to use all cores)13# to call a "GIL-less" function, we place nogil after it;14# note that we can't interact with python objects inside15cdef inline double euclidean_distance(double[:, :] X, int i, int j, int N) nogil:1617# declare C types for as many of our variables as possible18# using cdef:19cdef:20int k21double tmp, d = 0.02223for k in range(N):24tmp = X[i, k] - X[j, k]25d += tmp * tmp2627return sqrt(d)282930def pairwise3(double[:, :] X):3132cdef:33int i, j34double dist35int n_samples = X.shape[0], n_dim = X.shape[1]36double[:, :] D = np.zeros((n_samples, n_samples), dtype = np.float64)3738# parallelize this over the outermost loop, using the prange function39with nogil, parallel():40for i in prange(n_samples):41for j in range(i + 1, n_samples):42dist = euclidean_distance(X, i, j, n_dim)43D[i, j] = dist44D[j, i] = dist45return D464748