-
Notifications
You must be signed in to change notification settings - Fork 86
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
Add a uniform coarse generation algorithm #1526
base: develop
Are you sure you want to change the base?
Conversation
|
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #1526 +/- ##
===========================================
- Coverage 91.04% 89.78% -1.27%
===========================================
Files 700 707 +7
Lines 56996 57487 +491
===========================================
- Hits 51894 51612 -282
- Misses 5102 5875 +773 ☔ View full report in Codecov by Sentry. |
0537b1e
to
2db6399
Compare
Especially focusing on distributed, I think if we include this, we should try to support at least 2D and maybe 3D coarsening ( |
Maybe it makes sense to split the |
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.
As I mentioned, I think the UniformCoarsening
class should be split up. Other than that I have mostly smaller comments.
parameters_.coarse_skip, &coarse_rows_)); | ||
|
||
gko::dim<2>::dimension_type coarse_dim = | ||
(coarse_rows_.get_size() + parameters_.coarse_skip - 1) / |
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.
ceildiv
.with_criteria(iter_stop, tol_stop) | ||
.on(exec)); | ||
if (coarse_type == std::string("uniform")) { | ||
std::cout << "Using Uniform coarsening" << std::endl; |
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 don't think the output is necessary, since that information is already part of the program arguments.
.on(exec)); | ||
if (coarse_type == std::string("uniform")) { | ||
std::cout << "Using Uniform coarsening" << std::endl; | ||
multigrid_gen = gko::share(mg::build() |
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.
it shouldn't generate the MG twice.
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.
This just builds the factories, no actual generation is done.
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.
doesn't really matter, it's unnecessary duplication.
tol_stop->add_logger(logger); | ||
|
||
// Create smoother factory (ir with bj) | ||
auto inner_solver_gen = |
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.
is it necessary to introduce these intermediate factories again. I refactored this example to be as minimal as possible.
namespace kernels { | ||
namespace reference { | ||
/** | ||
* @brief The UNIFORM_COARSENING solver namespace. |
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 don't think these comments are useful.
} | ||
} | ||
|
||
static void assert_same_coarse_rows(const index_type* m1, |
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.
Same but for array.
PairTypenameNameGenerator); | ||
|
||
|
||
TYPED_TEST(UniformCoarsening, CanBeCopied) |
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.
Aren't copy/move/clone/clear generally core tests?
TYPED_TEST(UniformCoarsening, CanBeCopied) | ||
{ | ||
using Mtx = typename TestFixture::Mtx; | ||
using MgLevel = typename TestFixture::MgLevel; |
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.
unused (and in the other tests)
* @ingroup LinOp | ||
*/ | ||
template <typename ValueType = default_precision, typename IndexType = int32> | ||
class UniformCoarsening |
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.
Should this define copy/move assignment/constructors? The default ones are not completely inline with our normal understanding of those.
gko::kernels::reference::uniform_coarsening::fill_incremental_indices( | ||
this->exec, 2, &c_rows); | ||
GKO_ASSERT_ARRAY_EQ(c_rows, c2_rows); |
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.
range-based for loop?
903a8a5
to
915e227
Compare
|
915e227
to
2f5525a
Compare
c6939ee
to
e77eef8
Compare
e77eef8
to
185f551
Compare
@upsj, After a bit of thought, I think this class should not represent Geometric/Structured coarsening. Uniform coarsening is just a cheap coarsening method that just uniformly discards rows and columns to construct the coarse matrix, and hence is not suitable for Geometric coarsening, which needs to create connections between the coarse nodes. @MarcelKoch , we already provide the users with a way to specify custom indices for coarsening with the |
@pratikvn If we discard variables for restriction, we still need to interpolate new values for prolongation, so I don't yet see how this makes multi-dimensional coarsening impossible if 1D coarsening is possible? |
In a similar fashion to PGM, the prolongation matrix will be a transpose of the restriction matrix. I think maybe I have given a wrong impression that this would be a 1D coarsening. The fine level vectors will not have extrapolated values, but just "mapped" values. |
Doesn't PGM do the same thing? And I believe we are mixing two things here - coarsening and interpolation. One is structural, one concerns the actual numerical values. |
Just adding more performance results on a 7pt stencil and some chosen matrices from Suitesparse, to show that this type of coarsening can help in certain cases. Apply speedup for cage15 (v/s PGM) matrix and bcsstm39 matrix (v/s no preconditioning)speedup_app_ss_bicgstab_cskip.pdf Apply speedup for 7pt stencil (v/s PGM)Generate speedup for 7pt stencil (v/s PGM) |
I don't think these results matter, since even for simple stencils, the matrix loses all connectivity: Take the poisson-solver example and plug in the following code: auto gen = gko::multigrid::UniformCoarsening<ValueType, IndexType>::build().on(app_exec)->generate(matrix->clone());
gko::write(std::cout, matrix);
gko::write(std::cout, gko::as<mtx>(gen->get_composition()->get_operators()[1])); The fine matrix is tridiagonal, but the coarse matrix is just a diagonal matrix. |
This PR is an updated version of #979 . The idea is to have a very cheap coarse grid generation algorithm that works well for matrices that are uniform, for example, matrices that arise from stencils on structured grids.
For example, for a 7 point stencil on a 3D grid, it is very competitive to PGM (
with_deterministic=false
) with much faster generation and faster apply for larger problems (on OMP executor with 8 cores):