pybind / pybind11

Seamless operability between C++11 and Python
https://pybind11.readthedocs.io/
Other
15.08k stars 2.05k forks source link

[BUG]: Function with Param of type `const Eigen::VectorXd&` causes "windows fatal exception: access violation" on Windows #5181

Open huweiATgithub opened 1 week ago

huweiATgithub commented 1 week ago

Required prerequisites

What version (or hash if on master) of pybind11 are you using?

v2.10.4

Problem description

When calling function with parameter const Eigen::VectorXd&, it fails with "windows fatal exception: access violation" on Windows, compiled with VS2022, Python 3.12, and Pybind v2.10.4.

However, the example works well with Python 3.10 + VS2019 + Pybind v2.10.4. Besides, it also works well in Python 3.12 + VS2022 + Pybind current stable branch.

I know from the Documentation that it recommend using Eigen::Ref for reference. Using Eigen::Ref, Python 3.12 + VS2022 + Pybind v2.10.4 also works.

That said, using either Pybind current stable branch or Eigen::Ref can make it work.

I have been struggling on this issue for a while.

I want to understand how things go wrong:

Reproducible example code

#include <pybind11/operators.h>
#include <pybind11/pybind11.h>
#include <pybind11/functional.h>
#include <pybind11/eigen.h>
#include <pybind11/stl.h>
#include <vector>
#include <Eigen/Eigen>

namespace py = pybind11;

class ArrayDynamic {
 using Vector =Eigen::VectorXd;

 private:
  Vector data_;

 public:
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW

  ArrayDynamic() = default;
  virtual ~ArrayDynamic() = default;

  explicit ArrayDynamic(size_t dim) { data_.resize(dim); }
  auto data() const -> const Vector& { return data_; }
  auto data() -> Vector& { return data_; }
};

PYBIND11_MODULE(promote, m)
{
    auto math = m.def_submodule("math");
    py::class_<ArrayDynamic>(math, "ArrayDynamic")
        .def(py::init<size_t>(), "Create an array of given size.", py::arg("dim"))
        .def("data", py::overload_cast<>(&ArrayDynamic::data), py::return_value_policy::reference_internal, "internal")
        .def( "set_data",
            [](ArrayDynamic& array,
               const Eigen::VectorXd& data)
            {
                array.data() = data;
            },
            "Set data.");
}

For a full example, see https://github.com/huweiATgithub/pybind_fail_example



### Is this a regression? Put the last known working version here if it is.

Not a regression