为32位和64位编写cython?

时间:2015-01-23 14:57:44

标签: python numpy 64-bit cython

我正在研究一些包含

等函数定义的cython模块的项目
def f(np.ndarray[int, ndim=1, mode='c'] x):
    _f(&x[0])

cdef _f(int* x):
    ...

我在64位计算机上,所以在运行时我在调用f时遇到如下错误:

ValueError: Item size of buffer (8 bytes) does not match size of 'int' (4 bytes)

通过更改为long整数,可以“修复”代码以在我的机器上运行:

def f(np.ndarray[long, ndim=1, mode='c'] x):
    _f(&x[0])

cdef _f(long* x):
    ...

问题是NumPy整数数组在32位上默认为int32,在64位上默认为int64,分别对应intlong,在c / cython中。 (这甚至是正确的吗?)

那么,编写适用于32位和64位的cython的推荐或标准做法是什么?

  1. 我应该检查platform.architecture并将ctypedef放在我的.pyx文件的顶部吗?将ctypedef置于if语句中是否有效?像这样:

    import platform
    bits, linkage = platform.architechure
    if bits == '64bit':
        ctypedef long myint_t
    elif bits == '32bit':
        ctypedef int myint_t
    
    def f(np.ndarray[myint_t, ndim=1, mode='c'] x):
         _f(x)
    
    cdef _f(long* x):
        ...
    
  2. 我应该单独离开cython库,强制输入数组为32位整数吗?像这样:

    import numpy as np
    import my_cython_library
    
    data = np.arange(10, dtype='int32')
    my_cython_library.f(data)
    
  3. 我是否遗漏了cython构建或编译选项中显而易见的内容?

  4. 我不喜欢(1)因为那时我只有基本整数的自定义类型,我不喜欢(2)因为那时我使用我的硬件很差并指定类型,即使它应该很明显。所以我希望有一个很好的选择(3)。

1 个答案:

答案 0 :(得分:1)

如何声明fused type,例如:

cimport numpy as np

ctypedef fused int_t:
    np.int32_t
    np.int64_t

cdef int_t my_func(int_t[:] A, int_t[:] B):
    ...

这样你就可以拥有一个静态类型的Cython函数,它可以在32位或64位整数上运行。