Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
3 tasks done
tttapa opened this issue Nov 4, 2024 · 0 comments
Open
3 tasks done
Labels
triage New bug, unverified

Comments

@tttapa
Copy link
Contributor

tttapa commented Nov 4, 2024

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).

value = EigenMapSparseMatrix<Scalar,
Type::Flags &(Eigen::RowMajor | Eigen::ColMajor),
StorageIndex>(shape[0].cast<Index>(),
shape[1].cast<Index>(),
std::move(nnz),
outerIndices.mutable_data(),
innerIndices.mutable_data(),
values.mutable_data());

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

@tttapa tttapa added the triage New bug, unverified label Nov 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
triage New bug, unverified
Projects
None yet
Development

No branches or pull requests

1 participant