diff --git a/requirements.txt b/requirements.txt index 5a6870cd3d8..b23bdc7cdb7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -15,7 +15,7 @@ pathlib==1.0.1; python_version < "3.4" jsonschema>=2.6.0,<3.1.0 # Development dependencies cython>=0.25 -pytest>=4.0.0,<4.1.0 +pytest>=4.6.5 pytest-timeout>=1.3.0,<2.0.0 mock>=2.0.0,<3.0.0 flake8>=3.5.0,<3.6.0 diff --git a/spacy/syntax/_parser_model.pxd b/spacy/syntax/_parser_model.pxd index 5aec986d2a2..9c72f34156b 100644 --- a/spacy/syntax/_parser_model.pxd +++ b/spacy/syntax/_parser_model.pxd @@ -36,7 +36,9 @@ cdef WeightsC get_c_weights(model) except * cdef SizesC get_c_sizes(model, int batch_size) except * -cdef void resize_activations(ActivationsC* A, SizesC n) nogil +cdef ActivationsC alloc_activations(SizesC n) nogil + +cdef void free_activations(const ActivationsC* A) nogil cdef void predict_states(ActivationsC* A, StateC** states, const WeightsC* W, SizesC n) nogil diff --git a/spacy/syntax/_parser_model.pyx b/spacy/syntax/_parser_model.pyx index 841e3343234..ce3dcbfa5a3 100644 --- a/spacy/syntax/_parser_model.pyx +++ b/spacy/syntax/_parser_model.pyx @@ -62,6 +62,21 @@ cdef SizesC get_c_sizes(model, int batch_size) except *: return output +cdef ActivationsC alloc_activations(SizesC n) nogil: + cdef ActivationsC A + memset(&A, 0, sizeof(A)) + resize_activations(&A, n) + return A + + +cdef void free_activations(const ActivationsC* A) nogil: + free(A.token_ids) + free(A.scores) + free(A.unmaxed) + free(A.hiddens) + free(A.is_valid) + + cdef void resize_activations(ActivationsC* A, SizesC n) nogil: if n.states <= A._max_size: A._curr_size = n.states diff --git a/spacy/syntax/nn_parser.pyx b/spacy/syntax/nn_parser.pyx index fa1a41fa4c4..9b45fb0f73e 100644 --- a/spacy/syntax/nn_parser.pyx +++ b/spacy/syntax/nn_parser.pyx @@ -27,7 +27,8 @@ from thinc.neural.util import get_array_module from thinc.linalg cimport Vec, VecVec import srsly -from ._parser_model cimport resize_activations, predict_states, arg_max_if_valid +from ._parser_model cimport alloc_activations, free_activations +from ._parser_model cimport predict_states, arg_max_if_valid from ._parser_model cimport WeightsC, ActivationsC, SizesC, cpu_log_loss from ._parser_model cimport get_c_weights, get_c_sizes from ._parser_model import ParserModel @@ -306,8 +307,7 @@ cdef class Parser: WeightsC weights, SizesC sizes) nogil: cdef int i, j cdef vector[StateC*] unfinished - cdef ActivationsC activations - memset(&activations, 0, sizeof(activations)) + cdef ActivationsC activations = alloc_activations(sizes) while sizes.states >= 1: predict_states(&activations, states, &weights, sizes) @@ -321,6 +321,7 @@ cdef class Parser: states[i] = unfinished[i] sizes.states = unfinished.size() unfinished.clear() + free_activations(&activations) def set_annotations(self, docs, states_or_beams, tensors=None): cdef StateClass state