-
Notifications
You must be signed in to change notification settings - Fork 88
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
Fix ilu preconditioner and extended solver #353
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some comments and questions
@@ -134,7 +141,9 @@ class Bicgstab : public EnableLinOp<Bicgstab<ValueType>>, | |||
parameters_{factory->get_parameters()}, | |||
system_matrix_{std::move(system_matrix)} | |||
{ | |||
if (parameters_.preconditioner) { | |||
if (parameters_.generated_preconditioner) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure, but I think in some cases you would like to regenerate the preconditioner and pass in a LinOpFactory
. I am not sure if this strict dependency is suitable.
I would prefer a parameter, something like always_use_generated_preconditioner
or something like that. I know that this increases the list of parameters, but I am not sure if there is another way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want the preconditioner to be generated, you could simply not use the with_generated_preconditioner
. If you provide both, one has to be chosen above another. Adding another factory parameter would not really make the situation better since you could just choose to give one or the other instead.
We could resolve this by providing a set_preconditioner()
function for all solvers, however, that can lead undefined behavior when a preconditioner is set while an apply
is running (also, one preconditioner is generated in the beginning without being used).
Despite that, it would allow you to use the same factory for a lot of solvers, while allowing you to change the preconditioner. The downsides are still totally manageable (it should be clear that changing the preconditioner while calculating is a bad idea).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the way it has been implemented currently is good enough, though a set_preconditioner
method might be useful as well. I dont think there is a problem of setting the preconditioner when the apply is running, because each apply call is synchronous (?), atleast currently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but the problem is that we might want to go asynchronous at some point, and we can't simply take this functionality back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just for reference: After the discussion, we agreed that I should add both the factory parameter (which is already implemented) and the set_preconditioner
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess not every solver has the "set_preconditioner" function - i.e. only "preconditionable" objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that is how I plan to implement it.
But I will also add a set_solver
for Iterative Refinement since the interface there is very much like the ones for preconditioner.
Codecov Report
@@ Coverage Diff @@
## develop #353 +/- ##
===========================================
+ Coverage 97.96% 97.99% +0.02%
===========================================
Files 256 256
Lines 18972 19216 +244
===========================================
+ Hits 18586 18830 +244
Misses 386 386
Continue to review full report at Codecov.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Apparently, this has now a bit too much duplicated code for SonarCloud. I could resolve it by making the interface Preconditionable a MixIn, but I think that would break our interface. I could also add a MixIn just for this one function, but for these few lines, I don't think it is worth it. |
@thoasm yes, I was also wondering about the same thing. In general, the interface would stay the same though as you would still have I also don't think it's very much worth it, I thought it would also reduce a lot of tests but in fact that only removes one out of the four tests you added for every solver, which is already something I guess. |
If we would change the Just adding the |
@tcojean It would also not really reduce the amount of tests. For example, |
Actually rather than a mixin, can we not make Preconditionable a type which solvers inherit from? That is what I was rather thinking of, in fact. We anyway already have |
Yes, we can do that. The only problem we would have is that we could not check during the I can definitively make this change. The reason why I did not is that I wanted to throw the error as soon as I detect it, so it is less searching overhead for any user that may encounter that problem. |
As I was saying, I don't think it's very useful since it removes a test per solver and remove the |
All preconditioner must have a factory of type `LinOpFactory` in order to get accepted as a preconditioner in any solver. This is now possible with ILU (a test was added to ensure that). However, as part of that adaptation, it is no longer possible to use `generate` with both L and U separately. Now, either a matrix can be passed, which will be factorized with ParIlu internally, or a composition can be passed, consisting of both L and U (in that order).
This allows us to generate a preconditioner once and use it in multiple solvers without the need to generate it again. Providing a factory is still possible as it was. However, if both a factory and a generated preconditioner is given, the generated preconditioner is used, and the factory ignored.
`set_preconditioner` can be use to change the preconditioner of a solver after it was already created & generated. An error is thrown when the newly set preconditioner has wrong dimensions. Implementation of the `set_preconditioner` and tests (including the throwing) are added for all respective solvers.
Implementation of `get_preconditioner` and `set_preconditioner` are moved from the solver to the class `Preconditionable`. Both functions are now no longer `virtual` to allow for inlining. Additionally, LowerTrs and UpperTrs no longer inherit from `Preconditionable` since they do not use the preconditioner inside the apply.
ae5c83b
to
c380ba8
Compare
I talked with @pratikvn, and he is in favor of putting the implementation into In my latest commit, I do exactly that. We might have to discuss if it was OK to remove the What do you think of these changes, @tcojean? I am fine with them, but I would also not mind to go back to the previous version (which is a trade-off between having an error thrown faster and having less code duplication, especially when creating another solver). |
@thoasm technically, I think you may consider removing the |
@tcojean there I am not 100% sure about, but I think it might be better to add it again, just to be sure. |
- Make funktions in `Preconditionable` `virtual` - Remove `generated_preconditioner` factory parameter in LowerTrs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
@tcojean I changed the functions |
@thoasm Sure that is fine. |
The Ginkgo team is proud to announce the new minor release of Ginkgo version 1.1.0. This release brings several performance improvements, adds Windows support, adds support for factorizations inside Ginkgo and a new ILU preconditioner based on ParILU algorithm, among other things. For detailed information, check the respective issue. Supported systems and requirements: + For all platforms, cmake 3.9+ + Linux and MacOS + gcc: 5.3+, 6.3+, 7.3+, 8.1+ + clang: 3.9+ + Intel compiler: 2017+ + Apple LLVM: 8.0+ + CUDA module: CUDA 9.0+ + Windows + MinGW and CygWin: gcc 5.3+, 6.3+, 7.3+, 8.1+ + Microsoft Visual Studio: VS 2017 15.7+ + CUDA module: CUDA 9.0+, Microsoft Visual Studio + OpenMP module: MinGW or CygWin. The current known issues can be found in the [known issues page](https://github.com/ginkgo-project/ginkgo/wiki/Known-Issues). Additions: + Upper and lower triangular solvers ([#327](#327), [#336](#336), [#341](#341), [#342](#342)) + New factorization support in Ginkgo, and addition of the ParILU algorithm ([#305](#305), [#315](#315), [#319](#319), [#324](#324)) + New ILU preconditioner ([#348](#348), [#353](#353)) + Windows MinGW and Cygwin support ([#347](#347)) + Windows Visual studio support ([#351](#351)) + New example showing how to use ParILU as a preconditioner ([#358](#358)) + New example on using loggers for debugging ([#360](#360)) + Add two new 9pt and 27pt stencil examples ([#300](#300), [#306](#306)) + Allow benchmarking CuSPARSE spmv formats through Ginkgo's benchmarks ([#303](#303)) + New benchmark for sparse matrix format conversions ([#312](https://github.com/ginkgo-project/ginkgo/issues/312)[#317](https://github.com/ginkgo-project/ginkgo/issues/317)) + Add conversions between CSR and Hybrid formats ([#302](#302), [#310](#310)) + Support for sorting rows in the CSR format by column idices ([#322](#322)) + Addition of a CUDA COO SpMM kernel for improved performance ([#345](#345)) + Addition of a LinOp to handle perturbations of the form (identity + scalar * basis * projector) ([#334](#334)) + New sparsity matrix representation format with Reference and OpenMP kernels ([#349](#349), [#350](#350)) Fixes: + Accelerate GMRES solver for CUDA executor ([#363](#363)) + Fix BiCGSTAB solver convergence ([#359](#359)) + Fix CGS logging by reporting the residual for every sub iteration ([#328](#328)) + Fix CSR,Dense->Sellp conversion's memory access violation ([#295](#295)) + Accelerate CSR->Ell,Hybrid conversions on CUDA ([#313](#313), [#318](#318)) + Fixed slowdown of COO SpMV on OpenMP ([#340](#340)) + Fix gcc 6.4.0 internal compiler error ([#316](#316)) + Fix compilation issue on Apple clang++ 10 ([#322](#322)) + Make Ginkgo able to compile on Intel 2017 and above ([#337](#337)) + Make the benchmarks spmv/solver use the same matrix formats ([#366](#366)) + Fix self-written isfinite function ([#348](#348)) + Fix Jacobi issues shown by cuda-memcheck Tools and ecosystem: + Multiple improvements to the CI system and tools ([#296](#296), [#311](#311), [#365](#365)) + Multiple improvements to the Ginkgo containers ([#328](#328), [#361](#361)) + Add sonarqube analysis to Ginkgo ([#304](#304), [#308](#308), [#309](#309)) + Add clang-tidy and iwyu support to Ginkgo ([#298](#298)) + Improve Ginkgo's support of xSDK M12 policy by adding the `TPL_` arguments to CMake ([#300](#300)) + Add support for the xSDK R7 policy ([#325](#325)) + Fix examples in html documentation ([#367](#367))
The Ginkgo team is proud to announce the new minor release of Ginkgo version 1.1.0. This release brings several performance improvements, adds Windows support, adds support for factorizations inside Ginkgo and a new ILU preconditioner based on ParILU algorithm, among other things. For detailed information, check the respective issue. Supported systems and requirements: + For all platforms, cmake 3.9+ + Linux and MacOS + gcc: 5.3+, 6.3+, 7.3+, 8.1+ + clang: 3.9+ + Intel compiler: 2017+ + Apple LLVM: 8.0+ + CUDA module: CUDA 9.0+ + Windows + MinGW and Cygwin: gcc 5.3+, 6.3+, 7.3+, 8.1+ + Microsoft Visual Studio: VS 2017 15.7+ + CUDA module: CUDA 9.0+, Microsoft Visual Studio + OpenMP module: MinGW or Cygwin. The current known issues can be found in the [known issues page](https://github.com/ginkgo-project/ginkgo/wiki/Known-Issues). ### Additions + Upper and lower triangular solvers ([#327](#327), [#336](#336), [#341](#341), [#342](#342)) + New factorization support in Ginkgo, and addition of the ParILU algorithm ([#305](#305), [#315](#315), [#319](#319), [#324](#324)) + New ILU preconditioner ([#348](#348), [#353](#353)) + Windows MinGW and Cygwin support ([#347](#347)) + Windows Visual Studio support ([#351](#351)) + New example showing how to use ParILU as a preconditioner ([#358](#358)) + New example on using loggers for debugging ([#360](#360)) + Add two new 9pt and 27pt stencil examples ([#300](#300), [#306](#306)) + Allow benchmarking CuSPARSE spmv formats through Ginkgo's benchmarks ([#303](#303)) + New benchmark for sparse matrix format conversions ([#312](https://github.com/ginkgo-project/ginkgo/issues/312)[#317](https://github.com/ginkgo-project/ginkgo/issues/317)) + Add conversions between CSR and Hybrid formats ([#302](#302), [#310](#310)) + Support for sorting rows in the CSR format by column idices ([#322](#322)) + Addition of a CUDA COO SpMM kernel for improved performance ([#345](#345)) + Addition of a LinOp to handle perturbations of the form (identity + scalar * basis * projector) ([#334](#334)) + New sparsity matrix representation format with Reference and OpenMP kernels ([#349](#349), [#350](#350)) ### Fixes + Accelerate GMRES solver for CUDA executor ([#363](#363)) + Fix BiCGSTAB solver convergence ([#359](#359)) + Fix CGS logging by reporting the residual for every sub iteration ([#328](#328)) + Fix CSR,Dense->Sellp conversion's memory access violation ([#295](#295)) + Accelerate CSR->Ell,Hybrid conversions on CUDA ([#313](#313), [#318](#318)) + Fixed slowdown of COO SpMV on OpenMP ([#340](#340)) + Fix gcc 6.4.0 internal compiler error ([#316](#316)) + Fix compilation issue on Apple clang++ 10 ([#322](#322)) + Make Ginkgo able to compile on Intel 2017 and above ([#337](#337)) + Make the benchmarks spmv/solver use the same matrix formats ([#366](#366)) + Fix self-written isfinite function ([#348](#348)) + Fix Jacobi issues shown by cuda-memcheck ### Tools and ecosystem improvements + Multiple improvements to the CI system and tools ([#296](#296), [#311](#311), [#365](#365)) + Multiple improvements to the Ginkgo containers ([#328](#328), [#361](#361)) + Add sonarqube analysis to Ginkgo ([#304](#304), [#308](#308), [#309](#309)) + Add clang-tidy and iwyu support to Ginkgo ([#298](#298)) + Improve Ginkgo's support of xSDK M12 policy by adding the `TPL_` arguments to CMake ([#300](#300)) + Add support for the xSDK R7 policy ([#325](#325)) + Fix examples in html documentation ([#367](#367)) Related PR: #370
This PR contains two changes (each with its own commit):
1. Make the ILU preconditioner usable as a preconditioner.
The problem is that each solver takes a
LinOpFactory
as a preconditioner, which the ILU was not. It was a self-written class instead ofLinOpFactory
, so it was possible to generate it with either one parameter (a composition), or two factors (L and U). However, that also meant that it was not possible to hand over a factory (withwith_preconditioner
) to any solver, making it useless as a preconditioner.Now, it is no longer possible to take two parameters, however, it is still possible to just pass a
gko::Composition<value_type>
with first L and then U. Also, more importantly, it is now possible to use it as a regular preconditioner (a test also proves this now).2. Add the possibility to give a solver factory an already generated preconditioner
Since some preconditioners are expensive to build, it can be handy to generate it once, and use it with multiple solvers at the same time. To enable this feature, each solver was now given the factory parameter
generated_preconditioner
. If this parameter is set, the given preconditioner is used, even ifwith_preconditioner
(specifying a factory of a preconditioner) was used (order of importance:generated_preconditioner
>preconditioner
> identity matrix).This PR allows to share the same preconditioner in many different solvers, while it also allows to use a preconditioner generated for matrix
A
with a solver generated for matrixB
.Also, the function
set_preconditioner(std::shared_ptr<const LinOp>)
was added to the abstract classPreconditionable
, and implemented in all solvers. This function allows to set the preconditioner after the solver was already generated.