ypbind11获取numpy的itemsize为0

pybind11与numpy版本兼容问题

问题

我们的一个程序,主程序是基于c++编写,在主程序中通过ypbind11调用python从而实现可以通过python编写脚本,python通过numpy把数据返回给c++,最近打包的镜像突然发现c++侧无法正常拿到数据了,通过debug发现pybind11侧从python结构里面拿到的数据的itemsize是0,去查看了pybind11的更新发现是因为我们的pybind11版本和numpy2.0不兼容了,需要升级更新的pybind11才能兼容numpy2.0.

这里我们在作镜像的时候会安装numpy依赖,但是因为我们在requirement.txt中只指定了最小版本,没有指定最大版本,所以当安装的numpy是2.0的时候,就会有问题。

pybind11怎么兼容的

可以看到在新版本的pybind11中,https://github.com/pybind/pybind11/blob/master/include/pybind11/numpy.h里面已经同时包含了numpy的1.0和2.0的对象部署声明:

/* NumPy 1 proxy (always includes legacy fields) */
struct PyArrayDescr1_Proxy {
    PyObject_HEAD
    PyObject *typeobj;
    char kind;
    char type;
    char byteorder;
    char flags;
    int type_num;
    int elsize;
    int alignment;
    char *subarray;
    PyObject *fields;
    PyObject *names;
};

struct PyArrayDescr_Proxy {
    PyObject_HEAD
    PyObject *typeobj;
    char kind;
    char type;
    char byteorder;
    char _former_flags;
    int type_num;
    /* Additional fields are NumPy version specific. */
};

/* NumPy 2 proxy, including legacy fields */
struct PyArrayDescr2_Proxy {
    PyObject_HEAD
    PyObject *typeobj;
    char kind;
    char type;
    char byteorder;
    char _former_flags;
    int type_num;
    std::uint64_t flags;
    ssize_t elsize;
    ssize_t alignment;
    PyObject *metadata;
    Py_hash_t hash;
    void *reserved_null[2];
    /* The following fields only exist if 0 <= type_num < 2056 */
    char *subarray;
    PyObject *fields;
    PyObject *names;
};

struct PyArray_Proxy {
    PyObject_HEAD
    char *data;
    int nd;
    ssize_t *dimensions;
    ssize_t *strides;
    PyObject *base;
    PyObject *descr;
    int flags;
};

并且在涉及到不兼容的地方都加入了numpy的版本判断。

 ssize_t itemsize() const {
        if (detail::npy_api::get().PyArray_RUNTIME_VERSION_ < 0x12) {
            return detail::array_descriptor1_proxy(m_ptr)->elsize;
        }
        return detail::array_descriptor2_proxy(m_ptr)->elsize;
    }

解决方案

所以这里的解决方案有两种:

  1. 升级pybind11版本,重新编译程序。
  2. 锁定numpy版本到2.0以下。

教训

在不确定的情况下,python的依赖在测试通过后,最好锁定版本,避免出现因为版本不兼容导致的问题。

有兴趣请关注我的微信公众号:码哥日常,码农和码农娃的日常经验分享。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值