Skip to content

Commit 0db47c7

Browse files
authored
Add nonexcept declarations for Cython 3.0 (#680)
This fixes a large performance regression with many of the CPU models. For instance when training the ml100k dataset, when compiled with Cython 3.0.0: * Without this change ``` DEBUG:implicit:trained model 'bpr' in 69.49404716491699 DEBUG:implicit:trained model 'lmf' in 42.24160981178284 DEBUG:implicit:trained model 'als' in 120.11413407325745 ``` * With this change ``` DEBUG:implicit:trained model 'bpr' in 0.18895816802978516 DEBUG:implicit:trained model 'lmf' in 0.06523633003234863 DEBUG:implicit:trained model 'als' in 1.8809657096862793 ``` Fixes #678
1 parent 95c9b33 commit 0db47c7

File tree

4 files changed

+14
-12
lines changed

4 files changed

+14
-12
lines changed

implicit/cpu/_als.pyx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#cython: legacy_implicit_noexcept=True
2+
13
import cython
24
import numpy as np
35

@@ -15,40 +17,40 @@ from libc.string cimport memcpy, memset
1517

1618
# lapack/blas wrappers for cython fused types
1719
cdef inline void axpy(int * n, floating * da, floating * dx, int * incx, floating * dy,
18-
int * incy) nogil:
20+
int * incy) noexcept nogil:
1921
if floating is double:
2022
cython_blas.daxpy(n, da, dx, incx, dy, incy)
2123
else:
2224
cython_blas.saxpy(n, da, dx, incx, dy, incy)
2325

2426
cdef inline void symv(char *uplo, int *n, floating *alpha, floating *a, int *lda, floating *x,
25-
int *incx, floating *beta, floating *y, int *incy) nogil:
27+
int *incx, floating *beta, floating *y, int *incy) noexcept nogil:
2628
if floating is double:
2729
cython_blas.dsymv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
2830
else:
2931
cython_blas.ssymv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
3032

31-
cdef inline floating dot(int *n, floating *sx, int *incx, floating *sy, int *incy) nogil:
33+
cdef inline floating dot(int *n, floating *sx, int *incx, floating *sy, int *incy) noexcept nogil:
3234
if floating is double:
3335
return cython_blas.ddot(n, sx, incx, sy, incy)
3436
else:
3537
return cython_blas.sdot(n, sx, incx, sy, incy)
3638

37-
cdef inline void scal(int *n, floating *sa, floating *sx, int *incx) nogil:
39+
cdef inline void scal(int *n, floating *sa, floating *sx, int *incx) noexcept nogil:
3840
if floating is double:
3941
cython_blas.dscal(n, sa, sx, incx)
4042
else:
4143
cython_blas.sscal(n, sa, sx, incx)
4244

4345
cdef inline void posv(char * u, int * n, int * nrhs, floating * a, int * lda, floating * b,
44-
int * ldb, int * info) nogil:
46+
int * ldb, int * info) noexcept nogil:
4547
if floating is double:
4648
cython_lapack.dposv(u, n, nrhs, a, lda, b, ldb, info)
4749
else:
4850
cython_lapack.sposv(u, n, nrhs, a, lda, b, ldb, info)
4951

5052
cdef inline void gesv(int * n, int * nrhs, floating * a, int * lda, int * piv, floating * b,
51-
int * ldb, int * info) nogil:
53+
int * ldb, int * info) noexcept nogil:
5254
if floating is double:
5355
cython_lapack.dgesv(n, nrhs, a, lda, piv, b, ldb, info)
5456
else:

implicit/cpu/bpr.pyx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ cdef extern from "<random>" namespace "std":
3737

3838
cdef cppclass uniform_int_distribution[T]:
3939
uniform_int_distribution(T, T)
40-
T operator()(mt19937) nogil
40+
T operator()(mt19937) noexcept nogil
4141

4242

4343
cdef class RNGVector(object):
@@ -55,13 +55,13 @@ cdef class RNGVector(object):
5555
self.rng.push_back(mt19937(rng_seeds[i]))
5656
self.dist.push_back(uniform_int_distribution[long](0, rows))
5757

58-
cdef inline long generate(self, int thread_id) nogil:
58+
cdef inline long generate(self, int thread_id) noexcept nogil:
5959
return self.dist[thread_id](self.rng[thread_id])
6060

6161

6262
@cython.boundscheck(False)
6363
cdef bool has_non_zero(integral[:] indptr, integral[:] indices,
64-
integral rowid, integral colid) nogil:
64+
integral rowid, integral colid) noexcept nogil:
6565
""" Given a CSR matrix, returns whether the [rowid, colid] contains a non zero.
6666
Assumes the CSR matrix has sorted indices """
6767
return binary_search(&indices[indptr[rowid]], &indices[indptr[rowid + 1]], colid)

implicit/cpu/lmf.pyx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ cdef class RNGVector(object):
5252
self.rng.push_back(mt19937(rng_seeds[i]))
5353
self.dist.push_back(uniform_int_distribution[long](0, rows))
5454

55-
cdef inline long generate(self, int thread_id) nogil:
55+
cdef inline long generate(self, int thread_id) noexcept nogil:
5656
return self.dist[thread_id](self.rng[thread_id])
5757

5858

@@ -218,7 +218,7 @@ class LogisticMatrixFactorization(MatrixFactorizationBase):
218218

219219

220220
@cython.cdivision(True)
221-
cdef inline floating sigmoid(floating x) nogil:
221+
cdef inline floating sigmoid(floating x) noexcept nogil:
222222
if x >= 0:
223223
return 1 / (1+exp(-x))
224224
else:

implicit/cpu/topk.pyx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ from cython.parallel import parallel, prange
99
cdef extern from "implicit/cpu/select.h" namespace "implicit" nogil:
1010
cdef void select[T](const T * batch,
1111
int batch_rows, int batch_columns, int k,
12-
int * ids, T * distances) nogil except +
12+
int * ids, T * distances) noexcept nogil
1313

1414

1515
def topk(items, query, int k, item_norms=None, filter_query_items=None, filter_items=None, int num_threads=0):

0 commit comments

Comments
 (0)