error: no matching function for call to ‘pybind11::buffer_info::buffer_info
error: no matching function for call to ‘pybind11::buffer_info::buffer_info
我正在尝试使用 pybind11
和 cppimport
包装一个使用 Armadillo 库的 c++ 函数。但是当我尝试做一些简单的事情时,比如矩阵乘法,我得到了以下错误。
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) {
这是在 armadillo mat 和 numpy 之间进行转换的代码,反之亦然。
#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函数:
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)
这个 link 包含完整的堆栈跟踪:https://pastebin.com/XuKyQDMQ
我不明白这个错误是什么意思。如何解决这个问题,我是否正确地进行了转换?
编辑:要解决这些问题,请在矩阵形状和 buffer_info 的步长部分之前添加 py::detail::any_container。并将 mat_to_py
函数的类型从 py::array
更改为 pyarr_d
.
这修复了代码的所有问题。
从上述评论的追踪来看,似乎是由于您的回溯(第 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>’
我的建议是通过首先为这些参数显式构建 py::any_container<size_t>(...)
来完成这项工作,这将帮助您缩小推理出错的范围。可能是由于 Armadillo 的尺寸与 pybind11
的 ssize_t
不匹配?
我正在尝试使用 pybind11
和 cppimport
包装一个使用 Armadillo 库的 c++ 函数。但是当我尝试做一些简单的事情时,比如矩阵乘法,我得到了以下错误。
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) {
这是在 armadillo mat 和 numpy 之间进行转换的代码,反之亦然。
#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函数:
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)
这个 link 包含完整的堆栈跟踪:https://pastebin.com/XuKyQDMQ
我不明白这个错误是什么意思。如何解决这个问题,我是否正确地进行了转换?
编辑:要解决这些问题,请在矩阵形状和 buffer_info 的步长部分之前添加 py::detail::any_container。并将 mat_to_py
函数的类型从 py::array
更改为 pyarr_d
.
这修复了代码的所有问题。
从上述评论的追踪来看,似乎是由于您的回溯(第 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>’
我的建议是通过首先为这些参数显式构建 py::any_container<size_t>(...)
来完成这项工作,这将帮助您缩小推理出错的范围。可能是由于 Armadillo 的尺寸与 pybind11
的 ssize_t
不匹配?