22#ifndef INCLUDE_EXADG_UTILITIES_PRINT_SOLVER_RESULTS_H_
23#define INCLUDE_EXADG_UTILITIES_PRINT_SOLVER_RESULTS_H_
29#include <deal.II/base/conditional_ostream.h>
30#include <deal.II/base/mpi.h>
31#include <deal.II/base/utilities.h>
34#include <exadg/utilities/print_functions.h>
40 std::vector<std::tuple<unsigned int, dealii::types::global_dof_index, double>>
const & wall_times,
41 std::string
const & operator_type,
42 MPI_Comm
const & mpi_comm)
44 unsigned int N_mpi_processes = dealii::Utilities::MPI::n_mpi_processes(mpi_comm);
46 if(dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0)
49 std::cout << std::endl
50 << print_horizontal_line()
51 << std::endl << std::endl
52 <<
"Operator type: " << operator_type
53 << std::endl << std::endl
54 << std::setw(5) << std::left <<
"k"
55 << std::setw(15) << std::left <<
"DoFs"
56 << std::setw(15) << std::left <<
"DoFs/sec"
57 << std::setw(15) << std::left <<
"DoFs/(sec*core)"
58 << std::endl << std::flush;
60 typedef typename std::vector<std::tuple<unsigned int, dealii::types::global_dof_index, double> >::const_iterator ITERATOR;
61 for(ITERATOR it = wall_times.begin(); it != wall_times.end(); ++it)
63 std::cout << std::setw(5) << std::left << std::get<0>(*it)
64 << std::scientific << std::setprecision(4)
65 << std::setw(15) << std::left << (double)std::get<1>(*it)
66 << std::setw(15) << std::left << std::get<2>(*it)
67 << std::setw(15) << std::left << std::get<2>(*it)/(double)N_mpi_processes
68 << std::endl << std::flush;
71 std::cout << print_horizontal_line() << std::endl << std::endl << std::flush;
77print_throughput_steady(dealii::ConditionalOStream
const & pcout,
78 dealii::types::global_dof_index
const n_dofs,
79 double const overall_time_avg,
80 unsigned int const N_mpi_processes)
84 <<
"Throughput:" << std::endl
85 <<
" Number of MPI processes = " << N_mpi_processes << std::endl
86 <<
" Degrees of freedom = " << n_dofs << std::endl
87 <<
" Wall time = " << std::scientific << std::setprecision(2) << overall_time_avg <<
" s" << std::endl
88 <<
" Throughput = " << std::scientific << std::setprecision(2) << n_dofs / (overall_time_avg * N_mpi_processes) <<
" DoFs/s/core" << std::endl
94print_throughput_10(dealii::ConditionalOStream
const & pcout,
95 dealii::types::global_dof_index
const n_dofs,
97 unsigned int const N_mpi_processes)
99 double const tau_10 = t_10 * (double)N_mpi_processes / n_dofs;
103 <<
"Throughput of linear solver (numbers based on n_10):" << std::endl
104 <<
" Number of MPI processes = " << N_mpi_processes << std::endl
105 <<
" Degrees of freedom = " << n_dofs << std::endl
106 <<
" Wall time t_10 = " << std::scientific << std::setprecision(2) << t_10 <<
" s" << std::endl
107 <<
" tau_10 = " << std::scientific << std::setprecision(2) << tau_10 <<
" s*core/DoF" << std::endl
108 <<
" Throughput E_10 = " << std::scientific << std::setprecision(2) << 1.0 / tau_10 <<
" DoF/s/core" << std::endl
114print_throughput_unsteady(dealii::ConditionalOStream
const & pcout,
115 dealii::types::global_dof_index
const n_dofs,
116 double const overall_time_avg,
117 unsigned int const N_time_steps,
118 unsigned int const N_mpi_processes)
120 double const time_per_timestep = overall_time_avg / (double)N_time_steps;
124 <<
"Throughput per time step:" << std::endl
125 <<
" Number of MPI processes = " << N_mpi_processes << std::endl
126 <<
" Degrees of freedom = " << n_dofs << std::endl
127 <<
" Wall time = " << std::scientific << std::setprecision(2) << overall_time_avg <<
" s" << std::endl
128 <<
" Time steps = " << std::left << N_time_steps << std::endl
129 <<
" Wall time per time step = " << std::scientific << std::setprecision(2) << time_per_timestep <<
" s" << std::endl
130 <<
" Throughput = " << std::scientific << std::setprecision(2) << n_dofs / (time_per_timestep * N_mpi_processes) <<
" DoFs/s/core" << std::endl
136print_throughput_unsteady(dealii::ConditionalOStream
const & pcout,
137 double const avg_n_dofs,
138 double const overall_time_avg,
139 unsigned int const N_time_steps,
140 unsigned int const N_mpi_processes)
142 double const time_per_timestep = overall_time_avg / (double)N_time_steps;
146 <<
"Throughput per time step:" << std::endl
147 <<
" Number of MPI processes = " << N_mpi_processes << std::endl
148 <<
" Average Degrees of freedom = " << std::scientific << std::setprecision(2)<< avg_n_dofs << std::endl
149 <<
" Wall time = " << std::scientific << std::setprecision(2) << overall_time_avg <<
" s" << std::endl
150 <<
" Time steps = " << std::left << N_time_steps << std::endl
151 <<
" Wall time per time step = " << std::scientific << std::setprecision(2) << time_per_timestep <<
" s" << std::endl
152 <<
" Throughput = " << std::scientific << std::setprecision(2) << avg_n_dofs / (time_per_timestep * N_mpi_processes) <<
" DoFs/s/core" << std::endl
158print_costs(dealii::ConditionalOStream
const & pcout,
159 double const overall_time_avg,
160 unsigned int const N_mpi_processes)
165 <<
"Computational costs:" << std::endl
166 <<
" Number of MPI processes = " << N_mpi_processes << std::endl
167 <<
" Wall time = " << std::scientific << std::setprecision(2) << overall_time_avg <<
" s" << std::endl
168 <<
" Computational costs = " << std::scientific << std::setprecision(2) << overall_time_avg * (double)N_mpi_processes / 3600.0 <<
" CPUh" << std::endl
174print_solver_info_nonlinear(dealii::ConditionalOStream
const & pcout,
175 unsigned int const N_iter_nonlinear,
176 unsigned int const N_iter_linear,
177 double const wall_time)
180 double const N_iter_linear_avg =
181 (N_iter_nonlinear > 0) ?
double(N_iter_linear) / double(N_iter_nonlinear) : N_iter_linear;
185 <<
" Newton iterations: " << std::setw(12) << std::right << N_iter_nonlinear << std::endl
186 <<
" Linear iterations (avg):" << std::setw(12) << std::fixed << std::setprecision(1) << std::right << N_iter_linear_avg << std::endl
187 <<
" Linear iterations (tot):" << std::setw(12) << std::right << N_iter_linear << std::endl
188 <<
" Wall time [s]: " << std::setw(12) << std::scientific << std::setprecision(2) << std::right << wall_time << std::endl
194print_solver_info_linear(dealii::ConditionalOStream
const & pcout,
195 unsigned int const N_iter_linear,
196 double const wall_time)
201 <<
" Iterations: " << std::setw(12) << std::right << N_iter_linear << std::endl
202 <<
" Wall time [s]:" << std::setw(12) << std::scientific << std::setprecision(2) << std::right << wall_time << std::endl
208print_wall_time(dealii::ConditionalOStream
const & pcout,
double const wall_time)
213 <<
" Wall time [s]:" << std::setw(12) << std::scientific << std::setprecision(2) << std::right << wall_time << std::endl
219print_list_of_iterations(dealii::ConditionalOStream
const & pcout,
220 std::vector<std::string>
const & names,
221 std::vector<double>
const & iterations_avg)
223 unsigned int length = 1;
224 for(
unsigned int i = 0; i < names.size(); ++i)
226 length = length > names[i].length() ? length : names[i].length();
230 for(
unsigned int i = 0; i < iterations_avg.size(); ++i)
232 pcout <<
" " << std::setw(length + 2) << std::left << names[i] << std::fixed
233 << std::setprecision(2) << std::right << std::setw(6) << iterations_avg[i] << std::endl;
239 SolverResult() : degree(1), dofs(1), n_10(0), tau_10(0.0)
243 SolverResult(
unsigned int const degree_,
244 dealii::types::global_dof_index
const dofs_,
246 double const tau_10_)
247 : degree(degree_), dofs(dofs_), n_10(n_10_), tau_10(tau_10_)
252 print_header(dealii::ConditionalOStream
const & pcout)
255 pcout << std::setw(7) <<
"degree";
256 pcout << std::setw(15) <<
"dofs";
257 pcout << std::setw(8) <<
"n_10";
258 pcout << std::setw(15) <<
"tau_10";
259 pcout << std::setw(15) <<
"throughput";
263 pcout << std::setw(7) <<
" ";
264 pcout << std::setw(15) <<
" ";
265 pcout << std::setw(8) <<
" ";
266 pcout << std::setw(15) <<
"in s*core/DoF";
267 pcout << std::setw(15) <<
"in DoF/s/core";
274 print(dealii::ConditionalOStream
const & pcout)
const
276 pcout << std::setw(7) << std::fixed << degree;
277 pcout << std::setw(15) << std::fixed << dofs;
278 pcout << std::setw(8) << std::fixed << std::setprecision(1) << n_10;
279 pcout << std::setw(15) << std::scientific << std::setprecision(2) << tau_10;
280 pcout << std::setw(15) << std::scientific << std::setprecision(2) << 1.0 / tau_10;
285 dealii::types::global_dof_index dofs;
237struct SolverResult {
…};
291print_results(std::vector<SolverResult>
const & results, MPI_Comm
const & mpi_comm)
294 dealii::ConditionalOStream pcout(std::cout,
295 dealii::Utilities::MPI::this_mpi_process(mpi_comm) == 0);
297 pcout << std::endl << print_horizontal_line() << std::endl << std::endl;
299 pcout <<
"Summary of results:" << std::endl << std::endl;
301 SolverResult::print_header(pcout);
302 for(std::vector<SolverResult>::const_iterator it = results.begin(); it != results.end(); ++it)
305 pcout << print_horizontal_line() << std::endl << std::endl;