From 129e312ee18e1421380144622ac24ed971c4858a Mon Sep 17 00:00:00 2001 From: Atell Krasnopolski Date: Wed, 22 Oct 2025 11:25:17 +0200 Subject: [PATCH 1/8] Add diag sorting to Schwarz precond w/ l1 smoother --- .gitignore | 1 + core/distributed/preconditioner/schwarz.cpp | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 58d305f00f1..dd5ef0f582f 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,7 @@ GSYMS GTAGS GPATH .gitignore +.cache ### OS # temporary and backup files diff --git a/core/distributed/preconditioner/schwarz.cpp b/core/distributed/preconditioner/schwarz.cpp index e93b229157b..544e4696c00 100644 --- a/core/distributed/preconditioner/schwarz.cpp +++ b/core/distributed/preconditioner/schwarz.cpp @@ -230,6 +230,8 @@ void Schwarz::generate( exec, local_matrix->get_size()[0], std::move(l1_diag_arr)); auto l1_diag_csr = Csr::create(exec); l1_diag->move_to(l1_diag_csr); + l1_diag_csr->sort_by_column_index(); // spgeam requires sorting for + // some backends auto id = matrix::Identity::create( exec, local_matrix->get_size()[0]); auto one = initialize>( From 001d5828e74832983caca9603decb02465645495 Mon Sep 17 00:00:00 2001 From: Atell Krasnopolski Date: Thu, 23 Oct 2025 11:52:10 +0200 Subject: [PATCH 2/8] Fix a typo --- core/distributed/preconditioner/schwarz.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/distributed/preconditioner/schwarz.cpp b/core/distributed/preconditioner/schwarz.cpp index 544e4696c00..300c381bc8f 100644 --- a/core/distributed/preconditioner/schwarz.cpp +++ b/core/distributed/preconditioner/schwarz.cpp @@ -192,7 +192,7 @@ void Schwarz::generate( } if (!parameters_.local_solver && !parameters_.generated_local_solver) { GKO_INVALID_STATE( - "Requires either a generated solver or an solver factory"); + "Requires either a generated solver or a solver factory"); } if (parameters_.generated_local_solver) { this->set_solver(parameters_.generated_local_solver); From cee911d05b365a2bdec83d2f2c71c7b301b99d0d Mon Sep 17 00:00:00 2001 From: Atell Krasnopolski Date: Thu, 23 Oct 2025 11:52:43 +0200 Subject: [PATCH 3/8] Add an L1 smoother solver test for the Schwarz precond --- test/mpi/preconditioner/schwarz.cpp | 39 +++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/mpi/preconditioner/schwarz.cpp b/test/mpi/preconditioner/schwarz.cpp index 8cacfa1ec9f..86348c9d4a3 100644 --- a/test/mpi/preconditioner/schwarz.cpp +++ b/test/mpi/preconditioner/schwarz.cpp @@ -381,3 +381,42 @@ TYPED_TEST(SchwarzPreconditioner, CanApplyPreconditionerWithL1Smoother) this->assert_equal_to_non_distributed_vector(this->dist_x, this->non_dist_x); } + +TYPED_TEST(SchwarzPreconditioner, CanApplyPreconditionedSolverWithL1Smoother) +{ + using value_type = typename TestFixture::value_type; + using csr = typename TestFixture::local_matrix_type; + using cg = typename TestFixture::solver_type; + using prec = typename TestFixture::dist_prec_type; + constexpr double tolerance = 1e-20; + auto iter_stop = gko::share( + gko::stop::Iteration::build().with_max_iters(200u).on(this->exec)); + auto tol_stop = gko::share( + gko::stop::ResidualNorm::build() + .with_reduction_factor( + static_cast>(tolerance)) + .on(this->exec)); + this->dist_solver_factory = + cg::build() + .with_preconditioner( + prec::build() + .with_local_solver(this->local_solver_factory) + .with_l1_smoother(true) + .on(this->exec)) + .with_criteria(iter_stop, tol_stop) + .on(this->exec); + auto dist_solver = this->dist_solver_factory->generate(this->dist_mat); + this->non_dist_solver_factory = + cg::build() + .with_preconditioner(this->local_solver_factory) + .with_criteria(iter_stop, tol_stop) + .on(this->exec); + auto non_dist_solver = + this->non_dist_solver_factory->generate(this->non_dist_mat); + + dist_solver->apply(this->dist_b.get(), this->dist_x.get()); + non_dist_solver->apply(this->non_dist_b.get(), this->non_dist_x.get()); + + this->assert_equal_to_non_distributed_vector(this->dist_x, + this->non_dist_x); +} From 00aef87f7212f64e297f3b48bbef57ce387b43fb Mon Sep 17 00:00:00 2001 From: Atell Krasnopolski Date: Fri, 24 Oct 2025 17:04:59 +0200 Subject: [PATCH 4/8] fix the test --- core/distributed/preconditioner/schwarz.cpp | 1 + test/mpi/preconditioner/schwarz.cpp | 11 +++++++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/core/distributed/preconditioner/schwarz.cpp b/core/distributed/preconditioner/schwarz.cpp index 300c381bc8f..6636fcd3e95 100644 --- a/core/distributed/preconditioner/schwarz.cpp +++ b/core/distributed/preconditioner/schwarz.cpp @@ -4,6 +4,7 @@ #include "ginkgo/core/distributed/preconditioner/schwarz.hpp" +#include #include #include diff --git a/test/mpi/preconditioner/schwarz.cpp b/test/mpi/preconditioner/schwarz.cpp index 86348c9d4a3..33d73dc6f5b 100644 --- a/test/mpi/preconditioner/schwarz.cpp +++ b/test/mpi/preconditioner/schwarz.cpp @@ -388,14 +388,19 @@ TYPED_TEST(SchwarzPreconditioner, CanApplyPreconditionedSolverWithL1Smoother) using csr = typename TestFixture::local_matrix_type; using cg = typename TestFixture::solver_type; using prec = typename TestFixture::dist_prec_type; + using local_matrix_type = typename TestFixture::local_matrix_type; constexpr double tolerance = 1e-20; auto iter_stop = gko::share( - gko::stop::Iteration::build().with_max_iters(200u).on(this->exec)); + gko::stop::Iteration::build().with_max_iters(400u).on(this->exec)); auto tol_stop = gko::share( gko::stop::ResidualNorm::build() .with_reduction_factor( static_cast>(tolerance)) .on(this->exec)); + auto non_dist_diag_with_l1 = + gko::share(gko::matrix::Diagonal::create( + this->exec, 8u, + gko::array(this->exec, {2, 3, 3, 3, 3, 2, 2, 2}))); this->dist_solver_factory = cg::build() .with_preconditioner( @@ -408,7 +413,9 @@ TYPED_TEST(SchwarzPreconditioner, CanApplyPreconditionedSolverWithL1Smoother) auto dist_solver = this->dist_solver_factory->generate(this->dist_mat); this->non_dist_solver_factory = cg::build() - .with_preconditioner(this->local_solver_factory) + .with_generated_preconditioner(this->local_solver_factory->generate( + gko::copy_and_convert_to( + this->exec, non_dist_diag_with_l1))) .with_criteria(iter_stop, tol_stop) .on(this->exec); auto non_dist_solver = From c3c01fc37bf52aeebef7757a60ce4e209ce4b4f0 Mon Sep 17 00:00:00 2001 From: Atell Krasnopolski Date: Wed, 29 Oct 2025 16:44:05 +0100 Subject: [PATCH 5/8] add mult = 2 to the test --- test/mpi/preconditioner/schwarz.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/test/mpi/preconditioner/schwarz.cpp b/test/mpi/preconditioner/schwarz.cpp index 33d73dc6f5b..3e030ae0050 100644 --- a/test/mpi/preconditioner/schwarz.cpp +++ b/test/mpi/preconditioner/schwarz.cpp @@ -31,6 +31,7 @@ #include "core/test/utils.hpp" #include "core/test/utils/matrix_generator.hpp" #include "core/utils/matrix_utils.hpp" +#include "ginkgo/core/base/math.hpp" #include "test/utils/mpi/common_fixture.hpp" @@ -145,7 +146,8 @@ class SchwarzPreconditioner : public CommonMpiTestFixture { void assert_equal_to_non_distributed_vector( std::shared_ptr dist_vec, - std::shared_ptr local_vec) + std::shared_ptr local_vec, + gko::remove_complex mult = gko::one()) { auto host_row_part = row_part->clone(ref); auto l_dist_vec = dist_vec->get_local_vector(); @@ -156,7 +158,8 @@ class SchwarzPreconditioner : public CommonMpiTestFixture { local_vec->get_const_values() + host_row_part->get_range_bounds()[comm.rank()]), l_dist_vec->get_size()[1]); - GKO_ASSERT_MTX_NEAR(l_dist_vec, vec_view.get(), r::value); + GKO_ASSERT_MTX_NEAR(l_dist_vec, vec_view.get(), + mult * r::value); } }; @@ -391,7 +394,7 @@ TYPED_TEST(SchwarzPreconditioner, CanApplyPreconditionedSolverWithL1Smoother) using local_matrix_type = typename TestFixture::local_matrix_type; constexpr double tolerance = 1e-20; auto iter_stop = gko::share( - gko::stop::Iteration::build().with_max_iters(400u).on(this->exec)); + gko::stop::Iteration::build().with_max_iters(200u).on(this->exec)); auto tol_stop = gko::share( gko::stop::ResidualNorm::build() .with_reduction_factor( @@ -424,6 +427,7 @@ TYPED_TEST(SchwarzPreconditioner, CanApplyPreconditionedSolverWithL1Smoother) dist_solver->apply(this->dist_b.get(), this->dist_x.get()); non_dist_solver->apply(this->non_dist_b.get(), this->non_dist_x.get()); - this->assert_equal_to_non_distributed_vector(this->dist_x, - this->non_dist_x); + this->assert_equal_to_non_distributed_vector( + this->dist_x, this->non_dist_x, + 2); // mult = 2 is needed for the gko::half to work } From 900829ac794caef5eae3d6e18fc578853e1a4637 Mon Sep 17 00:00:00 2001 From: Atell Krasnopolski Date: Wed, 29 Oct 2025 16:46:39 +0100 Subject: [PATCH 6/8] match the types --- test/mpi/preconditioner/schwarz.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/mpi/preconditioner/schwarz.cpp b/test/mpi/preconditioner/schwarz.cpp index 3e030ae0050..f2880fbd604 100644 --- a/test/mpi/preconditioner/schwarz.cpp +++ b/test/mpi/preconditioner/schwarz.cpp @@ -147,7 +147,8 @@ class SchwarzPreconditioner : public CommonMpiTestFixture { void assert_equal_to_non_distributed_vector( std::shared_ptr dist_vec, std::shared_ptr local_vec, - gko::remove_complex mult = gko::one()) + gko::remove_complex mult = + gko::one>()) { auto host_row_part = row_part->clone(ref); auto l_dist_vec = dist_vec->get_local_vector(); From 7a12250bc53806f82d0c482686da3fd17243a3b6 Mon Sep 17 00:00:00 2001 From: Atell Krasnopolski Date: Tue, 4 Nov 2025 14:32:07 +0100 Subject: [PATCH 7/8] Sort the right matrix --- core/distributed/preconditioner/schwarz.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/distributed/preconditioner/schwarz.cpp b/core/distributed/preconditioner/schwarz.cpp index 6636fcd3e95..418666ab63c 100644 --- a/core/distributed/preconditioner/schwarz.cpp +++ b/core/distributed/preconditioner/schwarz.cpp @@ -231,12 +231,12 @@ void Schwarz::generate( exec, local_matrix->get_size()[0], std::move(l1_diag_arr)); auto l1_diag_csr = Csr::create(exec); l1_diag->move_to(l1_diag_csr); - l1_diag_csr->sort_by_column_index(); // spgeam requires sorting for - // some backends auto id = matrix::Identity::create( exec, local_matrix->get_size()[0]); auto one = initialize>( {::gko::one()}, exec); + local_matrix_copy->sort_by_column_index(); // spgeam requires sorting + // for some backends l1_diag_csr->apply(one, id, one, local_matrix_copy); this->set_solver( From 49c0abacb4d45171beafb3a24055579f4e0d22ea Mon Sep 17 00:00:00 2001 From: Atell Krasnopolski Date: Tue, 4 Nov 2025 14:33:26 +0100 Subject: [PATCH 8/8] address the review suggestions --- core/distributed/preconditioner/schwarz.cpp | 1 - test/mpi/preconditioner/schwarz.cpp | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/core/distributed/preconditioner/schwarz.cpp b/core/distributed/preconditioner/schwarz.cpp index 418666ab63c..cd4c2500a5c 100644 --- a/core/distributed/preconditioner/schwarz.cpp +++ b/core/distributed/preconditioner/schwarz.cpp @@ -4,7 +4,6 @@ #include "ginkgo/core/distributed/preconditioner/schwarz.hpp" -#include #include #include diff --git a/test/mpi/preconditioner/schwarz.cpp b/test/mpi/preconditioner/schwarz.cpp index f2880fbd604..7218b676543 100644 --- a/test/mpi/preconditioner/schwarz.cpp +++ b/test/mpi/preconditioner/schwarz.cpp @@ -386,6 +386,7 @@ TYPED_TEST(SchwarzPreconditioner, CanApplyPreconditionerWithL1Smoother) this->non_dist_x); } + TYPED_TEST(SchwarzPreconditioner, CanApplyPreconditionedSolverWithL1Smoother) { using value_type = typename TestFixture::value_type;