Skip to content

Commit d6f3127

Browse files
removed the restriction n_max_matches put on memory allocation
1 parent 5b2ce38 commit d6f3127

17 files changed

+1892
-736
lines changed

setup.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,28 @@ def finalize_options(self):
2929
else:
3030
extra_compile_args = ['-std=c++0x', '-pthread', '-O3']
3131

32+
array_wrappers_ext = Extension('sparse_dot_topn.array_wrappers',
33+
sources=[
34+
'./sparse_dot_topn/array_wrappers.pyx',
35+
'./sparse_dot_topn/sparse_dot_topn_source.cpp'
36+
],
37+
extra_compile_args=extra_compile_args,
38+
language='c++')
39+
3240
original_ext = Extension('sparse_dot_topn.sparse_dot_topn',
33-
sources=['./sparse_dot_topn/sparse_dot_topn.pyx',
34-
'./sparse_dot_topn/sparse_dot_topn_source.cpp'],
41+
sources=[
42+
'./sparse_dot_topn/sparse_dot_topn.pyx',
43+
'./sparse_dot_topn/sparse_dot_topn_source.cpp'
44+
],
3545
extra_compile_args=extra_compile_args,
3646
language='c++')
3747

3848
threaded_ext = Extension('sparse_dot_topn.sparse_dot_topn_threaded',
3949
sources=[
4050
'./sparse_dot_topn/sparse_dot_topn_threaded.pyx',
4151
'./sparse_dot_topn/sparse_dot_topn_source.cpp',
42-
'./sparse_dot_topn/sparse_dot_topn_parallel.cpp'],
52+
'./sparse_dot_topn/sparse_dot_topn_parallel.cpp'
53+
],
4354
extra_compile_args=extra_compile_args,
4455
language='c++')
4556

@@ -77,5 +88,5 @@ def finalize_options(self):
7788
, 'pandas>=0.25.3'
7889
],
7990
cmdclass={'build_ext': my_build_ext},
80-
ext_modules=[original_ext, threaded_ext]
91+
ext_modules=[array_wrappers_ext, original_ext, threaded_ext]
8192
)

sparse_dot_topn/__init__.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
# flake8: noqa
2-
from sparse_dot_topn.awesome_cossim_topn import awesome_cossim_topn, awesome_cossim_true_minmax_topn_only
2+
import sys
3+
4+
if sys.version_info[0] >= 3:
5+
from sparse_dot_topn.awesome_cossim_topn import awesome_cossim_topn
6+
else:
7+
from awesome_cossim_topn import awesome_cossim_topn

sparse_dot_topn/array_wrappers.pxd

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from libcpp.vector cimport vector
2+
3+
# define a Cython array wrapper class to hold a C++ vector of ints, adhering to numpy's buffer protocol:
4+
cdef class ArrayWrapper_int:
5+
cdef int view_count
6+
cdef vector[int] vec
7+
cdef Py_ssize_t shape[2]
8+
cdef Py_ssize_t strides[2]
9+
10+
11+
# define a Cython array wrapper class to hold a C++ vector of doubles, adhering to numpy's buffer protocol:
12+
cdef class ArrayWrapper_double:
13+
cdef int view_count
14+
cdef vector[double] vec
15+
cdef Py_ssize_t shape[2]
16+
cdef Py_ssize_t strides[2]
17+
18+

sparse_dot_topn/array_wrappers.pyx

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
from cpython cimport Py_buffer
2+
from libcpp.vector cimport vector
3+
4+
# define a Cython array wrapper class to hold a C++ vector of ints, adhering to numpy's buffer protocol:
5+
cdef class ArrayWrapper_int:
6+
# constructor and destructor are fairly unimportant now since
7+
# vec will be destroyed automatically.
8+
9+
def __cinit__(self, vector[int]& data):
10+
self.vec.swap(data)
11+
self.view_count = 0
12+
13+
# now implement the buffer protocol for the class
14+
# which makes it generally useful to anything that expects an array
15+
def __getbuffer__(self, Py_buffer *buffer, int flags):
16+
# relevant documentation http://cython.readthedocs.io/en/latest/src/userguide/buffer.html#a-matrix-class
17+
cdef Py_ssize_t itemsize = sizeof(self.vec[0])
18+
19+
self.shape[1] = self.vec.size()
20+
self.shape[0] = 1
21+
self.strides[1] = <Py_ssize_t>( <char *>&(self.vec[1]) - <char *>&(self.vec[0]))
22+
self.strides[0] = self.vec.size() * self.strides[1]
23+
buffer.buf = <char *>&(self.vec[0])
24+
buffer.format = 'i'
25+
buffer.internal = NULL
26+
buffer.itemsize = itemsize
27+
buffer.len = self.vec.size() * itemsize # product(shape) * itemsize
28+
buffer.ndim = 2
29+
buffer.obj = self
30+
buffer.readonly = 0
31+
buffer.shape = self.shape
32+
buffer.strides = self.strides
33+
buffer.suboffsets = NULL
34+
self.view_count += 1
35+
36+
def __releasebuffer__(self, Py_buffer *buffer):
37+
self.view_count -= 1
38+
39+
40+
# define a Cython array wrapper class to hold a C++ vector of doubles, adhering to numpy's buffer protocol:
41+
cdef class ArrayWrapper_double:
42+
# constructor and destructor are fairly unimportant now since
43+
# vec will be destroyed automatically.
44+
45+
def __cinit__(self, vector[double]& data):
46+
self.vec.swap(data)
47+
self.view_count = 0
48+
49+
# now implement the buffer protocol for the class
50+
# which makes it generally useful to anything that expects an array
51+
def __getbuffer__(self, Py_buffer *buffer, int flags):
52+
# relevant documentation http://cython.readthedocs.io/en/latest/src/userguide/buffer.html#a-matrix-class
53+
cdef Py_ssize_t itemsize = sizeof(self.vec[0])
54+
55+
self.shape[1] = self.vec.size()
56+
self.shape[0] = 1
57+
self.strides[1] = <Py_ssize_t>( <char *>&(self.vec[1]) - <char *>&(self.vec[0]))
58+
self.strides[0] = self.vec.size() * self.strides[1]
59+
buffer.buf = <char *>&(self.vec[0])
60+
buffer.format = 'd'
61+
buffer.internal = NULL
62+
buffer.itemsize = itemsize
63+
buffer.len = self.vec.size() * itemsize # product(shape) * itemsize
64+
buffer.ndim = 2
65+
buffer.obj = self
66+
buffer.readonly = 0
67+
buffer.shape = self.shape
68+
buffer.strides = self.strides
69+
buffer.suboffsets = NULL
70+
self.view_count += 1
71+
72+
def __releasebuffer__(self, Py_buffer *buffer):
73+
self.view_count -= 1

0 commit comments

Comments
 (0)