I am trying to define a hash for a sorted vector of type size_t
. As part of the solution, I use an XOR operation.
cdef size_t vector_hash(const vector[size_t]& v) noexcept nogil:
"""Hash a vector of size_t."""
cdef size_t seed = v.size()
cdef size_t i, hash_val
for i in v:
seed = seed ^ (i + 0x9e3779b9 + (seed << 6) + (seed >> 2))
hash_val = seed
return hash_val
However, I get the following error when trying to compile:
Error compiling Cython file:
------------------------------------------------------------
...
cdef size_t vector_hash(const vector[size_t]& v) noexcept nogil:
"""Hash a vector of size_t."""
cdef size_t seed = v.size()
cdef size_t i, hash_val
for i in v:
seed = seed ^ (i + 0x9e3779b9 + (seed << 6) + (seed >> 2))
^
------------------------------------------------------------
/Users/adam2392/Documents/scikit-tree/sktree/tree/_utils.pyx:155:20: Coercion from Python not allowed without the GIL
My questions are:
There are two problems:
The constant 0x9e3779b9
is treated as a python integer, we should cast it to size_t
: <size_t>0x9e3779b9
Cython cannot generate the right code for the loop for i in v
when v
is const vector[size_t]&
, Cython will produce a non-const interator which result in a compiling error. We can drop the const qualifier: size_t vector_hash(vector[size_t]& v)
or use an alternative loop method:
for i in range(v.size()):
seed = seed ^ (v[i] + <size_t>0x9e3779b9 + (seed << 6) + (seed >> 2))