8 #ifndef OPENFPM_NUMERICS_SRC_SOLVERS_PETSC_SOLVER_AMG_REPORT_HPP_
9 #define OPENFPM_NUMERICS_SRC_SOLVERS_PETSC_SOLVER_AMG_REPORT_HPP_
16 #include "Solvers/petsc_solver.hpp"
17 #include "Vector/map_vector.hpp"
86 auto x_ = solver.
solve(A,b);
98 double time1 = tm_solve.
getwct();
99 double time2 = tm_solve2.
getwct();
101 Vcluster & v_cl = create_vcluster();
115 std::cout <<
"Time1: " << time1 <<
" Time2: " << time2 << std::endl;
126 Vcluster & v_cl = create_vcluster();
147 A.getMatrixTriplets();
148 if (v_cl.
getProcessUnitID() == 0) {std::cout <<
"Benchmarking HMIS coarsener" << std::endl;}
154 A.getMatrixTriplets();
155 if (v_cl.
getProcessUnitID() == 0) {std::cout <<
"Benchmarking PMIS coarsener" << std::endl;}
161 A.getMatrixTriplets();
162 if (v_cl.
getProcessUnitID() == 0) {std::cout <<
"Benchmarking Falgout coarsener" << std::endl;}
168 A.getMatrixTriplets();
169 if (v_cl.
getProcessUnitID() == 0) {std::cout <<
"Benchmarking modifiedRuge-Stueben coarsener" << std::endl;}
172 method.add(
"modifiedRuge-Stueben");
175 A.getMatrixTriplets();
176 if (v_cl.
getProcessUnitID() == 0) {std::cout <<
"Benchmarking Ruge-Stueben coarsener" << std::endl;}
179 method.add(
"Ruge-Stueben");
182 A.getMatrixTriplets();
183 if (v_cl.
getProcessUnitID() == 0) {std::cout <<
"Benchmarking CLJP coarsener" << std::endl;}
209 std::cout <<
"Composing coarsening report" << std::endl;
221 yn.add(
"Norm infinity");
222 yn.add(
"time to setup");
223 yn.add(
"time to solve");
232 options.
title = std::string(
"Overview of different coarsener on a V cycle with 6 relaxation SOR/Jacobi sweeps for each level up and down");
233 options.yAxis = std::string(
"Error/time");
234 options.xAxis = std::string(
"Method");
235 options.stype = std::string(
"bars");
236 options.more = std::string(
"vAxis: {scaleType: 'log'}");
238 std::stringstream ss;
240 cg.addHTML(
"<h2>Coarsener</h2>");
241 cg.AddHistGraph(x,y,yn,options);
252 cg.
addHTML(
"<h2>V cycle sweep</h2>");
253 for(
size_t k = 0 ; k < perf_amg_sweep_sym.size() / num_sweep_test ; k++)
261 for (
size_t i = 0 ; i < num_sweep_test ; i++)
262 x.add(v_cycle_tested_sym.get(i));
271 for (
size_t i = 0 ; i < num_sweep_test ; i++)
273 double score = score_solver(perf_amg_sweep_sym.get(k*num_sweep_test+i).time_solve,perf_amg_sweep_sym.get(k*num_sweep_test+i).residual);
274 y.add({perf_amg_sweep_sym.get(k*num_sweep_test+i).residual,perf_amg_sweep_sym.get(k*num_sweep_test+i).time_solve,score});
280 options.
title = std::string(
"Coarsener: " + coars.get(k)) + std::string(
": Overview of V cycle with n sweeps symmetrically up and down");
281 options.
yAxis = std::string(
"error/time/score");
282 options.
xAxis = std::string(
"sweeps");
283 options.
stype = std::string(
"bars");
284 options.
more = std::string(
"vAxis: {scaleType: 'log'}");
286 std::stringstream ss;
300 cg.
addHTML(
"<h2>V cycle sweep asymmetric test</h2>");
301 for(
size_t k = 0 ; k < coars.
size() ; k++)
308 size_t num_sweep_test = asym_tests.get(k+1) - asym_tests.get(k);
309 size_t sweep_start = asym_tests.get(k);
312 for (
size_t i = 0 ; i < num_sweep_test ; i++)
313 {x.add(std::string(
"(" + std::to_string(v_cycle_tested_asym.get(i+sweep_start).first) +
"," + std::to_string(v_cycle_tested_asym.get(i+sweep_start).second) +
")"));}
322 for (
size_t i = 0 ; i < num_sweep_test ; i++)
324 double score = score_solver(perf_amg_sweep_asym.get(sweep_start+i).time_solve,perf_amg_sweep_asym.get(sweep_start+i).residual);
325 y.add({perf_amg_sweep_asym.get(sweep_start+i).residual,perf_amg_sweep_asym.get(sweep_start+i).time_solve,score});
331 options.
title = std::string(
"Coarsener: " + coars.get(k)) + std::string(
": Overview of V cycle with n sweeps asymmetrically distributed");
332 options.
yAxis = std::string(
"error/time/score");
333 options.
xAxis = std::string(
"sweeps");
334 options.
stype = std::string(
"bars");
335 options.
more = std::string(
"vAxis: {scaleType: 'log'}");
337 std::stringstream ss;
354 Vcluster & v_cl = create_vcluster();
366 for (
size_t k = 0 ; k < coarsener_to_test.
size(); k++)
368 for (
size_t i = 1 ; i <= num_sweep_test ; i++)
380 A.getMatrixTriplets();
382 benchmark(A,b,solver,perf_amg_sweep_sym);
384 double score = score_solver(perf_amg_sweep_sym.get(k*num_sweep_test+(i-1)).time_solve,perf_amg_sweep_sym.get(k*num_sweep_test+(i-1)).residual);
385 perf_amg_sweep_sym.last().score = score;
388 std::cout <<
"Coarsener: " << coarsener_to_test.get(k) <<
" Sweep: " << i <<
" Score: " << score << std::endl;
390 v_cycle_tested_sym.add(i);
409 Vcluster & v_cl = create_vcluster();
421 for (
size_t k = 0 ; k < coarsener_to_test.
size(); k++)
423 asym_tests.add(perf_amg_sweep_asym.size());
424 size_t num_tot_sweep = 2*ids_ts.get(k);
425 for (
size_t i = 0 ; i <= num_tot_sweep ; i++)
437 A.getMatrixTriplets();
440 benchmark(A,b,solver,perf_amg_sweep_asym);
442 double score = score_solver(perf_amg_sweep_asym.last().time_solve,perf_amg_sweep_asym.last().residual);
445 std::cout <<
"Coarsener: " << coarsener_to_test.get(k) <<
" Sweep: (" << i <<
"," << num_tot_sweep-i <<
") Score: " << score << std::endl;
447 v_cycle_tested_asym.add(std::pair<size_t,size_t>(i,num_tot_sweep-i));
452 asym_tests.add(perf_amg_sweep_asym.size());
462 if (create_vcluster().getProcessUnitID() != 0)
466 write_report_coars(cg);
469 write_report_cycle(cg,coars);
471 write_report_cycle_asym(cg,coars);
473 cg.
write(
"gc_AMG_preconditioners.html");
484 double best_time = perf_amg_coars.get(0).time_solve;
486 double best_accuracy = perf_amg_coars.get(0).residual;
488 for (
size_t i = 1 ; i < perf_amg_coars.size() ; i++)
490 if (perf_amg_coars.get(i).time_solve < best_time)
493 best_time = perf_amg_coars.get(i).time_solve;
496 if (perf_amg_coars.get(i).residual < best_accuracy)
499 best_accuracy = perf_amg_coars.get(i).residual;
503 coars.add(method.get(fastest));
504 coars.add(method.get(accurate));
518 size_t page = perf.
size() / nm;
520 for (
size_t k = 0 ; k < nm ; k++)
522 int score_id = page*k;
523 double best_score = perf.get(score_id).score;
525 for (
size_t i = page*k ; i < page*k+page ; i++)
527 if (perf.get(i).score > best_score)
530 best_score = perf.get(i).score;
534 sw_optimal.add(v_cycle_tested_sym.get(score_id));
552 target_accuracy = t_a;
564 num_sweep_test = max_sw;
580 best_coarsener(coa_methods);
582 test_cycle_type(A,b,coa_methods);
584 best_score(perf_amg_sweep_sym,sweep_optimal,coa_methods.
size());
586 test_cycle_asym(A,b,sweep_optimal,coa_methods);
588 write_report(coa_methods);
Class to test AMG solvers.
void setPreconditioner(PCType type)
Set the preconditioner of the linear solver.
void log_monitor()
Set the Petsc solver.
openfpm::vector< AMG_time_err_coars > perf_amg_sweep_asym
It contain the performance of several AMG methods sweep configuration.
void addHTML(const std::string &html)
Add HTML text.
double score
assign a score to the solver
size_t getProcessUnitID()
Get the process unit id.
void execute()
Execute all the requests.
Sparse Matrix implementation stub object when OpenFPM is compiled with no linear algebra support...
std::string title
Title of the chart.
void setMaxIter(PetscInt n)
Set the maximum number of iteration for Krylov solvers.
void test_cycle_asym(SparseMatrix< double, int, PETSC_BASE > &A, const Vector< double, PETSC_BASE > &b, openfpm::vector< size_t > &ids_ts, openfpm::vector< std::string > &coarsener_to_test)
test best asymmetric combination of sweeps
It contain statistic of the error of the calculated solution.
size_t num_sweep_test
Number of sweeps for test.
void setPreconditionerAMG_cycleType(const std::string &cycle_type, int sweep_up=-1, int sweep_dw=-1, int sweep_crs=-1)
It set the type of cycle and optionally the number of sweep.
double time_solve
time to solve
double target_accuracy
Target accuracy for the preconditioner.
void setAbsTol(PetscReal abstol_)
Set the absolute tolerance as stop criteria.
Vector< double, PETSC_BASE > solve(SparseMatrix< double, int, PETSC_BASE > &A, const Vector< double, PETSC_BASE > &b, bool initial_guess=false)
Here we invert the matrix and solve the system.
void max(T &num)
Get the maximum number across all processors (or reduction with infinity norm)
double getwct()
Return the elapsed real time.
openfpm::vector< size_t > asym_tests
starting point of each coarsening test for the asymmetric test
Implementation of VCluster class.
void setPreconditionerAMG_maxit(int nit)
Set the maximum number of V or W cycle for algebraic-multi-grid.
std::string yAxis
Y axis name.
void best_coarsener(openfpm::vector< std::string > &coars)
take the most accurate and the fastest AMG
void try_solve(SparseMatrix< double, int, PETSC_BASE > &A, const Vector< double, PETSC_BASE > &b)
Try to use AMG pre-conditioner and check how they they perform.
void test_cycle_type(SparseMatrix< double, int, PETSC_BASE > &A, const Vector< double, PETSC_BASE > &b, openfpm::vector< std::string > &coarsener_to_test)
test the corasener for this problem
Small class to produce graph with Google chart in HTML.
Sparse Matrix implementation.
openfpm::vector< size_t > v_cycle_tested_sym
List of tested cycles.
void setPreconditionerAMG_nl(int nl)
Set the number of levels for the algebraic-multigrid preconditioner.
This class is able to do Matrix inversion in parallel with PETSC solvers.
void setMaxSweep(int max_sw)
Set the target accuracy to score the AMG solver.
void write_report(openfpm::vector< std::string > &coars)
void setSolver(KSPType type)
Set the Petsc solver.
void start()
Start the timer.
void benchmark(SparseMatrix< double, int, PETSC_BASE > &A, const Vector< double, PETSC_BASE > &b, petsc_solver< double > &solver, openfpm::vector< AMG_time_err_coars > &perf_amg)
benchmark the selected setting for the preconditioner
void write_report_cycle(GoogleChart &cg, openfpm::vector< std::string > &coars)
Write the report for coarsening.
openfpm::vector< AMG_time_err_coars > perf_amg_sweep_sym
It contain the performance of several AMG methods sweep configuration.
openfpm::vector< std::pair< size_t, size_t > > v_cycle_tested_asym
List of tested cycles in case of asymmetric.
It contain information about the performance of the AMG.
void best_score(openfpm::vector< AMG_time_err_coars > &perf, openfpm::vector< size_t > &sw_optimal, size_t nm)
Return the best scoring solver.
void write(std::string file)
It write the graphs on file in html format using Google charts.
openfpm::vector< std::string > method
List of methods.
void setPreconditionerAMG_coarsen(const std::string &type)
Set the coarsening method for the algebraic-multi-grid preconditioner.
void write_report_cycle_asym(GoogleChart &cg, openfpm::vector< std::string > &coars)
Write the report for coarsening.
double score_solver(double t_solve, double t_m)
Score the solver.
double time_setup
time to setup
void setPreconditionerAMG_relax(const std::string &type, int k=REL_ALL)
Set the relaxation method for the algebraic-multi-grid preconditioner.
void AddHistGraph(openfpm::vector< Y > &y)
Add an histogram graph.
void write_report_coars(GoogleChart &cg)
Write the report for coarsening.
solError get_residual_error(SparseMatrix< double, int, PETSC_BASE > &A, const Vector< double, PETSC_BASE > &x, const Vector< double, PETSC_BASE > &b)
It return the resiual error.
std::string xAxis
X axis name.
void setTergetAMGAccuracy(double t_a)
Set the target accuracy to score the AMG solver.
double residual
residual norm
void test_coarsener(SparseMatrix< double, int, PETSC_BASE > &A, const Vector< double, PETSC_BASE > &b)
test the corasener for this problem
Class for cpu time benchmarking.
void setPreconditionerAMG_coarsenNodalType(int norm)
Set the block coarsening norm type.
void stop()
Stop the timer.
openfpm::vector< AMG_time_err_coars > perf_amg_coars
It contains the performance of several AMG methods coarsener.
PetscReal err_inf
infinity norm of the error