ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
TuningAlgorithm.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010
4 * Max-Planck-Institute for Polymer Research, Theory Group
5 *
6 * This file is part of ESPResSo.
7 *
8 * ESPResSo is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * ESPResSo is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#pragma once
23
24#include "config/config.hpp"
25
26#if defined(P3M) || defined(DP3M)
27
28#include "p3m/TuningLogger.hpp"
29#include "p3m/common.hpp"
30
31#include <utils/Vector.hpp>
32
33#include <cstddef>
34#include <limits>
35#include <memory>
36#include <optional>
37#include <string>
38#include <tuple>
39
40namespace System {
41class System;
42}
43
44/**
45 * @brief Tuning algorithm for P3M.
46 *
47 * The algorithm basically determines the mesh, cao
48 * and then the real-space cutoff, in this order.
49 *
50 * For each mesh, the optimal cao for the previous mesh is re-used as an
51 * initial guess, and the algorithm checks whether increasing or decreasing
52 * it leads to a better solution. This is efficient, since the optimal cao
53 * only changes little with the meshes in general.
54 *
55 * The real-space cutoff for a given mesh and cao is determined via a
56 * bisection on the error estimate, which determines where the error
57 * estimate equals the required accuracy. Therefore the smallest possible,
58 * i.e. fastest real-space cutoff is determined.
59 *
60 * Both the search over mesh and cao stop to search in a specific
61 * direction once the computation time is significantly higher
62 * than the currently known optimum.
63 */
65protected:
67
68private:
69 int m_timings;
70 std::size_t m_n_trials;
71
72protected:
74 std::unique_ptr<TuningLogger> m_logger = nullptr;
75 int cao_min = -1, cao_max = -1, cao_best = -1;
76 double m_r_cut_iL_min = -1., m_r_cut_iL_max = -1.;
77
78 /**
79 * @brief Granularity of the time measurement (milliseconds).
80 * Tuning halts when the runtime is larger than the best time plus this value.
81 */
82 static auto constexpr time_granularity = 2.;
83
84 /**
85 * @brief Maximal number of consecutive trials that don't improve runtime.
86 * Tuning halts when this threshold is reached.
87 */
88 static auto constexpr max_n_consecutive_trials = 20;
89
90 /** @brief Value for invalid time measurements. */
91 static auto constexpr time_sentinel = std::numeric_limits<double>::max();
92
93public:
94 TuningAlgorithm(System::System &system, double prefactor, int timings)
95 : m_system{system}, m_timings{timings}, m_n_trials{0ul},
96 m_prefactor{prefactor} {}
97
98 virtual ~TuningAlgorithm() = default;
99
100 struct Parameters {
102 int cao = -1;
103 double alpha_L = -1.;
104 double r_cut_iL = -1.;
105 double accuracy = -1.;
106 double time = std::numeric_limits<double>::max();
107 };
108
109 /** @brief Get the P3M parameters. */
110 virtual P3MParameters &get_params() = 0;
111
112 /** @brief Re-initialize the currently active solver. */
113 virtual void on_solver_change() const = 0;
114
115 /** @brief Tuning loop entry point. */
117
118 /** @brief Configure the logger. */
119 virtual void setup_logger(bool verbose) = 0;
120
121 /** @brief Determine a sensible range for the mesh. */
122 virtual void determine_mesh_limits() = 0;
123
124 /** @brief Determine a sensible range for the real-space cutoff. */
126
127 /** @brief Determine a sensible range for the charge assignment order. */
128 void determine_cao_limits(int initial_cao);
129
130 /**
131 * @brief Get the minimal error for this combination of parameters.
132 *
133 * The real-space error is tuned such that it contributes half of the
134 * total error, and then the k-space error is calculated.
135 * If an optimal alpha is not found, the value 0.1 is used as fallback.
136 * @param[in] mesh @copybrief P3MParameters::mesh
137 * @param[in] cao @copybrief P3MParameters::cao
138 * @param[in] r_cut_iL @copybrief P3MParameters::r_cut_iL
139 * @returns Error magnitude, real-space error, k-space error,
140 * @copybrief P3MParameters::alpha_L
141 */
142 virtual std::tuple<double, double, double, double>
144 double r_cut_iL) const = 0;
145
146 /** @brief Veto real-space cutoffs larger than the layer correction gap. */
147 virtual std::optional<std::string>
148 layer_correction_veto_r_cut(double r_cut) const = 0;
149
150 /** @brief Veto FFT decomposition in non-cubic boxes. */
151 virtual std::optional<std::string>
153 return std::nullopt;
154 }
155
156 /** @brief Write tuned parameters to the P3M parameter struct. */
157 void commit(Utils::Vector3i const &mesh, int cao, double r_cut_iL,
158 double alpha_L);
159
160 void tune() {
161 // activate tuning mode
162 get_params().tuning = true;
163
164 auto const tuned_params = get_time();
165
166 // deactivate tuning mode
167 get_params().tuning = false;
168
169 if (tuned_params.time == time_sentinel) {
170 throw std::runtime_error(m_logger->get_name() +
171 ": failed to reach requested accuracy");
172 }
173 // set tuned parameters
174 get_params().accuracy = tuned_params.accuracy;
175 commit(tuned_params.mesh, tuned_params.cao, tuned_params.r_cut_iL,
176 tuned_params.alpha_L);
177
178 m_logger->tuning_results(tuned_params.mesh, tuned_params.cao,
179 tuned_params.r_cut_iL, tuned_params.alpha_L,
180 tuned_params.accuracy, tuned_params.time);
181 }
182
183protected:
184 auto get_n_trials() { return m_n_trials; }
185 void increment_n_trials() { ++m_n_trials; }
186 void reset_n_trials() { m_n_trials = 0ul; }
187 double get_m_time(Utils::Vector3i const &mesh, int &tuned_cao,
188 double &tuned_r_cut_iL, double &tuned_alpha_L,
189 double &tuned_accuracy);
190 double get_mc_time(Utils::Vector3i const &mesh, int cao,
191 double &tuned_r_cut_iL, double &tuned_alpha_L,
192 double &tuned_accuracy);
193};
194
195#endif // P3M or DP3M
Vector implementation and trait types for boost qvm interoperability.
Main system class.
Tuning algorithm for P3M.
double get_m_time(Utils::Vector3i const &mesh, int &tuned_cao, double &tuned_r_cut_iL, double &tuned_alpha_L, double &tuned_accuracy)
Get the optimal alpha and the corresponding computation time for a fixed mesh.
static auto constexpr time_sentinel
Value for invalid time measurements.
virtual void determine_mesh_limits()=0
Determine a sensible range for the mesh.
virtual std::optional< std::string > fft_decomposition_veto(Utils::Vector3i const &) const
Veto FFT decomposition in non-cubic boxes.
virtual void setup_logger(bool verbose)=0
Configure the logger.
virtual TuningAlgorithm::Parameters get_time()=0
Tuning loop entry point.
static auto constexpr max_n_consecutive_trials
Maximal number of consecutive trials that don't improve runtime.
System::System & m_system
virtual ~TuningAlgorithm()=default
virtual void on_solver_change() const =0
Re-initialize the currently active solver.
double get_mc_time(Utils::Vector3i const &mesh, int cao, double &tuned_r_cut_iL, double &tuned_alpha_L, double &tuned_accuracy)
Get the optimal alpha and the corresponding computation time for a fixed mesh and cao.
virtual std::tuple< double, double, double, double > calculate_accuracy(Utils::Vector3i const &mesh, int cao, double r_cut_iL) const =0
Get the minimal error for this combination of parameters.
virtual std::optional< std::string > layer_correction_veto_r_cut(double r_cut) const =0
Veto real-space cutoffs larger than the layer correction gap.
void commit(Utils::Vector3i const &mesh, int cao, double r_cut_iL, double alpha_L)
Write tuned parameters to the P3M parameter struct.
void determine_cao_limits(int initial_cao)
Determine a sensible range for the charge assignment order.
TuningAlgorithm(System::System &system, double prefactor, int timings)
void determine_r_cut_limits()
Determine a sensible range for the real-space cutoff.
virtual P3MParameters & get_params()=0
Get the P3M parameters.
std::unique_ptr< TuningLogger > m_logger
static auto constexpr time_granularity
Granularity of the time measurement (milliseconds).
This file contains the defaults for ESPResSo.
Common functions for dipolar and charge P3M.
Structure to hold P3M parameters and some dependent variables.
double accuracy
accuracy of the actual parameter set.
bool tuning
tuning or production?