-
Notifications
You must be signed in to change notification settings - Fork 89
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
Re-ordering matrices in Ginkgo #346
Comments
I prefer to use gko::Array. If someone really needs the real permutation matrix, conversion from array to Coo is easier than the other direction. |
I think permutation can help in the solver, for example the RCM re-ordering should reduce the bandwidth of a sparse matrix and this could be beneficial for generation of good preconditioners for example in the case of ParILU or in the case of the block detection in the case of the Block Jacobi preconditioner. Of course, the benefit of using re-ordering compared to the cost of it is something that is not yet clear. |
I prefer to not expose any // The permutation computed by the reordering algorithm.
IndexType *get_permutation() const { ... }
// The inverse permutation computed by the reordering algorithm.
IndexType *get_inverse_permutation() const { ... } The way you wrote it, you would need to create a new Array and copy the data at every access (I guess you meant a pointer to an Array, but I also think that that would be bad). Currently, everything that a LinOp (Solver, preconditioner, matrix, ...) returns to the user is another LinOp, and breaking that pattern could lead to confusion, which is why I would prefer a new matrix LinOp (maybe // A is the matrix that you want to permutate
// P is the permutation LinOp, storing the permutation information
auto B = matrix::Csr<>::create(exec);
P->apply(A, B);
// Now, B stores `P A`, which is the permutated matrix A That would also work well with your proposition of a reordering interface (2.) similar to the preconditioner one (all preconditioners are also LinOps). However, there we should not use the |
The other option that is also possible and is also probably easier to implement is using a You can check out how it looks in this branch implemented for Dense- permute-interface. This currently takes in an Array, but I guess it should be possible to have it as a LinOp which contains the permutation array as you suggest. |
I would prefer a version that uses CRTP, so you would return the same matrix type it had previously. That way, you could directly use all the functionality again without the need for a template <typename ResultType, typename IndexType>
class Permutable {
public:
virtual ~Permutable() = default;
virtual std::unique_ptr<ResultType> row_permute(
const IndexType *permutation_indices, size_type size) const = 0;
virtual std::unique_ptr<ResultType> column_permute(
const IndexType *permutation_indices, size_type size) const = 0;
}; |
I am not an expert on bandwidth reduction but the GPS, Gibbs, Poole and Stockmeyer algorithm might be a faster option: "Initially the most widely used of the heuristics was the Reverse Cuthill-McKee algorithm (RCM), a modification by Alan George of the original algorithm developed by CutHill and McKee in 1969. In 1976 the GPS algorithm (named after its developers Gibbs, Poole and Stockmeyer) was proposed. On average GPS and RCM find solutions of relative equal quality, but GPS is up to ten times as fast." Source: http://ciprian-zavoianu.blogspot.com/2009/01/project-bandwidth-reduction.html |
@klausbu Just a quick note concerning the GPS algorithm:
Based on these two observations I don't expect GPS to significantly outperform RCM for parallel implementations, on large matrices. On the other hand, a spectral pseudoperipheral node finder might yield significant speedups, that's future-talk though. |
Aiming to reduce duplicate discussions, I'll close this one, but we have it referenced in #940 |
Reordering sparse matrices in Ginkgo.
Re-ordering a sparse matrix is quite an important algorithm to have. It can improve performance drastically particularly when some factorization routines are involved as in ParILU by reducing fill-in of the factors.
Some of the available re-ordering algorithms are:
METIS: Fill-in reducing re-ordering: This algorithm was designed to specifically reduce fill-in when factorized as the name suggests and is available within the METIS library. It uses the multi-level nested dissection paradigm to re-order the sparse matrix.
Approximate minimum degree reordering (AMD). An example of the implementation is in Suitesparse
Reverse-Cuthill Mckhee reordering (RCM). This reordering is generally used to reduce the bandwidth of a sparse matrix. RCM at Wikipedia.
Currently, I see the interface with something of this fashion (With the METIS fill reduce as an example):
Things to discuss:
The factory can take in a normal matrix(any format) and internally convert it into an adjacency matrix and generate a permutation which would be a vector(gko::Array) which would contain the required permutation mappings for each row.
Note: I guess if the first option(permutation vector) when abstracted as a LinOp would be equal to that of the permutation matrix and would not lose any elegance, so probably the way to go is storing the permutation as a vector(gko::Array).
Similar to a Preconditionable interface we have for Preconditioners when used within solvers, it could also make sense to add a Reorderable interface to reorder the matrices as a preprocessor step.
Infact, it is also possible to see the Reordering as a preconditioner and use it as such, but the demarcation of the concept could be lost here.
In general, when you re-order a sparse matrix involved with a solver, you would re-order the right hand side as well. The way this could be implemented efficiently also needs to be discussed.
Another aspect that probably needs to be considered is if there could be some reason one would want to stack the reorderings. In this case we would need to think about some kind of a composition of re-orderings.
A simple example of the metis fill reduce implementation can be found on the metis-reorder branch. It is a work in progress.
The text was updated successfully, but these errors were encountered: