Skip to content

Instantly share code, notes, and snippets.

@dwatanabee
Created March 4, 2022 05:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save dwatanabee/bba0902321c02da21d99705473ae1aaf to your computer and use it in GitHub Desktop.
Save dwatanabee/bba0902321c02da21d99705473ae1aaf to your computer and use it in GitHub Desktop.
#include <vector>
#include <iostream>
#include <amgcl/backend/builtin.hpp>
#include <amgcl/value_type/static_matrix.hpp>
#include <amgcl/adapter/crs_tuple.hpp>
#include <amgcl/adapter/block_matrix.hpp>
#include <amgcl/mpi/distributed_matrix.hpp>
#include <amgcl/mpi/make_solver.hpp>
#include <amgcl/mpi/amg.hpp>
#include <amgcl/mpi/coarsening/smoothed_aggregation.hpp>
#include <amgcl/mpi/relaxation/spai0.hpp>
#include <amgcl/mpi/solver/bicgstab.hpp>
#include <amgcl/io/binary.hpp>
#include <amgcl/profiler.hpp>
#include <Eigen/Sparse>
// Block size
// const int B = 1;
// Get the global size of the matrix:
int rows = 5;
//---------------------------------------------------------------------------
int main(int argc, char *argv[])
{
amgcl::mpi::init mpi(&argc, &argv);
amgcl::mpi::communicator world(MPI_COMM_WORLD);
Eigen::SparseMatrix<double> eA(rows, rows);
int localsize = 3;
if (world.rank == 0)
{
eA.coeffRef(0, 0) = 1.0;
eA.coeffRef(1, 1) = 1.0;
eA.coeffRef(2, 2) = 0.5;
}
else
{
eA.coeffRef(2, 2) = 0.5;
eA.coeffRef(3, 3) = 1.0;
eA.coeffRef(4, 4) = 1.0;
}
eA.makeCompressed();
// The profiler:
amgcl::profiler<> prof("Serena MPI");
prof.tic("read");
int row_beg = world.rank;
int row_end = world.rank + localsize;
int chunk = row_end - row_beg;
// Read our part of the system matrix.
int nonzeros = eA.nonZeros();
std::vector<int> ptr(eA.outerIndexPtr(), eA.outerIndexPtr() + nonzeros + 1);
std::vector<int> col(eA.innerIndexPtr(), eA.innerIndexPtr() + nonzeros);
std::vector<double> val(eA.valuePtr(), eA.valuePtr() + nonzeros);
prof.toc("read");
// Declare the backend and the solver types
typedef amgcl::backend::builtin<double> DBackend;
typedef amgcl::backend::builtin<float> FBackend;
typedef amgcl::mpi::make_solver<
amgcl::mpi::amg<
FBackend,
amgcl::mpi::coarsening::smoothed_aggregation<FBackend>,
amgcl::mpi::relaxation::spai0<FBackend>>,
amgcl::mpi::solver::bicgstab<DBackend>>
Solver;
// Solver parameters
Solver::params prm;
prm.solver.maxiter = 200;
auto A = std::make_shared<amgcl::mpi::distributed_matrix<DBackend>>(
world, std::tie(chunk, ptr, col, val));
std::vector<double> rhs(chunk, 1.0);
// Initialize the solver:
prof.tic("setup");
Solver solve(world, A, prm);
prof.toc("setup");
// Show the mini-report on the constructed solver:
if (world.rank == 0)
std::cout << solve << std::endl;
// Solve the system with the zero initial approximation:
int iters;
double error;
std::vector<double> x(chunk, 0.0);
prof.tic("solve");
std::tie(iters, error) = solve(*A, rhs, x);
prof.toc("solve");
// Output the number of iterations, the relative error,
// and the profiling data:
if (world.rank == 0)
{
std::cout
<< "Iterations: " << iters << std::endl
<< "Error: " << error << std::endl
<< prof << std::endl;
std::cout << "sol: " << std::endl;
for (auto &xi : x)
std::cout << xi << std::endl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment