Skip to content

Conversation

@ManifoldFR
Copy link
Contributor

@ManifoldFR ManifoldFR commented Mar 26, 2025

Hi,

I've just encountered an issue when the user passes a scipy sparse matrix with unsorted inner indices to Eigen.
This issue manifests in two ways:

  • an eigen_assert() is triggered when compiling in Debug,
  • or you can get incorrect values in your converted sparse matrix.

It seems until relatively recently it was not explicitly stated that Eigen::Map<SparseMatrix> objects expect the inner indices to be sorted. This issue really pops up when you try to evaluate the map into a plain sparse matrix object, like here:

value = SparseMap(rows, cols, nnz, outer_indices.data(), inner_indices.data(), values.data());

Eigen's master branch has a nice a.sortInnerIndices() function and some helpers to check if the indices are sorted, for compressed storage types. For Eigen's released version (3.4.0 and below), for now I've added a call to SciPy's API to sort the indices of the passed sparse matrix.

This might be relevant for #782.
Also related: stack-of-tasks/eigenpy#538 (in Boost.Python world)

@ManifoldFR ManifoldFR force-pushed the topic/scipy-sparse-unsorted branch 2 times, most recently from cb9486a to 7e7e4e8 Compare March 26, 2025 18:31
@ManifoldFR ManifoldFR marked this pull request as ready for review March 26, 2025 18:31
@ManifoldFR ManifoldFR force-pushed the topic/scipy-sparse-unsorted branch from 7e7e4e8 to 455f0fc Compare April 4, 2025 13:35
@wjakob
Copy link
Owner

wjakob commented Apr 7, 2025

Actually, I am wondering about something here: isn't it unsafe to use mapped_matrix.sortInnerIndices(); because it will modify the contents of the mapped index/value arrays? (which are owned by SciPy/NumPy). In that case, the safer alternative would seem to be to use the SciPy function.

The advantage of this is also that we can avoid sorting if the flag is True. It seems to me that the Eigen sortInnerIndices function in contrast doesn't know if the indices are sorted and will have to conservatively invoke a sort routine at some cost.

@ManifoldFR
Copy link
Contributor Author

Actually, I am wondering about something here: isn't it unsafe to use mapped_matrix.sortInnerIndices(); because it will modify the contents of the mapped index/value arrays? (which are owned by SciPy/NumPy). In that case, the safer alternative would seem to be to use the SciPy function.

You might be right, we would be modifying SciPy's indices array from mapped data in C++, which SciPy itself might not expect, whereas calling the SciPy function would be safer (and would call whatever internal code the SciPy function has).

The advantage of this is also that we can avoid sorting if the flag is True. It seems to me that the Eigen sortInnerIndices function in contrast doesn't know if the indices are sorted and will have to conservatively invoke a sort routine at some cost.

I hadn't looked at the code that much in-depth. I think we can go with your suggestion.

@wjakob
Copy link
Owner

wjakob commented Apr 7, 2025

Thanks!

@wjakob wjakob merged commit f9dc481 into wjakob:master Apr 7, 2025
34 checks passed
@ManifoldFR ManifoldFR deleted the topic/scipy-sparse-unsorted branch April 8, 2025 12:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants