Skip to content
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

Multigrid solver (V, W, F and K cycle) and example #542

Merged
merged 32 commits into from
Sep 1, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
4a5ddc4
initial multigrid
yhmtsai May 14, 2020
931df59
add v_cycle
yhmtsai May 19, 2020
7f9918b
try to fix MSVC error
yhmtsai May 19, 2020
a4f9b02
add core test
yhmtsai May 21, 2020
0232707
smoother and relaxation
yhmtsai May 27, 2020
009ea60
reduce
yhmtsai May 27, 2020
f0d0fae
add documentation and the v_cycle step check
yhmtsai Jun 2, 2020
31a8c54
add w/f cycle, cycle parameter, test cycle step
yhmtsai Jun 3, 2020
debdc9b
Example WIP
yhmtsai Jun 5, 2020
09631d7
add mid_smoother and more tests
yhmtsai Jun 12, 2020
3095878
add MultigridState
yhmtsai Jun 12, 2020
bc4f295
add coarsest_solver selector and tests
yhmtsai Jun 14, 2020
2116128
add throw test
yhmtsai Jun 15, 2020
6918961
change the name
yhmtsai Jun 20, 2020
e31b47e
implement kcycle
yhmtsai Jun 20, 2020
6c1f0da
kcycle omp/hip/cuda impl/test
yhmtsai Jun 22, 2020
2f38b9e
remove relaxation and use Ir for the direct linop
yhmtsai Jul 27, 2020
d952295
make multigrid work with MultigridLevel LinOp, update example
yhmtsai Mar 9, 2021
90a9fc9
recover mg_level, post/mid use pre by default
yhmtsai Jun 2, 2021
0867ea6
fix error
yhmtsai Jun 2, 2021
1f41644
use the new GKO_FACTORY_PARAMETER_*
yhmtsai Jun 2, 2021
2ea1cb4
rm almost all VT dep from Multigrid, add mixed test
yhmtsai Jun 4, 2021
5cfc06b
rm Multigrid's ValueType, add helper to loop type
yhmtsai Jun 8, 2021
0550263
add mixed-multigrid-solver
yhmtsai Jun 9, 2021
c8ade11
add smoother_build shortcut and corresponding test
yhmtsai Jun 11, 2021
a2b0b9b
documentation improvement
yhmtsai Jun 28, 2021
d19b845
use child structure to isolate the kcycle things
yhmtsai Jun 29, 2021
8ec7148
update mid smoother behavior and some tests
yhmtsai Jun 30, 2021
4d5626e
update documentation and naming
yhmtsai Jul 8, 2021
29af32a
fix gko::share usage wrong
yhmtsai Aug 27, 2021
1e14c2a
amgx_pgm skip_sorting
yhmtsai Aug 27, 2021
cb08a25
add zero_guess for multigrid
yhmtsai Aug 31, 2021
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
Prev Previous commit
Next Next commit
remove relaxation and use Ir for the direct linop
1. relaxation is moved under Ir relaxation_factor
2. If the LinOpFactory produce direct operator, use Ir on it.
  • Loading branch information
yhmtsai committed Sep 1, 2021
commit 2f38b9ed2623b0b3b172cb33625b0ca7dc5b3a63
17 changes: 16 additions & 1 deletion core/multigrid/amgx_pgm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <ginkgo/core/matrix/csr.hpp>
#include <ginkgo/core/matrix/dense.hpp>
#include <ginkgo/core/matrix/identity.hpp>

#include <iostream>

#include "core/components/fill_array.hpp"
#include "core/matrix/csr_builder.hpp"
Expand Down Expand Up @@ -109,13 +109,24 @@ void AmgxPgm<ValueType, IndexType>::generate()
lend(weight_mtx));
// Extract the diagonal value of matrix
auto diag = weight_mtx->extract_diagonal();
auto host = exec->get_master();
// auto weight_mtx_host = weight_matrix_type::create(host);
// auto diag_host = matrix::Dense<rmc_value_type>::create(host);
// weight_mtx_host->copy_from(weight_mtx.get());
// diag_host->copy_from(diag.get());
// strongest_neighbor.set_executor(host);
for (int i = 0; i < parameters_.max_iterations; i++) {
// Find the strongest neighbor of each row
// host->run(amgx_pgm::make_find_strongest_neighbor(
// weight_mtx_host.get(), diag_host.get(), agg_,
// strongest_neighbor));
exec->run(amgx_pgm::make_find_strongest_neighbor(
weight_mtx.get(), diag.get(), agg_, strongest_neighbor));
// Match edges
// host->run(amgx_pgm::make_match_edge(strongest_neighbor, agg_));
exec->run(amgx_pgm::make_match_edge(strongest_neighbor, agg_));
// Get the num_unagg
// host->run(amgx_pgm::make_count_unagg(agg_, &num_unagg));
exec->run(amgx_pgm::make_count_unagg(agg_, &num_unagg));
// no new match, all match, or the ratio of num_unagg/num is lower
// than parameter.max_unassigned_ratio
Expand All @@ -125,6 +136,9 @@ void AmgxPgm<ValueType, IndexType>::generate()
}
num_unagg_prev = num_unagg;
}
// agg_.set_executor(exec);
// strongest_neighbor.set_executor(exec);
std::cout << "num_unagg: " << num_unagg << std::endl;
// Handle the left unassign points
if (num_unagg != 0 && parameters_.deterministic) {
// copy the agg to intermediate_agg
Expand All @@ -136,6 +150,7 @@ void AmgxPgm<ValueType, IndexType>::generate()
weight_mtx.get(), diag.get(), agg_, intermediate_agg));
}
IndexType num_agg = 0;

// Renumber the index
exec->run(amgx_pgm::make_renumber(agg_, &num_agg));

Expand Down
83 changes: 37 additions & 46 deletions core/solver/multigrid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <ginkgo/core/base/name_demangling.hpp>
yhmtsai marked this conversation as resolved.
Show resolved Hide resolved
#include <ginkgo/core/base/utils.hpp>
#include <ginkgo/core/matrix/dense.hpp>

#include <ginkgo/core/solver/ir.hpp>
#include <ginkgo/core/stop/iteration.hpp>
#include <iostream>

#include "core/components/fill_array.hpp"
#include "core/solver/ir_kernels.hpp"
Expand Down Expand Up @@ -70,9 +72,7 @@ void handle_list(
std::shared_ptr<const Executor> &exec, size_type index,
std::shared_ptr<const LinOp> &matrix,
std::vector<std::shared_ptr<const LinOpFactory>> &smoother_list,
gko::Array<ValueType> &relaxation_array,
std::vector<std::shared_ptr<LinOp>> &smoother,
std::vector<std::shared_ptr<matrix::Dense<ValueType>>> &relaxation,
std::shared_ptr<matrix::Dense<ValueType>> &one)
{
auto list_size = smoother_list.size();
Expand All @@ -83,23 +83,25 @@ void handle_list(
if (item == nullptr) {
smoother.emplace_back(nullptr);
} else {
smoother.emplace_back(give(item->generate(matrix)));
auto solver = item->generate(matrix);
if (solver->apply_uses_initial_guess() == true) {
smoother.emplace_back(give(solver));
} else {
// if it is not use initial guess, use it as inner solver of Ir
// with 1 iteration and relaxation_factor 1
auto ir =
Ir<ValueType>::build()
.with_generated_solver(give(solver))
.with_criteria(
gko::stop::Iteration::build().with_max_iters(1u).on(
exec))
.on(exec);
smoother.emplace_back(give(ir->generate(matrix)));
}
}
} else {
smoother.emplace_back(nullptr);
}
auto array_size = relaxation_array.get_num_elems();
if (array_size != 0) {
auto temp_index = array_size == 1 ? 0 : index;
GKO_ENSURE_IN_BOUNDS(temp_index, array_size);
auto data = relaxation_array.get_data();
relaxation.emplace_back(give(matrix::Dense<ValueType>::create(
exec, gko::dim<2>{1},
Array<ValueType>::view(exec, 1, data + temp_index), 1)));
} else {
// default is one;
relaxation.emplace_back(one);
}
}


Expand Down Expand Up @@ -185,24 +187,21 @@ struct MultigridState {
auto total_level = multigrid->get_rstr_prlg_list().size();
// get the pre_smoother
auto pre_smoother = multigrid->get_pre_smoother_list().at(level);
auto pre_relaxation = multigrid->get_pre_relaxation_list().at(level);
// get the mid_smoother
auto mid_smoother = multigrid->get_mid_smoother_list().at(level);
auto mid_relaxation = multigrid->get_mid_relaxation_list().at(level);
// get the post_smoother
auto post_smoother = multigrid->get_post_smoother_list().at(level);
auto post_relaxation = multigrid->get_post_relaxation_list().at(level);
// move the residual computation in level zero to out-of-cycle
if (level != 0) {
r->copy_from(b);
matrix->apply(neg_one, x, one, r.get());
}
// x += relaxation * Smoother(r)
// Smoother * x = r
if (pre_smoother) {
pre_smoother->apply(pre_relaxation.get(), r.get(), one, x);
pre_smoother->apply(b, x);
// compute residual
r->copy_from(b); // n * b
matrix->apply(neg_one, x, one, r.get());
} else if (level != 0) {
// move the residual computation at level 0 to out-of-cycle if there
// is no pre-smoother at level 0
r->copy_from(b);
matrix->apply(neg_one, x, one, r.get());
}
// first cycle
rstr_prlg->restrict_apply(r.get(), g.get());
Expand All @@ -218,16 +217,13 @@ struct MultigridState {
// second cycle - f_cycle, w_cycle
// prolong
rstr_prlg->prolong_applyadd(e.get(), x);
// compute residual
r->copy_from(b); // n * b
matrix->apply(neg_one, x, one, r.get());
// mid-smooth
if (mid_smoother) {
mid_smoother->apply(mid_relaxation.get(), r.get(), one, x);
// compute residual
r->copy_from(b); // n * b
matrix->apply(neg_one, x, one, r.get());
mid_smoother->apply(b, x);
}
// compute residual
r->copy_from(b); // n * b
matrix->apply(neg_one, x, one, r.get());

rstr_prlg->restrict_apply(r.get(), g.get());
// next level or solve it
Expand Down Expand Up @@ -321,9 +317,7 @@ struct MultigridState {

// post-smooth
if (post_smoother) {
r->copy_from(b);
matrix->apply(neg_one, x, one, r.get());
post_smoother->apply(post_relaxation.get(), r.get(), one, x);
post_smoother->apply(b, x);
}
}

Expand Down Expand Up @@ -367,7 +361,9 @@ void Multigrid<ValueType>::generate()
size_type level = 0;
auto matrix = system_matrix_;
auto exec = this->get_executor();
// Always generate smoother and relaxation with size = level.
std::cout << matrix->get_size()[0] << " " << matrix->get_size()[1]
<< std::endl;
yhmtsai marked this conversation as resolved.
Show resolved Hide resolved
// Always generate smoother with size = level.
while (level < parameters_.max_levels &&
num_rows > parameters_.min_coarse_rows) {
auto index = rstr_prlg_index_(level, lend(matrix));
Expand All @@ -382,34 +378,29 @@ void Multigrid<ValueType>::generate()
rstr_prlg_list_.emplace_back(give(rstr));
// pre_smooth_generate
handle_list(exec, index, matrix, parameters_.pre_smoother,
parameters_.pre_relaxation, pre_smoother_list_,
pre_relaxation_list_, one_op_);
pre_smoother_list_, one_op_);
// mid_smooth_generate
if (parameters_.mid_case == multigrid_mid_uses::mid) {
handle_list(exec, index, matrix, parameters_.mid_smoother,
parameters_.mid_relaxation, mid_smoother_list_,
mid_relaxation_list_, one_op_);
mid_smoother_list_, one_op_);
}
// post_smooth_generate
if (!parameters_.post_uses_pre) {
handle_list(exec, index, matrix, parameters_.post_smoother,
parameters_.post_relaxation, post_smoother_list_,
post_relaxation_list_, one_op_);
post_smoother_list_, one_op_);
}
matrix = rstr_prlg_list_.back()->get_coarse_operator();
std::cout << num_rows << " -> " << matrix->get_size()[0] << std::endl;
yhmtsai marked this conversation as resolved.
Show resolved Hide resolved
num_rows = matrix->get_size()[0];
level++;
}
if (parameters_.post_uses_pre) {
post_smoother_list_ = pre_smoother_list_;
post_relaxation_list_ = pre_relaxation_list_;
}
if (parameters_.mid_case == multigrid_mid_uses::pre) {
mid_smoother_list_ = pre_smoother_list_;
mid_relaxation_list_ = pre_relaxation_list_;
} else if (parameters_.mid_case == multigrid_mid_uses::post) {
mid_smoother_list_ = post_smoother_list_;
mid_relaxation_list_ = post_relaxation_list_;
}
// Generate at least one level
GKO_ASSERT_EQ(level > 0, true);
tcojean marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
Loading