]> https://gitweb.dealii.org/ - dealii.git/commitdiff
Add a test. 13564/head
authorWolfgang Bangerth <bangerth@colostate.edu>
Tue, 22 Mar 2022 23:37:57 +0000 (17:37 -0600)
committerWolfgang Bangerth <bangerth@colostate.edu>
Tue, 22 Mar 2022 23:37:57 +0000 (17:37 -0600)
tests/performance/instrumentation_step_3_count_cycles.cc [new file with mode: 0644]
tests/performance/instrumentation_step_3_count_cycles.with_valgrind=true.threads=1.release.run_only [new file with mode: 0644]

diff --git a/tests/performance/instrumentation_step_3_count_cycles.cc b/tests/performance/instrumentation_step_3_count_cycles.cc
new file mode 100644 (file)
index 0000000..fe9ee0e
--- /dev/null
@@ -0,0 +1,257 @@
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2022 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+//
+// Description:
+//
+// A performance benchmark based on step 3 that measures the number of
+// instruction cycles for system setup, assembly, solve and postprocessing
+// for a Stokes problem.
+//
+// Status: experimental
+//
+
+#include <deal.II/base/function.h>
+#include <deal.II/base/quadrature_lib.h>
+#include <deal.II/base/timer.h>
+
+#include <deal.II/dofs/dof_handler.h>
+#include <deal.II/dofs/dof_tools.h>
+
+#include <deal.II/fe/fe_q.h>
+#include <deal.II/fe/fe_values.h>
+
+#include <deal.II/grid/grid_generator.h>
+#include <deal.II/grid/tria.h>
+
+#include <deal.II/lac/dynamic_sparsity_pattern.h>
+#include <deal.II/lac/full_matrix.h>
+#include <deal.II/lac/precondition.h>
+#include <deal.II/lac/solver_cg.h>
+#include <deal.II/lac/sparse_matrix.h>
+#include <deal.II/lac/vector.h>
+
+#include <deal.II/numerics/data_out.h>
+#include <deal.II/numerics/matrix_tools.h>
+#include <deal.II/numerics/vector_tools.h>
+
+#include "performance_test_driver.h"
+#include "valgrind_instrumentation.h"
+
+using namespace dealii;
+
+dealii::ConditionalOStream debug_output(std::cout, false);
+
+class Step3
+{
+public:
+  Step3();
+
+  Measurement
+  run();
+
+private:
+  void
+  make_grid();
+  void
+  setup_system();
+  void
+  assemble_system();
+  void
+  solve();
+  void
+  output_results() const;
+
+  Triangulation<2> triangulation;
+  FE_Q<2>          fe;
+  DoFHandler<2>    dof_handler;
+
+  SparsityPattern      sparsity_pattern;
+  SparseMatrix<double> system_matrix;
+
+  Vector<double> solution;
+  Vector<double> system_rhs;
+};
+
+
+Step3::Step3()
+  : fe(1)
+  , dof_handler(triangulation)
+{}
+
+
+void
+Step3::make_grid()
+{
+  GridGenerator::hyper_cube(triangulation, -1, 1);
+
+  switch (get_testing_environment())
+    {
+      case TestingEnvironment::light:
+        triangulation.refine_global(6);
+        break;
+      case TestingEnvironment::medium:
+        DEAL_II_FALLTHROUGH;
+      case TestingEnvironment::heavy:
+        triangulation.refine_global(7);
+        break;
+    }
+
+  debug_output << "Number of active cells: " << triangulation.n_active_cells()
+               << std::endl;
+}
+
+
+void
+Step3::setup_system()
+{
+  dof_handler.distribute_dofs(fe);
+  debug_output << "Number of degrees of freedom: " << dof_handler.n_dofs()
+               << std::endl;
+
+  DynamicSparsityPattern dsp(dof_handler.n_dofs());
+  DoFTools::make_sparsity_pattern(dof_handler, dsp);
+  sparsity_pattern.copy_from(dsp);
+
+  system_matrix.reinit(sparsity_pattern);
+
+  solution.reinit(dof_handler.n_dofs());
+  system_rhs.reinit(dof_handler.n_dofs());
+}
+
+
+void
+Step3::assemble_system()
+{
+  QGauss<2>   quadrature_formula(fe.degree + 1);
+  FEValues<2> fe_values(fe,
+                        quadrature_formula,
+                        update_values | update_gradients | update_JxW_values);
+
+  const unsigned int dofs_per_cell = fe.n_dofs_per_cell();
+
+  FullMatrix<double> cell_matrix(dofs_per_cell, dofs_per_cell);
+  Vector<double>     cell_rhs(dofs_per_cell);
+
+  std::vector<types::global_dof_index> local_dof_indices(dofs_per_cell);
+
+  for (const auto &cell : dof_handler.active_cell_iterators())
+    {
+      fe_values.reinit(cell);
+
+      cell_matrix = 0;
+      cell_rhs    = 0;
+
+      for (const unsigned int q_index : fe_values.quadrature_point_indices())
+        {
+          for (const unsigned int i : fe_values.dof_indices())
+            for (const unsigned int j : fe_values.dof_indices())
+              cell_matrix(i, j) +=
+                (fe_values.shape_grad(i, q_index) * // grad phi_i(x_q)
+                 fe_values.shape_grad(j, q_index) * // grad phi_j(x_q)
+                 fe_values.JxW(q_index));           // dx
+
+          for (const unsigned int i : fe_values.dof_indices())
+            cell_rhs(i) += (fe_values.shape_value(i, q_index) * // phi_i(x_q)
+                            1. *                                // f(x_q)
+                            fe_values.JxW(q_index));            // dx
+        }
+      cell->get_dof_indices(local_dof_indices);
+
+      for (const unsigned int i : fe_values.dof_indices())
+        for (const unsigned int j : fe_values.dof_indices())
+          system_matrix.add(local_dof_indices[i],
+                            local_dof_indices[j],
+                            cell_matrix(i, j));
+
+      for (const unsigned int i : fe_values.dof_indices())
+        system_rhs(local_dof_indices[i]) += cell_rhs(i);
+    }
+
+
+  std::map<types::global_dof_index, double> boundary_values;
+  VectorTools::interpolate_boundary_values(dof_handler,
+                                           0,
+                                           Functions::ZeroFunction<2>(),
+                                           boundary_values);
+  MatrixTools::apply_boundary_values(boundary_values,
+                                     system_matrix,
+                                     solution,
+                                     system_rhs);
+}
+
+
+void
+Step3::solve()
+{
+  SolverControl            solver_control(1000, 1e-6 * system_rhs.l2_norm());
+  SolverCG<Vector<double>> solver(solver_control);
+  PreconditionSSOR<SparseMatrix<double>> preconditioner;
+  preconditioner.initialize(system_matrix, 1.2);
+  solver.solve(system_matrix, solution, system_rhs, preconditioner);
+}
+
+
+void
+Step3::output_results() const
+{
+  DataOut<2> data_out;
+  data_out.attach_dof_handler(dof_handler);
+  data_out.add_data_vector(solution, "solution");
+  data_out.build_patches();
+}
+
+
+Measurement
+Step3::run()
+{
+  std::map<std::string, std::uint64_t> cycle_count;
+
+  cycle_count["make_grid"] =
+    CallgrindWrapper::count_cycles([this]() { make_grid(); });
+  cycle_count["setup_system"] =
+    CallgrindWrapper::count_cycles([this]() { setup_system(); });
+  cycle_count["assemble_system"] =
+    CallgrindWrapper::count_cycles([this]() { assemble_system(); });
+  cycle_count["solve"] = CallgrindWrapper::count_cycles([this]() { solve(); });
+  cycle_count["output_results"] =
+    CallgrindWrapper::count_cycles([this]() { output_results(); });
+
+  return {cycle_count["make_grid"],
+          cycle_count["setup_system"],
+          cycle_count["assemble_system"],
+          cycle_count["solve"],
+          cycle_count["output_results"]};
+}
+
+
+std::tuple<Metric, unsigned int, std::vector<std::string>>
+describe_measurements()
+{
+  return {Metric::instruction_count,
+          1,
+          {"make_grid",
+           "setup_system",
+           "assemble_system",
+           "solve",
+           "output_results"}};
+}
+
+
+Measurement
+perform_single_measurement()
+{
+  return Step3().run();
+}
diff --git a/tests/performance/instrumentation_step_3_count_cycles.with_valgrind=true.threads=1.release.run_only b/tests/performance/instrumentation_step_3_count_cycles.with_valgrind=true.threads=1.release.run_only
new file mode 100644 (file)
index 0000000..e69de29

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.