我正在研究一些包含
等函数定义的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
,分别对应int
和long
,在c / cython中。 (这甚至是正确的吗?)
那么,编写适用于32位和64位的cython的推荐或标准做法是什么?
我应该检查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):
...
我应该单独离开cython库,强制输入数组为32位整数吗?像这样:
import numpy as np
import my_cython_library
data = np.arange(10, dtype='int32')
my_cython_library.f(data)
我是否遗漏了cython构建或编译选项中显而易见的内容?
我不喜欢(1)因为那时我只有基本整数的自定义类型,我不喜欢(2)因为那时我使用我的硬件很差并指定类型,即使它应该很明显。所以我希望有一个很好的选择(3)。
答案 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位整数上运行。