diff --git a/setup.py b/setup.py index 5c588a70e..5080b82a0 100644 --- a/setup.py +++ b/setup.py @@ -56,9 +56,8 @@ exts = [ include_dirs=includes), Extension("spacy.tokens", ["spacy/tokens.pyx"], language="c++", include_dirs=includes), - - - + Extension("spacy.memory", ["spacy/memory.pyx"], language="c++", + include_dirs=includes) ] diff --git a/spacy/memory.pxd b/spacy/memory.pxd new file mode 100644 index 000000000..85155572e --- /dev/null +++ b/spacy/memory.pxd @@ -0,0 +1,11 @@ +from libcpp.vector cimport vector + +cdef class Pool: + cdef vector[void*] _addresses + + cdef void* alloc(self, size_t number, size_t size) except NULL + cdef void* realloc(self, void* addr, size_t n) except NULL + + +cdef class Address: + cdef size_t addr diff --git a/spacy/memory.pyx b/spacy/memory.pyx new file mode 100644 index 000000000..2cdc7fc05 --- /dev/null +++ b/spacy/memory.pyx @@ -0,0 +1,39 @@ +from cpython.mem cimport PyMem_Malloc, PyMem_Realloc, PyMem_Free +from libc.string cimport memset + +from libcpp.vector cimport vector + + +cdef class Pool: + def __cinit__(self): + pass + + def __dealloc__(self): + cdef void* addr + for addr in self._addresses: + PyMem_Free(addr) + + cdef void* alloc(self, size_t number, size_t size) except NULL: + cdef void* addr = PyMem_Malloc(number * size) + memset(addr, 0, number * size) + self._addresses.push_back(addr) + return addr + + cdef void* realloc(self, void* addr, size_t n) except NULL: + cdef size_t i + for i in range(self.size()): + if self._addresses[i] == addr: + self._addresses[i] = PyMem_Realloc(addr, n) + return self._addresses[i] + else: + raise MemoryError("Address to realloc not found in pool") + + +cdef class Address: + def __cinit__(self, size_t number, size_t size): + cdef void* addr = PyMem_Malloc(number * size) + memset(addr, 0, number * size) + self.addr = addr + + def __dealloc__(self): + PyMem_Free(self.addr)