Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ GSYMS
GTAGS
GPATH
.gitignore
.cache

### OS
# temporary and backup files
Expand Down
6 changes: 4 additions & 2 deletions core/distributed/preconditioner/schwarz.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
// SPDX-FileCopyrightText: 2017 - 2026 The Ginkgo authors
//
// SPDX-License-Identifier: BSD-3-Clause

Expand Down Expand Up @@ -192,7 +192,7 @@ void Schwarz<ValueType, LocalIndexType, GlobalIndexType>::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);
Expand Down Expand Up @@ -234,6 +234,8 @@ void Schwarz<ValueType, LocalIndexType, GlobalIndexType>::generate(
exec, local_matrix->get_size()[0]);
auto one = initialize<matrix::Dense<ValueType>>(
{::gko::one<ValueType>()}, 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(
Expand Down
75 changes: 74 additions & 1 deletion test/mpi/preconditioner/schwarz.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2017 - 2025 The Ginkgo authors
// SPDX-FileCopyrightText: 2017 - 2026 The Ginkgo authors
//
// SPDX-License-Identifier: BSD-3-Clause

Expand Down Expand Up @@ -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"


Expand Down Expand Up @@ -381,3 +382,75 @@ TYPED_TEST(SchwarzPreconditioner, CanApplyPreconditionerWithL1Smoother)
this->assert_equal_to_non_distributed_vector(this->dist_x,
this->non_dist_x);
}


TYPED_TEST(SchwarzPreconditioner, UnsortedMatrixSolverWithL1Smoother)
{
using value_type = typename TestFixture::value_type;
using global_index_type = typename TestFixture::global_index_type;
using dist_mtx_type = typename TestFixture::dist_mtx_type;
using prec = typename TestFixture::dist_prec_type;
using local_matrix_type = typename TestFixture::local_matrix_type;

gko::matrix_data<value_type, global_index_type> unsorted_data({8, 8});
auto rank = this->comm.rank();

if (rank == 0) {
unsorted_data.nonzeros = {
{0, 1, -1.0}, {0, 0, 2.0}, {1, 2, -1.0}, {1, 0, -1.0}, {1, 1, 2.0}};
} else if (rank == 1) {
unsorted_data.nonzeros = {{2, 3, -1.0}, {2, 1, -1.0}, {2, 2, 2.0},
{3, 4, -1.0}, {3, 2, -1.0}, {3, 3, 2.0}};
} else if (rank == 2) {
unsorted_data.nonzeros = {{4, 5, -1.0}, {4, 3, -1.0}, {4, 4, 2.0},
{5, 6, -1.0}, {5, 4, -1.0}, {5, 5, 2.0},
{6, 7, -1.0}, {6, 5, -1.0}, {6, 6, 2.0},
{7, 6, -1.0}, {7, 7, 2.0}};
}

auto dist_mat_unsorted =
gko::share(dist_mtx_type::create(this->exec, this->comm));
dist_mat_unsorted->read_distributed(unsorted_data, this->row_part);

auto sorted_data = unsorted_data;
sorted_data.sort_row_major();

auto dist_mat_sorted =
gko::share(dist_mtx_type::create(this->exec, this->comm));
dist_mat_sorted->read_distributed(sorted_data, this->row_part);

// ensure the unsorted matrix is actually unsorted
auto local_mtx =
gko::as<local_matrix_type>(dist_mat_unsorted->get_local_matrix());
auto host_local_mtx = gko::clone(this->exec->get_master(), local_mtx);
bool is_sorted = true;
for (gko::size_type i = 0; i < host_local_mtx->get_size()[0]; ++i) {
for (auto j = host_local_mtx->get_const_row_ptrs()[i];
j < host_local_mtx->get_const_row_ptrs()[i + 1] - 1; ++j) {
if (host_local_mtx->get_const_col_idxs()[j] >
host_local_mtx->get_const_col_idxs()[j + 1]) {
is_sorted = false;
break;
}
}
}
ASSERT_FALSE(is_sorted) << "The matrix was unexpectedly sorted.";

auto precond_factory = prec::build()
.with_local_solver(this->local_solver_factory)
.with_l1_smoother(true)
.on(this->exec);

auto precond_unsorted = precond_factory->generate(dist_mat_unsorted);
auto precond_sorted = precond_factory->generate(dist_mat_sorted);

auto dist_x_unsorted = gko::clone(this->dist_x);
auto dist_x_sorted = gko::clone(this->dist_x);

precond_unsorted->apply(this->dist_b.get(), dist_x_unsorted.get());
precond_sorted->apply(this->dist_b.get(), dist_x_sorted.get());

GKO_ASSERT_MTX_NEAR(dist_x_unsorted->get_local_vector(),
dist_x_sorted->get_local_vector(),
r<value_type>::value);
}
Loading