Nogil 上下文中 Cython 中的异或运算

问题描述 投票:0回答:1

我正在尝试为

size_t
类型的排序向量定义一个哈希。作为解决方案的一部分,我使用 XOR 运算。

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

但是,在尝试编译时出现以下错误:

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

我的问题是:

  1. 为什么不能在 nogil 上下文中使用 XOR?
  2. 那么在 nogil 上下文中实现 XOR 的方法是什么?
c++ cython xor
1个回答
0
投票

有两个问题:

  1. 常量

    0x9e3779b9
    被视为Python整数,我们应该将其转换为
    size_t
    <size_t>0x9e3779b9

  2. Cython 无法为循环

    for i in v
    生成正确的代码,当
    v
    const vector[size_t]&
    时,Cython 将生成非常量迭代器,从而导致编译错误。我们可以删除 const 限定符:
    size_t vector_hash(vector[size_t]& v)
    或使用替代循环方法:

    for i in range(v.size()):
        seed = seed ^ (v[i] + <size_t>0x9e3779b9 + (seed << 6) + (seed >> 2))
© www.soinside.com 2019 - 2024. All rights reserved.