Skip to content

Fill in reduction with Cuthill-McKee ordering #182

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

Merged
merged 20 commits into from
Jan 22, 2020
Merged

Conversation

vbarrielle
Copy link
Collaborator

The Cuthill-McKee ordering permutes a symmetric sparse matrix such that its profile is reduced. This in turn implies less additional nonzeros in Cholesky factorizations.

This pull request adds the ability to compute this ordering and to apply it to a matrix.

It also adds the ability to visualize the nonzero pattern of a sparse matrix to check the profile reduction.

To have good example matrices, the ability to create the (graph) laplacian matrix of a triangle mesh has also been added.

Nested dissection is a method to find a good permutation on sparse
matrices representing loosely connected graphs. This kind of matrix is
common for differential operators on discrete manifolds such as triangle
meshes, or on tetrahedral meshes.
This will be nice to visualize the effect of nested dissection.
Now the nested dissection knows the size of all parts during
its traversal, allowing it to stop the BFS early enough and ensure it
creates equal splits.
Previous fix would record the correct permutation, but would not
ensure the nested_dissection calls were issued with the components taken
into account. This patch is a simple way to fix that: each time a
connected component is identified, our nested dissection is run on it.
The gain is quite interesting when seen on triangle meshes.
This will enable saving an image to ease visualization.
We only need to be able to render pngs in our example.
Need to read more on the theory before implementing a good nested
dissection. Cuthill-McKee is already useful though. I'm explicitly
keeping the nested dissection experiments in the history in case it
turns out to be useful later on.
@vbarrielle
Copy link
Collaborator Author

CI fails because of a compiler regression apparently, see bluss/matrixmultiply#50 and rust-lang/rust#67743

I'll wait for the fix I guess.

@vbarrielle vbarrielle merged commit 72d7818 into master Jan 22, 2020
@lksriemer
Copy link
Contributor

Hey @vbarrielle :)
I thought I might drop in and share some thoughts on this implementation of the CM algorithm. I am currently researching it, and what better way to do that would there be, than to discuss it.

From the changes I can't quite see, if you have considered implementing the reverse Cuthill-Mckee algorithm instead? It is typically at least as good as the 'normal' ordering, and easy to obtain - simply reverse the ordering.

One question: Why do you not check if a vertex is unvisited before pushing to neighbors, then immediately marking it as visited afterwards? I didn't benchmark it, but that does seem like doing the same thing as skipping those vertices afterwards, and could save a lot of work.

Also, you seem to have choosen to always select a vertex of minimum degree as starting vertex. I believe it is state of the art to instead choose a pseudoperipheral vertex. Or did you decide that is too costly to compute for your users typical use cases?

@lksriemer
Copy link
Contributor

Some more remarks- I'm really sorry if I am wasting your time.

You sort using the stable method. Why not use sort_unstable_by_key instead, if stability is no concern? That should be a performance boost, though I haven't measured it. Also, really tiny vecs could be sorted with sorting networks, as those are really common for sparse matrices, I guess. That would require some serious implementation and benchmarking work though.

Some background: I have tweaked my rust implementation of this algorithm over the last few days, and would just like to share some insights I gained, with a commonly used crate.

I could prepare a PR, but I am not familiar with this codebase. Some mentoring would be required.

@vbarrielle
Copy link
Collaborator Author

Hello @LukiRe, thanks for your feedback, it will be particularly interesting if you're researching fill-in reducing algorithms. The main answer to all you questions would be that this PR was a first step towards understanding this topic which is new to me. Here are detailed answers to your questions:

  • I have considered implementing the reverse CM algorithm, I simply did not take the time to do it. Feel free to do so if you wish.
  • I think the choices I made regarding visited vertices checking were mostly made to have a simple implementation, so it's quite possible I missed some optimization opportunities like the one you suggest. This should be checked and banchmarked at some point yes.
  • I'm probably less aware of the state of the art, so I did not know the state of the art was choosing a pseudoperipheral vertex. Do you have some references I could read on the topic?
  • I've recently noticed on another branch that I should be using unstable sorting, so I will convert most instances of slice::sort to slice::unstable_sort.

If you want to open a PR to share your own implementation, I'm definetely open to it, and I can help you around with the codebase. Simply open a new issue with you questions.

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