pybind / pybind/pybind11

[BUG]: Sparse Eigen type caster assumes that the index and value arrays are mutable

Open
#5,431 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

triage
Dominant language
C++
Stars
18k
Forks
2.3k
Avg merge
5d 17h
Merged PRs (30d)
10

Description

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

2.13.6

Problem description

The type caster for sparse matrices assumes that the arrays inside of the csc_matrix class are mutable. This is not necessarily the case (for example, they could be initialized by Eigen::Ref<const Eigen::VectorXi> casted to a NumPy array).

https://github.com/pybind/pybind11/blob/75e48c5f959b4f0a49d8c664e059b6fb4b497102/include/pybind11/eigen/matrix.h#L680-L687

Reproducible example code
    Eigen::VectorXd values(2);
    Eigen::VectorXi inner_idx(2), outer_ptr(3);
    values << 11, 22;
    inner_idx << 0, 1;
    outer_ptr << 0, 1, 2;
    auto csc_array = py::module_::import("scipy.sparse").attr("csc_array");
#if 1
    using const_vec_i_ref = Eigen::Ref<const Eigen::VectorXi>;
    using const_vec_d_ref = Eigen::Ref<const Eigen::VectorXd>;
    auto matrix_args      = py::make_tuple(const_vec_d_ref{values}, const_vec_i_ref{inner_idx},
                                           const_vec_i_ref{outer_ptr}); // does not work
#else
    auto matrix_args = py::make_tuple(values, inner_idx, outer_ptr); // works
#endif
    auto shape        = ("shape"_a = py::make_tuple(2, 2));
    auto matrix       = csc_array(std::move(matrix_args), std::move(shape));
    auto eigen_matrix = py::cast<Eigen::SparseMatrix<double>>(matrix);
    //                      ↑ ValueError: array is not writeable
    std::cout << eigen_matrix << std::endl;
Is this a regression? Put the last known working version here if it is.

Not a regression

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in include/pybind11/eigen/matrix.h around lines 680-687, then reproduce the provided scipy.sparse csc_array example using const Eigen::Ref arrays. The work is complete when casting a matrix built from non-writeable index and value arrays succeeds while the existing mutable-array case continues to work.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp, python
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.