本文介绍了错误:没有匹配的函数可以调用‘pybind11 :: buffer_info :: buffer_info的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我正在尝试使用pybind11cppimport包装使用Armadillo库的c ++函数.但是,当我尝试做一些简单的事情(例如矩阵乘法)时,会出现以下错误.

I'm trying to wrap a c++ function that uses Armadillo library using pybind11 and cppimport. But when I try to do something simple like matrix multiplication I get the following error.

error: no matching function for call to ‘pybind11::buffer_info::buffer_info(double*, long unsigned int, std::__cxx11::string, int, <brace-enclosed initializer list>, <brace-enclosed initializer list>)’
      );
      ^
    In file included from /home/muah/anaconda3/envs/ising/include/python3.6m/pybind11/pytypes.h:13:0,
                     from /home/muah/anaconda3/envs/ising/include/python3.6m/pybind11/cast.h:13,
                     from /home/muah/anaconda3/envs/ising/include/python3.6m/pybind11/attr.h:13,
                     from /home/muah/anaconda3/envs/ising/include/python3.6m/pybind11/pybind11.h:43,
                     from /home/muah/Music/cpp2py/.rendered.code.cpp:3:
    /home/muah/anaconda3/envs/ising/include/python3.6m/pybind11/buffer_info.h:83:5: note: candidate: pybind11::buffer_info::buffer_info(pybind11::buffer_info::private_ctr_tag, void*, pybind11::ssize_t, const string&, pybind11::ssize_t, pybind11::detail::any_container<long int>&&, pybind11::detail::any_container<long int>&&)
         buffer_info(private_ctr_tag, void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim,
         ^~~~~~~~~~~
    /home/muah/anaconda3/envs/ising/include/python3.6m/pybind11/buffer_info.h:83:5: note:   candidate expects 7 arguments, 6 provided
    /home/muah/anaconda3/envs/ising/include/python3.6m/pybind11/buffer_info.h:59:5: note: candidate: pybind11::buffer_info::buffer_info(pybind11::buffer_info&&)
         buffer_info(buffer_info &&other) {

这是犰狳垫到numpy反之亦然之间转换的代码.

This is the code for conversions between armadillo mat to numpy vice versa.

#pragma once
#include <armadillo>
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>

namespace py=pybind11;

typedef py::array_t<double, py::array::f_style | py::array::forcecast> pyarr_d;

inline
arma::mat py_to_mat(pyarr_d& pmat)
{
    py::buffer_info info = pmat.request();
    arma::mat amat;
    if(info.ndim == 1) {
        amat = arma::mat(reinterpret_cast<double*>(info.ptr),info.shape[0],1);
    } else {
        amat = arma::mat(reinterpret_cast<double*>(info.ptr),info.shape[0],info.shape[1]);
    }
    return amat;
}


inline
py::array_t<double> mat_to_py(arma::mat &mat)
{
    py::buffer_info buffer(
        mat.memptr(),
        sizeof(double),
        py::format_descriptor<double>::format(),
        2,
        { mat.n_rows, mat.n_cols },
        { sizeof(double), sizeof(double) * mat.n_rows }
    );
    return py::array_t<double>(buffer);
}

这是c ++函数:

<%
cfg['compiler_args'] = ['-std=c++11', '-larmadillo']
setup_pybind11(cfg)
%>

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <armadillo>
#include "py2arma.hpp"

namespace py = pybind11;


py::array matrix_mul(pyarr_d a, pyarr_d b)
{
    arma::mat A = py_to_mat(a);
    arma::mat B = py_to_mat(b);
    arma::mat C = A * B;
    return mat_to_py(C);
}


PYBIND11_PLUGIN(code)
{
    py::module m("code", "lala");
    m.def("matrix_mul",(py::array(*)(pyarr_d,pyarr_d))&matrix_mul);
    return m.ptr();
}

这是python函数:

This is the python function:

import cppimport
import numpy as np

code = cppimport.imp("code")

if __name__ == '__main__':
    xs = np.random.rand(3,3)
    ys = np.random.rand(3,1)

    py_mul = np.dot(xs, ys)
    cpp_mul = code.matrix_mul(xs, ys)
    print(py_mul)
    print(cpp_mul)

此链接包含完整的堆栈跟踪: https://pastebin.com/XuKyQDMQ

This link contains the full stack-trace: https://pastebin.com/XuKyQDMQ

我不明白此错误的含义.如何解决此问题,我是否正确进行了转换?

I don't understand what this error means. How to fix this, am I doing the conversions correctly ?

要解决问题,请在矩阵形状之前添加py :: detail :: any_container并跨过buffer_info的一部分.并将mat_to_py函数的类型从py::array更改为pyarr_d.

To fix the problems, add py::detail::any_container before matrix shape and strides part of buffer_info. And change the type of mat_to_py function from py::array to pyarr_d.

这解决了代码中的所有问题.

This fixes all the issues with the code.

推荐答案

从上述注释中查找,似乎是由于回溯中的此代码段(第59行)造成的:

From tracing from the above comments, seems like it's due to this snippet from your backtrace (line 59):

/home/muah/anaconda3/envs/ising/include/python3.6m/pybind11/buffer_info.h:28:5: note: candidate: pybind11::buffer_info::buffer_info(void*, pybind11::ssize_t, const string&, pybind11::ssize_t, pybind11::detail::any_container<long int>, pybind11::detail::any_container<long int>) buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, ^~~~~~~~~~~/home/muah/anaconda3/envs/ising/include/python3.6m/pybind11/buffer_info.h:28:5: note: no known conversion for argument 6 from ‘<brace-enclosed initializer list>’ to ‘pybind11::detail::any_container<long int>’

/home/muah/anaconda3/envs/ising/include/python3.6m/pybind11/buffer_info.h:28:5: note: candidate: pybind11::buffer_info::buffer_info(void*, pybind11::ssize_t, const string&, pybind11::ssize_t, pybind11::detail::any_container<long int>, pybind11::detail::any_container<long int>) buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, ^~~~~~~~~~~/home/muah/anaconda3/envs/ising/include/python3.6m/pybind11/buffer_info.h:28:5: note: no known conversion for argument 6 from ‘<brace-enclosed initializer list>’ to ‘pybind11::detail::any_container<long int>’

我的建议是通过首先为这些参数明确构造py::any_container<size_t>(...)来完成这项工作,这将帮助您缩小推断出错的地方.也许是由于Armadillo的尺寸与pybind11中的ssize_t之间不匹配?

My suggestion would be to make this work by first explicitly constructing py::any_container<size_t>(...) for those arguments, which will help you narrow down where inference is going awry. Perhaps it's due to a mismatch between Armadillo's dimensions and ssize_t from pybind11?

这篇关于错误:没有匹配的函数可以调用‘pybind11 :: buffer_info :: buffer_info的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 15:06