Skip to content

Commit 6b90223

Browse files
yhmtsaigreole
authored andcommitted
update matrix value in multigrid
1 parent 5626104 commit 6b90223

File tree

2 files changed

+152
-3
lines changed

2 files changed

+152
-3
lines changed

core/solver/multigrid.cpp

+140
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,146 @@ void Multigrid::generate()
849849
}
850850

851851

852+
void Multigrid::update_matrix_value(std::shared_ptr<const LinOp> new_matrix)
853+
{
854+
this->set_system_matrix(new_matrix);
855+
// generate coarse matrix until reaching max_level or min_coarse_rows
856+
auto num_rows = this->get_system_matrix()->get_size()[0];
857+
size_type level = 0;
858+
auto matrix = this->get_system_matrix();
859+
auto exec = this->get_executor();
860+
// clean all smoother
861+
pre_smoother_list_.clear();
862+
mid_smoother_list_.clear();
863+
post_smoother_list_.clear();
864+
// Always generate smoother with size = level.
865+
for (int i = 0; i < mg_level_list_.size(); i++) {
866+
auto mg_level = mg_level_list_.at(i);
867+
as<UpdateMatrixValue>(mg_level)->update_matrix_value(matrix);
868+
matrix = mg_level->get_coarse_op();
869+
run<gko::multigrid::EnableMultigridLevel, float, double,
870+
std::complex<float>, std::complex<double>>(
871+
mg_level,
872+
[this](auto mg_level, auto index, auto matrix) {
873+
using value_type =
874+
typename std::decay_t<decltype(*mg_level)>::value_type;
875+
handle_list<value_type>(
876+
index, matrix, parameters_.pre_smoother, pre_smoother_list_,
877+
parameters_.smoother_iters, parameters_.smoother_relax);
878+
if (parameters_.mid_case ==
879+
multigrid::mid_smooth_type::standalone) {
880+
handle_list<value_type>(
881+
index, matrix, parameters_.mid_smoother,
882+
mid_smoother_list_, parameters_.smoother_iters,
883+
parameters_.smoother_relax);
884+
}
885+
if (!parameters_.post_uses_pre) {
886+
handle_list<value_type>(
887+
index, matrix, parameters_.post_smoother,
888+
post_smoother_list_, parameters_.smoother_iters,
889+
parameters_.smoother_relax);
890+
}
891+
},
892+
i, mg_level->get_fine_op());
893+
}
894+
if (parameters_.post_uses_pre) {
895+
post_smoother_list_ = pre_smoother_list_;
896+
}
897+
auto last_mg_level = mg_level_list_.back();
898+
899+
// generate coarsest solver
900+
run<gko::multigrid::EnableMultigridLevel, float, double,
901+
std::complex<float>, std::complex<double>>(
902+
last_mg_level,
903+
[this](auto mg_level, auto level, auto matrix) {
904+
using value_type =
905+
typename std::decay_t<decltype(*mg_level)>::value_type;
906+
auto exec = this->get_executor();
907+
// default coarse grid solver, direct LU
908+
// TODO: maybe remove fixed index type
909+
auto gen_default_solver = [&]() -> std::unique_ptr<LinOp> {
910+
// TODO: unify when dpcpp supports direct solver
911+
#if GINKGO_BUILD_MPI
912+
if (gko::detail::is_distributed(matrix.get())) {
913+
using absolute_value_type = remove_complex<value_type>;
914+
using experimental::distributed::Matrix;
915+
return run<Matrix<value_type, int32, int32>,
916+
Matrix<value_type, int32, int64>,
917+
Matrix<value_type, int64,
918+
int64>>(matrix, [exec](auto matrix) {
919+
using Mtx = typename decltype(matrix)::element_type;
920+
return solver::Gmres<value_type>::build()
921+
.with_criteria(
922+
stop::Iteration::build().with_max_iters(
923+
matrix->get_size()[0]),
924+
stop::ResidualNorm<value_type>::build()
925+
.with_reduction_factor(
926+
std::numeric_limits<
927+
absolute_value_type>::epsilon() *
928+
absolute_value_type{10}))
929+
.with_krylov_dim(
930+
std::min(size_type(100), matrix->get_size()[0]))
931+
.with_preconditioner(
932+
experimental::distributed::preconditioner::
933+
Schwarz<value_type,
934+
typename Mtx::local_index_type,
935+
typename Mtx::global_index_type>::
936+
build()
937+
.with_local_solver(
938+
preconditioner::Jacobi<
939+
value_type>::build()
940+
.with_max_block_size(1u)))
941+
.on(exec)
942+
->generate(matrix);
943+
});
944+
}
945+
#endif
946+
if (dynamic_cast<const DpcppExecutor*>(exec.get())) {
947+
using absolute_value_type = remove_complex<value_type>;
948+
return solver::Gmres<value_type>::build()
949+
.with_criteria(
950+
stop::Iteration::build().with_max_iters(
951+
matrix->get_size()[0]),
952+
stop::ResidualNorm<value_type>::build()
953+
.with_reduction_factor(
954+
std::numeric_limits<
955+
absolute_value_type>::epsilon() *
956+
absolute_value_type{10}))
957+
.with_krylov_dim(
958+
std::min(size_type(100), matrix->get_size()[0]))
959+
.with_preconditioner(
960+
preconditioner::Jacobi<value_type>::build()
961+
.with_max_block_size(1u))
962+
.on(exec)
963+
->generate(matrix);
964+
} else {
965+
return experimental::solver::Direct<value_type,
966+
int32>::build()
967+
.with_factorization(
968+
experimental::factorization::Lu<value_type,
969+
int32>::build())
970+
.on(exec)
971+
->generate(matrix);
972+
}
973+
};
974+
if (parameters_.coarsest_solver.size() == 0) {
975+
coarsest_solver_ = gen_default_solver();
976+
} else {
977+
auto temp_index = solver_selector_(level, matrix.get());
978+
GKO_ENSURE_IN_BOUNDS(temp_index,
979+
parameters_.coarsest_solver.size());
980+
auto solver = parameters_.coarsest_solver.at(temp_index);
981+
if (solver == nullptr) {
982+
coarsest_solver_ = gen_default_solver();
983+
} else {
984+
coarsest_solver_ = solver->generate(matrix);
985+
}
986+
}
987+
},
988+
mg_level_list_.size(), matrix);
989+
}
990+
991+
852992
void Multigrid::apply_impl(const LinOp* b, LinOp* x) const
853993
{
854994
this->apply_with_initial_guess_impl(b, x,

include/ginkgo/core/solver/multigrid.hpp

+12-3
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,8 @@ class MultigridState;
107107
class Multigrid : public EnableLinOp<Multigrid>,
108108
public EnableSolverBase<Multigrid>,
109109
public EnableIterativeBase<Multigrid>,
110-
public EnableApplyWithInitialGuess<Multigrid> {
110+
public EnableApplyWithInitialGuess<Multigrid>,
111+
public UpdateMatrixValue {
111112
friend class EnableLinOp<Multigrid>;
112113
friend class EnablePolymorphicObject<Multigrid, LinOp>;
113114
friend class EnableApplyWithInitialGuess<Multigrid>;
@@ -133,7 +134,12 @@ class Multigrid : public EnableLinOp<Multigrid>,
133134
std::vector<std::shared_ptr<const gko::multigrid::MultigridLevel>>
134135
get_mg_level_list() const
135136
{
136-
return mg_level_list_;
137+
std::vector<std::shared_ptr<const gko::multigrid::MultigridLevel>>
138+
const_copy(mg_level_list_.size());
139+
for (int i = 0; i < mg_level_list_.size(); i++) {
140+
const_copy.at(i) = mg_level_list_.at(i);
141+
}
142+
return const_copy;
137143
}
138144

139145
/**
@@ -400,6 +406,9 @@ class Multigrid : public EnableLinOp<Multigrid>,
400406
const config::type_descriptor& td_for_child =
401407
config::make_type_descriptor<>());
402408

409+
void update_matrix_value(
410+
std::shared_ptr<const gko::LinOp> new_matrix) override;
411+
403412
protected:
404413
void apply_impl(const LinOp* b, LinOp* x) const override;
405414

@@ -447,7 +456,7 @@ class Multigrid : public EnableLinOp<Multigrid>,
447456
void create_state() const;
448457

449458
private:
450-
std::vector<std::shared_ptr<const gko::multigrid::MultigridLevel>>
459+
std::vector<std::shared_ptr<gko::multigrid::MultigridLevel>>
451460
mg_level_list_{};
452461
std::vector<std::shared_ptr<const LinOp>> pre_smoother_list_{};
453462
std::vector<std::shared_ptr<const LinOp>> mid_smoother_list_{};

0 commit comments

Comments
 (0)