使用 cython 扩展 numpy

发布于 2024-08-15 05:09:37 字数 820 浏览 3 评论 0原文

我正在尝试包装一个头文件,其中包含许多类似

test.h

void test(int N, int* data_in, int* data_out);

的函数,以便我可以使用 numpy 中的函数。

现在我有以下 cython 代码:

test.pyx

import numpy as np
cimport numpy as np

ctypedef np.int_t itype_t

cdef extern from 'VolumeForm.h':
    void _test 'test' (int, int*, int*)

def wrap_test(np.ndarray[itype_t, ndim=2] data):
    cdef np.ndarray[dtype_t, ndim=1] out
    out = np.zeros((data.shape[0],1), dtype=np.double)
    _test(
        data.shape[0],
        <itype_t*> data.data,
        <itype_t*> out.data
    )
    return out

但是,当我尝试编译它时,我收到错误:

Error converting Pyrex file to C:
(...)
Cannot assign type 'test.itype_t *' to 'int *'

如何解决此问题?

I am trying to wrap a header file which has lots of functions like this

test.h

void test(int N, int* data_in, int* data_out);

so that I can use those from numpy.

Right now I have the following cython code:

test.pyx

import numpy as np
cimport numpy as np

ctypedef np.int_t itype_t

cdef extern from 'VolumeForm.h':
    void _test 'test' (int, int*, int*)

def wrap_test(np.ndarray[itype_t, ndim=2] data):
    cdef np.ndarray[dtype_t, ndim=1] out
    out = np.zeros((data.shape[0],1), dtype=np.double)
    _test(
        data.shape[0],
        <itype_t*> data.data,
        <itype_t*> out.data
    )
    return out

However, when I try to compile it I get the error:

Error converting Pyrex file to C:
(...)
Cannot assign type 'test.itype_t *' to 'int *'

How can I fix this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

娇俏 2024-08-22 05:09:37

这个问题目前正在 Cython 邮件列表上讨论;显然它源于 Cython 库之一中的一个小错误:

http://codespeak.net/ mailman/listinfo/cython-dev

目前,一种可能的解决方法是使用 dtype np.long 的 NumPy 数组,然后改为编写“ctypedef np.long_t itype_t”。然后你只需要让 C 代码满意地使用长整型而不是整型。

This issue is currently being discussed on the Cython mailing list; apparently it stems from a small bug in one of the Cython libraries:

http://codespeak.net/mailman/listinfo/cython-dev

For the moment, one potential workaround is to use NumPy arrays of dtype np.long, and then to write 'ctypedef np.long_t itype_t' instead. Then you just have to make the C code happy with long ints instead of ints.

再见回来 2024-08-22 05:09:37

另一种解决方法不需要您将 int 更改为 long:将 cdef extern 中的函数签名从“...”< /代码> 块。 Cython 使用 cdef extern 块中的声明仅在生成 .c 文件时检查类型,但生成的 C 代码仅执行 #include "VolumeForm. h",这样你就可以逃脱惩罚。

import numpy as np
cimport numpy as np

ctypedef np.int_t itype_t

cdef extern from 'VolumeForm.h':
    # NOTE: We changed the int* declarations to itype_t*
    void _test 'test' (int, itype_t*, itype_t*)

def wrap_test(np.ndarray[itype_t, ndim=2] data):
    cdef np.ndarray[dtype_t, ndim=1] out
    out = np.zeros((data.shape[0],1), dtype=np.double)
    _test(
        data.shape[0],
        <itype_t*> data.data,
        <itype_t*> out.data
    )
    return out

Cython 并不抱怨上述情况。

Another workaround that doesn't require you to change things from ints to longs: change the function signature in the cdef extern from '...' block. Cython uses the declarations in a cdef extern block only to check types while generating the .c file, but the generated C code merely does an #include "VolumeForm.h", so you can get away with it.

import numpy as np
cimport numpy as np

ctypedef np.int_t itype_t

cdef extern from 'VolumeForm.h':
    # NOTE: We changed the int* declarations to itype_t*
    void _test 'test' (int, itype_t*, itype_t*)

def wrap_test(np.ndarray[itype_t, ndim=2] data):
    cdef np.ndarray[dtype_t, ndim=1] out
    out = np.zeros((data.shape[0],1), dtype=np.double)
    _test(
        data.shape[0],
        <itype_t*> data.data,
        <itype_t*> out.data
    )
    return out

Cython does not complain about the above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文