diff --git a/include/nanobind/eigen/sparse.h b/include/nanobind/eigen/sparse.h index 96442161..f253feb5 100644 --- a/include/nanobind/eigen/sparse.h +++ b/include/nanobind/eigen/sparse.h @@ -183,15 +183,12 @@ struct type_caster, enable_if_t>> { } if (object data_o = obj.attr("data"); !data_caster.from_python(data_o, flags, cleanup)) return false; - ScalarNDArray& values = data_caster.value; if (object indices_o = obj.attr("indices"); !indices_caster.from_python(indices_o, flags, cleanup)) return false; - StorageIndexNDArray& inner_indices = indices_caster.value; if (object indptr_o = obj.attr("indptr"); !indptr_caster.from_python(indptr_o, flags, cleanup)) return false; - StorageIndexNDArray& outer_indices = indptr_caster.value; object shape_o = obj.attr("shape"), nnz_o = obj.attr("nnz"); try { diff --git a/tests/test_eigen.cpp b/tests/test_eigen.cpp index 8e555546..a3e32660 100644 --- a/tests/test_eigen.cpp +++ b/tests/test_eigen.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace nb = nanobind; @@ -166,8 +167,16 @@ NB_MODULE(test_eigen_ext, m) { assert(!m.isCompressed()); return m.markAsRValue(); }); + // This function doesn't appear to be called in tests/test_eigen.py m.def("sparse_complex", []() -> Eigen::SparseMatrix> { return {}; }); + m.def("sparse_map_c", [](const Eigen::Map &) { }); + m.def("sparse_map_r", [](const Eigen::Map &) { }); + m.def("sparse_update_map_to_zero_c", [](nb::object obj) { + Eigen::Map c = nb::cast>(obj); + for (int i = 0; i < c.nonZeros(); ++i) { c.valuePtr()[i] = 0; } + }); + /// issue #166 using Matrix1d = Eigen::Matrix; try { diff --git a/tests/test_eigen.py b/tests/test_eigen.py index 4e402ee3..0f15e576 100644 --- a/tests/test_eigen.py +++ b/tests/test_eigen.py @@ -374,3 +374,25 @@ def test14_single_element(): a = np.array([[1]], dtype=np.uint32) assert a.ndim == 2 and a.shape == (1, 1) t.addMXuCC(a, a) + +@needs_numpy_and_eigen +def test15_sparse_map(): + pytest.importorskip("scipy") + import scipy + c = scipy.sparse.csc_matrix([[1, 0], [0, 1]], dtype=float) + # These should be copy-less + t.sparse_map_c(c) + r = scipy.sparse.csr_matrix([[1, 0], [0, 1]], dtype=float) + t.sparse_map_r(r) + # These should be ok, but will copy(?) + t.sparse_map_c(r) + t.sparse_map_r(c) + + t.sparse_update_map_to_zero_c(c); + # check that c.sum() is zero now + assert c.sum() == 0 + + + + +