* Add support for l/r edge to add_dep, and move inlined methods into _state.pyx where possible

This commit is contained in:
Matthew Honnibal 2015-04-29 19:28:21 +02:00
parent d634038eb6
commit a4e2af54f9
2 changed files with 30 additions and 26 deletions

View File

@ -107,28 +107,6 @@ cdef int head_in_stack(const State *s, const int child, const int* gold) except
cdef State* new_state(Pool mem, TokenC* sent, const int sent_length) except NULL cdef State* new_state(Pool mem, TokenC* sent, const int sent_length) except NULL
cdef int count_left_kids(const TokenC* head) nogil cdef int count_left_kids(const TokenC* head) nogil
cdef int count_right_kids(const TokenC* head) nogil cdef int count_right_kids(const TokenC* head) nogil
# From https://en.wikipedia.org/wiki/Hamming_weight
cdef inline uint32_t _popcount(uint32_t x) nogil:
"""Find number of non-zero bits."""
cdef int count = 0
while x != 0:
x &= x - 1
count += 1
return count
cdef inline uint32_t _nth_significant_bit(uint32_t bits, int n) nogil:
cdef int i
for i in range(32):
if bits & (1 << i):
n -= 1
if n < 1:
return i
return 0

View File

@ -17,8 +17,14 @@ cdef int add_dep(State *s, int head, int child, int label) except -1:
# offset i from it, set that bit (tracking left and right separately) # offset i from it, set that bit (tracking left and right separately)
if child > head: if child > head:
s.sent[head].r_kids |= 1 << (-dist) s.sent[head].r_kids |= 1 << (-dist)
s.sent[head].r_edge = s.sent[child].r_edge
# Walk up the tree, setting right edge
while s.sent[head].head < 0:
head += s.sent[head].head
s.sent[head].r_edge = s.sent[child].r_edge
else: else:
s.sent[head].l_kids |= 1 << dist s.sent[head].l_kids |= 1 << dist
s.sent[head].l_edge = s.sent[child].l_edge
cdef int pop_stack(State *s) except -1: cdef int pop_stack(State *s) except -1:
@ -71,6 +77,10 @@ cdef int head_in_stack(const State *s, const int child, const int* gold) except
return 0 return 0
cdef bint has_head(const TokenC* t) nogil:
return t.head != 0
cdef const TokenC* get_left(const State* s, const TokenC* head, const int idx) nogil: cdef const TokenC* get_left(const State* s, const TokenC* head, const int idx) nogil:
cdef uint32_t kids = head.l_kids cdef uint32_t kids = head.l_kids
if kids == 0: if kids == 0:
@ -95,10 +105,6 @@ cdef const TokenC* get_right(const State* s, const TokenC* head, const int idx)
return NULL return NULL
cdef bint has_head(const TokenC* t) nogil:
return t.head != 0
cdef int count_left_kids(const TokenC* head) nogil: cdef int count_left_kids(const TokenC* head) nogil:
return _popcount(head.l_kids) return _popcount(head.l_kids)
@ -124,3 +130,23 @@ cdef State* new_state(Pool mem, const TokenC* sent, const int sent_len) except N
s.i = 0 s.i = 0
s.sent_len = sent_len s.sent_len = sent_len
return s return s
# From https://en.wikipedia.org/wiki/Hamming_weight
cdef inline uint32_t _popcount(uint32_t x) nogil:
"""Find number of non-zero bits."""
cdef int count = 0
while x != 0:
x &= x - 1
count += 1
return count
cdef inline uint32_t _nth_significant_bit(uint32_t bits, int n) nogil:
cdef int i
for i in range(32):
if bits & (1 << i):
n -= 1
if n < 1:
return i
return 0