From ad3b6d825e525732a2a7f7eff3c2982a132d653f Mon Sep 17 00:00:00 2001 From: Alexander Reinauer Date: Tue, 22 Dec 2020 18:25:49 +0100 Subject: [PATCH 1/5] core: p3m: replaced strcat_alloc with std::printf and added verbose parameter --- .../electrostatics_magnetostatics/p3m.cpp | 133 ++++++++++-------- .../electrostatics_magnetostatics/p3m.hpp | 4 +- src/python/espressomd/electrostatics.pxd | 14 +- src/python/espressomd/electrostatics.pyx | 16 +-- testsuite/python/p3m_tuning_exceptions.py | 12 +- 5 files changed, 92 insertions(+), 87 deletions(-) diff --git a/src/core/electrostatics_magnetostatics/p3m.cpp b/src/core/electrostatics_magnetostatics/p3m.cpp index 52af9de6251..2a9b2d5bd66 100644 --- a/src/core/electrostatics_magnetostatics/p3m.cpp +++ b/src/core/electrostatics_magnetostatics/p3m.cpp @@ -52,7 +52,6 @@ #include #include #include -#include #include #include @@ -69,7 +68,6 @@ #include using Utils::sinc; -using Utils::strcat_alloc; p3m_data_struct p3m; @@ -694,7 +692,6 @@ static double p3m_mcr_time(const int mesh[3], int cao, double r_cut_iL, * * The @p _r_cut_iL is determined via a simple bisection. * - * @param[out] log log output * @param[in] mesh @copybrief P3MParameters::mesh * @param[in] cao @copybrief P3MParameters::cao * @param[in] r_cut_iL_min lower bound for @p _r_cut_iL @@ -702,17 +699,16 @@ static double p3m_mcr_time(const int mesh[3], int cao, double r_cut_iL, * @param[out] _r_cut_iL @copybrief P3MParameters::r_cut_iL * @param[out] _alpha_L @copybrief P3MParameters::alpha_L * @param[out] _accuracy @copybrief P3MParameters::accuracy + * @param[in] verbose printf output * * @returns The integration time in case of success, otherwise * -@ref P3M_TUNE_FAIL, -@ref P3M_TUNE_ACCURACY_TOO_LARGE, * -@ref P3M_TUNE_CAO_TOO_LARGE, or -@ref P3M_TUNE_ELCTEST */ -static double p3m_mc_time(char **log, const int mesh[3], int cao, - double r_cut_iL_min, double r_cut_iL_max, - double *_r_cut_iL, double *_alpha_L, - double *_accuracy) { +static double p3m_mc_time(const int mesh[3], int cao, double r_cut_iL_min, + double r_cut_iL_max, double *_r_cut_iL, + double *_alpha_L, double *_accuracy, bool verbose) { double rs_err, ks_err; - char b[5 * ES_DOUBLE_SPACE + 3 * ES_INTEGER_SPACE + 128]; /* initial checks. */ auto const k_cut = @@ -725,8 +721,9 @@ static double p3m_mc_time(char **log, const int mesh[3], int cao, if (cao >= std::min(mesh[0], std::min(mesh[1], mesh[2])) || k_cut >= (std::min(min_box_l, min_local_box_l) - skin)) { - sprintf(b, "%-4d %-3d cao too large for this mesh\n", mesh[0], cao); - *log = strcat_alloc(*log, b); + if (verbose) { + std::printf("%-4d %-3d cao too large for this mesh\n", mesh[0], cao); + } return -P3M_TUNE_CAO_TOO_LARGE; } @@ -737,9 +734,11 @@ static double p3m_mc_time(char **log, const int mesh[3], int cao, if ((*_accuracy = p3m_get_accuracy(mesh, cao, r_cut_iL_max, _alpha_L, &rs_err, &ks_err)) > p3m.params.accuracy) { /* print result */ - sprintf(b, "%-4d %-3d %.5e %.5e %.5e %.3e %.3e accuracy not achieved\n", - mesh[0], cao, r_cut_iL_max, *_alpha_L, *_accuracy, rs_err, ks_err); - *log = strcat_alloc(*log, b); + if (verbose) { + std::printf("%-4d %-3d %.5e %.5e %.5e %.3e %.3e accuracy not achieved\n", + mesh[0], cao, r_cut_iL_max, *_alpha_L, *_accuracy, rs_err, + ks_err); + } return -P3M_TUNE_ACCURACY_TOO_LARGE; } @@ -768,15 +767,19 @@ static double p3m_mc_time(char **log, const int mesh[3], int cao, if (coulomb.method == COULOMB_ELC_P3M && elc_params.gap_size <= 1.1 * r_cut_iL * box_geo.length()[0]) { /* print result */ - sprintf(b, "%-4d %-3d %.5e %.5e %.5e %.3e %.3e conflict with ELC\n", - mesh[0], cao, r_cut_iL, *_alpha_L, *_accuracy, rs_err, ks_err); - *log = strcat_alloc(*log, b); + if (verbose) { + std::printf("%-4d %-3d %.5e %.5e %.5e %.3e %.3e conflict with ELC\n", + mesh[0], cao, r_cut_iL, *_alpha_L, *_accuracy, rs_err, + ks_err); + } return -P3M_TUNE_ELCTEST; } auto const int_time = p3m_mcr_time(mesh, cao, r_cut_iL, *_alpha_L); if (int_time == -P3M_TUNE_FAIL) { - *log = strcat_alloc(*log, "tuning failed, test integration not possible\n"); + if (verbose) { + std::printf("tuning failed, test integration not possible\n"); + } return int_time; } @@ -784,9 +787,10 @@ static double p3m_mc_time(char **log, const int mesh[3], int cao, p3m_get_accuracy(mesh, cao, r_cut_iL, _alpha_L, &rs_err, &ks_err); /* print result */ - sprintf(b, "%-4d %-3d %.5e %.5e %.5e %.3e %.3e %-8.2f\n", mesh[0], cao, - r_cut_iL, *_alpha_L, *_accuracy, rs_err, ks_err, int_time); - *log = strcat_alloc(*log, b); + if (verbose) { + std::printf("%-4d %-3d %.5e %.5e %.5e %.3e %.3e %-8.2f\n", mesh[0], cao, + r_cut_iL, *_alpha_L, *_accuracy, rs_err, ks_err, int_time); + } return int_time; } @@ -796,7 +800,6 @@ static double p3m_mc_time(char **log, const int mesh[3], int cao, * @p _cao should contain an initial guess, which is then adapted by stepping * up and down. * - * @param[out] log log output * @param[in] mesh @copybrief P3MParameters::mesh * @param[in] cao_min lower bound for @p _cao * @param[in] cao_max upper bound for @p _cao @@ -807,14 +810,15 @@ static double p3m_mc_time(char **log, const int mesh[3], int cao, * @param[out] _r_cut_iL @copybrief P3MParameters::r_cut_iL * @param[out] _alpha_L @copybrief P3MParameters::alpha_L * @param[out] _accuracy @copybrief P3MParameters::accuracy + * @param[in] verbose printf output * * @returns The integration time in case of success, otherwise * -@ref P3M_TUNE_FAIL or -@ref P3M_TUNE_CAO_TOO_LARGE */ -static double p3m_m_time(char **log, const int mesh[3], int cao_min, - int cao_max, int *_cao, double r_cut_iL_min, - double r_cut_iL_max, double *_r_cut_iL, - double *_alpha_L, double *_accuracy) { +static double p3m_m_time(const int mesh[3], int cao_min, int cao_max, int *_cao, + double r_cut_iL_min, double r_cut_iL_max, + double *_r_cut_iL, double *_alpha_L, double *_accuracy, + bool verbose) { double best_time = -1, tmp_time, tmp_r_cut_iL = 0.0, tmp_alpha_L = 0.0, tmp_accuracy = 0.0; /* in which direction improvement is possible. Initially, we don't know it @@ -828,8 +832,8 @@ static double p3m_m_time(char **log, const int mesh[3], int cao_min, to increase cao to increase the obtainable precision of the far formula. */ do { - tmp_time = p3m_mc_time(log, mesh, cao, r_cut_iL_min, r_cut_iL_max, - &tmp_r_cut_iL, &tmp_alpha_L, &tmp_accuracy); + tmp_time = p3m_mc_time(mesh, cao, r_cut_iL_min, r_cut_iL_max, &tmp_r_cut_iL, + &tmp_alpha_L, &tmp_accuracy, verbose); /* bail out if the force evaluation is not working */ if (tmp_time == -P3M_TUNE_FAIL) return tmp_time; @@ -869,8 +873,8 @@ static double p3m_m_time(char **log, const int mesh[3], int cao_min, double dir_times[3]; for (final_dir = -1; final_dir <= 1; final_dir += 2) { dir_times[final_dir + 1] = tmp_time = - p3m_mc_time(log, mesh, cao + final_dir, r_cut_iL_min, r_cut_iL_max, - &tmp_r_cut_iL, &tmp_alpha_L, &tmp_accuracy); + p3m_mc_time(mesh, cao + final_dir, r_cut_iL_min, r_cut_iL_max, + &tmp_r_cut_iL, &tmp_alpha_L, &tmp_accuracy, verbose); /* bail out on errors, as usual */ if (tmp_time == -P3M_TUNE_FAIL) return tmp_time; @@ -921,8 +925,8 @@ static double p3m_m_time(char **log, const int mesh[3], int cao_min, /* move cao into the optimisation direction until we do not gain anymore. */ for (; cao >= cao_min && cao <= cao_max; cao += final_dir) { - tmp_time = p3m_mc_time(log, mesh, cao, r_cut_iL_min, r_cut_iL_max, - &tmp_r_cut_iL, &tmp_alpha_L, &tmp_accuracy); + tmp_time = p3m_mc_time(mesh, cao, r_cut_iL_min, r_cut_iL_max, &tmp_r_cut_iL, + &tmp_alpha_L, &tmp_accuracy, verbose); /* bail out on errors, as usual */ if (tmp_time == -P3M_TUNE_FAIL) return tmp_time; @@ -944,14 +948,13 @@ static double p3m_m_time(char **log, const int mesh[3], int cao_min, return best_time; } -int p3m_adaptive_tune(char **log) { +int p3m_adaptive_tune(bool verbose) { double r_cut_iL_min, r_cut_iL_max, r_cut_iL = -1, tmp_r_cut_iL = 0.0; int cao_min, cao_max, cao = -1, tmp_cao; double alpha_L = -1, tmp_alpha_L = 0.0; double accuracy = -1, tmp_accuracy = 0.0; double time_best = 1e20; double mesh_density_min, mesh_density_max; - char b[3 * ES_INTEGER_SPACE + 3 * ES_DOUBLE_SPACE + 128]; bool tune_mesh = false; // indicates if mesh should be tuned if (p3m.params.epsilon != P3M_EPSILON_METALLIC) { @@ -969,19 +972,19 @@ int p3m_adaptive_tune(char **log) { /* preparation */ mpi_call_all(p3m_count_charged_particles); - /* Print Status */ - sprintf(b, "P3M tune parameters: Accuracy goal = %.5e prefactor = %.5e\n", - p3m.params.accuracy, coulomb.prefactor); - *log = strcat_alloc(*log, b); - sprintf(b, "System: box_l = %.5e # charged part = %d Sum[q_i^2] = %.5e\n", - box_geo.length()[0], p3m.sum_qpart, p3m.sum_q2); - *log = strcat_alloc(*log, b); - if (p3m.sum_qpart == 0) { runtimeErrorMsg() << "no charged particles in the system"; return ES_ERROR; } + /* Print Status */ + if (verbose) { + std::printf("P3M tune parameters: Accuracy goal = %.5e prefactor = %.5e\n" + "System: box_l = %.5e # charged part = %d Sum[q_i^2] = %.5e\n", + p3m.params.accuracy, coulomb.prefactor, box_geo.length()[0], + p3m.sum_qpart, p3m.sum_q2); + } + /* Activate tuning mode */ p3m.params.tuning = true; @@ -1011,16 +1014,18 @@ int p3m_adaptive_tune(char **log) { if (p3m.params.mesh[2] % 2 == 1) p3m.params.mesh[2]++; - sprintf(b, "fixed mesh %d %d %d\n", p3m.params.mesh[0], p3m.params.mesh[1], - p3m.params.mesh[2]); - *log = strcat_alloc(*log, b); + if (verbose) { + std::printf("fixed mesh %d %d %d\n", p3m.params.mesh[0], + p3m.params.mesh[1], p3m.params.mesh[2]); + } } else { mesh_density_min = mesh_density_max = p3m.params.mesh[0] / box_geo.length()[0]; - sprintf(b, "fixed mesh %d %d %d\n", p3m.params.mesh[0], p3m.params.mesh[1], - p3m.params.mesh[2]); - *log = strcat_alloc(*log, b); + if (verbose) { + std::printf("fixed mesh %d %d %d\n", p3m.params.mesh[0], + p3m.params.mesh[1], p3m.params.mesh[2]); + } } if (p3m.params.r_cut_iL == 0.0) { @@ -1034,8 +1039,9 @@ int p3m_adaptive_tune(char **log) { } else { r_cut_iL_min = r_cut_iL_max = p3m.params.r_cut_iL; - sprintf(b, "fixed r_cut_iL %f\n", p3m.params.r_cut_iL); - *log = strcat_alloc(*log, b); + if (verbose) { + std::printf("fixed r_cut_iL %f\n", p3m.params.r_cut_iL); + } } if (p3m.params.cao == 0) { @@ -1045,12 +1051,15 @@ int p3m_adaptive_tune(char **log) { } else { cao_min = cao_max = cao = p3m.params.cao; - sprintf(b, "fixed cao %d\n", p3m.params.cao); - *log = strcat_alloc(*log, b); + if (verbose) { + std::printf("fixed cao %d\n", p3m.params.cao); + } } - *log = strcat_alloc(*log, "mesh cao r_cut_iL alpha_L err " - "rs_err ks_err time [ms]\n"); + if (verbose) { + std::printf("mesh cao r_cut_iL alpha_L err " + "rs_err ks_err time [ms]\n"); + } /* mesh loop */ /* we're tuning the density of mesh points, which is the same in every @@ -1081,9 +1090,9 @@ int p3m_adaptive_tune(char **log) { if (tmp_mesh[2] % 2) tmp_mesh[2]++; - auto const tmp_time = - p3m_m_time(log, tmp_mesh, cao_min, cao_max, &tmp_cao, r_cut_iL_min, - r_cut_iL_max, &tmp_r_cut_iL, &tmp_alpha_L, &tmp_accuracy); + auto const tmp_time = p3m_m_time(tmp_mesh, cao_min, cao_max, &tmp_cao, + r_cut_iL_min, r_cut_iL_max, &tmp_r_cut_iL, + &tmp_alpha_L, &tmp_accuracy, verbose); /* some error occurred during the tuning force evaluation */ if (tmp_time == -P3M_TUNE_FAIL) return ES_ERROR; @@ -1133,12 +1142,12 @@ int p3m_adaptive_tune(char **log) { mpi_bcast_coulomb_params(); /* Tell the user about the outcome */ - sprintf(b, - "\nresulting parameters: mesh: (%d %d %d), cao: %d, r_cut_iL: %.4e," - "\n alpha_L: %.4e, accuracy: %.4e, time: %.2f\n", - mesh[0], mesh[1], mesh[2], cao, r_cut_iL, alpha_L, accuracy, - time_best); - *log = strcat_alloc(*log, b); + if (verbose) { + std::printf( + "\nresulting parameters: mesh: (%d %d %d), cao: %d, r_cut_iL: %.4e," + "\n alpha_L: %.4e, accuracy: %.4e, time: %.2f\n", + mesh[0], mesh[1], mesh[2], cao, r_cut_iL, alpha_L, accuracy, time_best); + } return ES_OK; } diff --git a/src/core/electrostatics_magnetostatics/p3m.hpp b/src/core/electrostatics_magnetostatics/p3m.hpp index a493498ac55..4433af82a7b 100644 --- a/src/core/electrostatics_magnetostatics/p3m.hpp +++ b/src/core/electrostatics_magnetostatics/p3m.hpp @@ -118,11 +118,11 @@ extern p3m_data_struct p3m; * The function is based on routines of the program HE_Q.cpp written by M. * Deserno. * - * @param[out] log log output + * @param verbose printf output * @retval ES_OK * @retval ES_ERROR */ -int p3m_adaptive_tune(char **log); +int p3m_adaptive_tune(bool verbose); /** Initialize all structures, parameters and arrays needed for the * P3M algorithm for charge-charge interactions. diff --git a/src/python/espressomd/electrostatics.pxd b/src/python/espressomd/electrostatics.pxd index a82772e0429..4417c630842 100644 --- a/src/python/espressomd/electrostatics.pxd +++ b/src/python/espressomd/electrostatics.pxd @@ -72,7 +72,7 @@ IF ELECTROSTATICS: void p3m_set_tune_params(double r_cut, int mesh[3], int cao, double alpha, double accuracy) int p3m_set_mesh_offset(double x, double y, double z) int p3m_set_eps(double eps) - int p3m_adaptive_tune(char ** log) + int p3m_adaptive_tune(bool verbose) ctypedef struct p3m_data_struct: P3MParameters params @@ -107,14 +107,10 @@ IF ELECTROSTATICS: return p3m_set_mesh_offset( mesh_offset[0], mesh_offset[1], mesh_offset[2]) - cdef inline python_p3m_adaptive_tune(): - cdef char * log = NULL - cdef int response - response = p3m_adaptive_tune( & log) - handle_errors("Error in p3m_adaptive_tune") - if log.strip(): - print(to_str(log)) - return response + cdef inline python_p3m_adaptive_tune(bool verbose): + cdef int response = p3m_adaptive_tune(verbose) + if response: + handle_errors("python_p3m_adaptive_tune") cdef inline python_p3m_set_params(p_r_cut, p_mesh, p_cao, p_alpha, p_accuracy): cdef int mesh[3] diff --git a/src/python/espressomd/electrostatics.pyx b/src/python/espressomd/electrostatics.pyx index 7f64ebad395..45ccd4fdcab 100644 --- a/src/python/espressomd/electrostatics.pyx +++ b/src/python/espressomd/electrostatics.pyx @@ -277,7 +277,7 @@ IF P3M == 1: def valid_keys(self): return ["mesh", "cao", "accuracy", "epsilon", "alpha", "r_cut", - "prefactor", "tune", "check_neutrality"] + "prefactor", "tune", "check_neutrality", "verbose"] def required_keys(self): return ["prefactor", "accuracy"] @@ -291,7 +291,8 @@ IF P3M == 1: "epsilon": 0.0, "mesh_off": [-1, -1, -1], "tune": True, - "check_neutrality": True} + "check_neutrality": True, + "verbose": True} def _get_params_from_es_core(self): params = {} @@ -331,8 +332,7 @@ IF P3M == 1: self._params["cao"], -1.0, self._params["accuracy"]) - resp = python_p3m_adaptive_tune() - handle_errors("P3M tuning failed") + python_p3m_adaptive_tune(self._params["verbose"]) self._params.update(self._get_params_from_es_core()) def _activate_method(self): @@ -422,7 +422,7 @@ IF P3M == 1: def valid_keys(self): return ["mesh", "cao", "accuracy", "epsilon", "alpha", "r_cut", - "prefactor", "tune", "check_neutrality"] + "prefactor", "tune", "check_neutrality", "verbose"] def required_keys(self): return ["prefactor", "accuracy"] @@ -436,7 +436,8 @@ IF P3M == 1: "epsilon": 0.0, "mesh_off": [-1, -1, -1], "tune": True, - "check_neutrality": True} + "check_neutrality": True, + "verbose": True} def _get_params_from_es_core(self): params = {} @@ -463,8 +464,7 @@ IF P3M == 1: self._params["cao"], -1.0, self._params["accuracy"]) - resp = python_p3m_adaptive_tune() - handle_errors("P3MGPU tuning failed") + python_p3m_adaptive_tune(self._params["verbose"]) self._params.update(self._get_params_from_es_core()) def _activate_method(self): diff --git a/testsuite/python/p3m_tuning_exceptions.py b/testsuite/python/p3m_tuning_exceptions.py index d3affc2eddb..c5a2aa351c1 100644 --- a/testsuite/python/p3m_tuning_exceptions.py +++ b/testsuite/python/p3m_tuning_exceptions.py @@ -49,7 +49,7 @@ def test_01_time_not_set_p3m_gpu(self): self.add_charged_particles() solver = espressomd.electrostatics.P3MGPU(prefactor=2, accuracy=1e-2) - with self.assertRaisesRegex(Exception, 'p3m_adaptive_tune: ERROR: time_step not set'): + with self.assertRaisesRegex(Exception, 'python_p3m_adaptive_tune: ERROR: time_step not set'): self.system.actors.add(solver) @utx.skipIfMissingFeatures("P3M") @@ -59,7 +59,7 @@ def test_01_time_not_set_p3m_cpu(self): self.add_charged_particles() solver = espressomd.electrostatics.P3M(prefactor=2, accuracy=1e-2) - with self.assertRaisesRegex(Exception, 'p3m_adaptive_tune: ERROR: time_step not set'): + with self.assertRaisesRegex(Exception, 'python_p3m_adaptive_tune: ERROR: time_step not set'): self.system.actors.add(solver) @utx.skipIfMissingFeatures("DP3M") @@ -85,7 +85,7 @@ def test_02_no_particles_p3m_gpu(self): self.system.time_step = 0.01 solver = espressomd.electrostatics.P3MGPU(prefactor=2, accuracy=1e-2) - with self.assertRaisesRegex(Exception, 'p3m_adaptive_tune: ERROR: no charged particles in the system'): + with self.assertRaisesRegex(Exception, 'python_p3m_adaptive_tune: ERROR: no charged particles in the system'): self.system.actors.add(solver) @utx.skipIfMissingFeatures("P3M") @@ -95,7 +95,7 @@ def test_02_no_particles_p3m_cpu(self): self.system.time_step = 0.01 solver = espressomd.electrostatics.P3M(prefactor=2, accuracy=1e-2) - with self.assertRaisesRegex(Exception, 'p3m_adaptive_tune: ERROR: no charged particles in the system'): + with self.assertRaisesRegex(Exception, 'python_p3m_adaptive_tune: ERROR: no charged particles in the system'): self.system.actors.add(solver) @utx.skipIfMissingFeatures("DP3M") @@ -124,7 +124,7 @@ def test_03_non_cubic_box_p3m_gpu(self): solver = espressomd.electrostatics.P3MGPU( prefactor=2, accuracy=1e-2, epsilon=1) - with self.assertRaisesRegex(Exception, 'p3m_adaptive_tune: ERROR: non-metallic epsilon requires cubic box'): + with self.assertRaisesRegex(Exception, 'python_p3m_adaptive_tune: ERROR: non-metallic epsilon requires cubic box'): self.system.actors.add(solver) @utx.skipIfMissingFeatures("P3M") @@ -137,7 +137,7 @@ def test_03_non_cubic_box_p3m_cpu(self): solver = espressomd.electrostatics.P3M( prefactor=2, accuracy=1e-2, epsilon=1) - with self.assertRaisesRegex(Exception, 'p3m_adaptive_tune: ERROR: non-metallic epsilon requires cubic box'): + with self.assertRaisesRegex(Exception, 'python_p3m_adaptive_tune: ERROR: non-metallic epsilon requires cubic box'): self.system.actors.add(solver) @utx.skipIfMissingFeatures("DP3M") From a620d1dd9995255a98ac249938bcd0c1f598e52d Mon Sep 17 00:00:00 2001 From: Alexander Reinauer Date: Thu, 17 Dec 2020 14:57:00 +0100 Subject: [PATCH 2/5] core: mmm1d: replaced strcat_alloc with std::printf and added verbose parameter fixup mmm1d --- .../electrostatics_magnetostatics/mmm1d.cpp | 23 ++++++++----------- .../electrostatics_magnetostatics/mmm1d.hpp | 4 ++-- src/python/espressomd/electrostatics.pxd | 14 +++-------- src/python/espressomd/electrostatics.pyx | 9 ++++---- 4 files changed, 18 insertions(+), 32 deletions(-) diff --git a/src/core/electrostatics_magnetostatics/mmm1d.cpp b/src/core/electrostatics_magnetostatics/mmm1d.cpp index 96624fa8b24..3204db5018d 100644 --- a/src/core/electrostatics_magnetostatics/mmm1d.cpp +++ b/src/core/electrostatics_magnetostatics/mmm1d.cpp @@ -44,7 +44,6 @@ #include #include #include -#include #include #include @@ -53,8 +52,6 @@ #include #include -using Utils::strcat_alloc; - /** How many trial calculations in @ref mmm1d_tune */ #define TEST_INTEGRATIONS 1000 @@ -339,10 +336,9 @@ double mmm1d_coulomb_pair_energy(double const chpref, Utils::Vector3d const &d, return chpref * E; } -int mmm1d_tune(char **log) { +int mmm1d_tune(bool verbose) { if (MMM1D_sanity_checks()) return ES_ERROR; - char buffer[32 + 2 * ES_DOUBLE_SPACE + ES_INTEGER_SPACE]; double min_time = std::numeric_limits::infinity(); double min_rad = -1; auto const maxrad = box_geo.length()[2]; @@ -372,8 +368,9 @@ int mmm1d_tune(char **log) { if (int_time < 0) return ES_ERROR; - sprintf(buffer, "r= %f t= %f ms\n", switch_radius, int_time); - *log = strcat_alloc(*log, buffer); + if (verbose) { + std::printf("r= %f t= %f ms\n", switch_radius, int_time); + } if (int_time < min_time) { min_time = int_time; @@ -385,13 +382,11 @@ int mmm1d_tune(char **log) { } switch_radius = min_rad; mmm1d_params.far_switch_radius_2 = Utils::sqr(switch_radius); - } else { - if (mmm1d_params.far_switch_radius_2 <= - Utils::sqr(bessel_radii[MAXIMAL_B_CUT - 1])) { - // this switching radius is too small for our Bessel series - *log = strcat_alloc(*log, "could not find reasonable bessel cutoff"); - return ES_ERROR; - } + } else if (mmm1d_params.far_switch_radius_2 <= + Utils::sqr(bessel_radii[MAXIMAL_B_CUT - 1])) { + // this switching radius is too small for our Bessel series + runtimeErrorMsg() << "could not find reasonable bessel cutoff"; + return ES_ERROR; } coulomb.method = COULOMB_MMM1D; diff --git a/src/core/electrostatics_magnetostatics/mmm1d.hpp b/src/core/electrostatics_magnetostatics/mmm1d.hpp index 21faf61f3bf..00fa5af63d9 100644 --- a/src/core/electrostatics_magnetostatics/mmm1d.hpp +++ b/src/core/electrostatics_magnetostatics/mmm1d.hpp @@ -76,11 +76,11 @@ double mmm1d_coulomb_pair_energy(double q1q2, Utils::Vector3d const &d, * @ref MMM1D_struct::bessel_cutoff "Bessel cutoff". Call this only * on the master node. * - * @param log contains information about the tuning (tried values and errors) + * @param verbose output information about the tuning (tried values and errors) * @retval ES_OK * @retval ES_ERROR */ -int mmm1d_tune(char **log); +int mmm1d_tune(bool verbose); #endif #endif diff --git a/src/python/espressomd/electrostatics.pxd b/src/python/espressomd/electrostatics.pxd index 4417c630842..43db7a9c6a1 100644 --- a/src/python/espressomd/electrostatics.pxd +++ b/src/python/espressomd/electrostatics.pxd @@ -183,24 +183,16 @@ IF ELECTROSTATICS: void MMM1D_set_params(double switch_rad, double maxPWerror) int MMM1D_init() - int MMM1D_sanity_checks() - int mmm1d_tune(char ** log) + int mmm1d_tune(bool verbose) - cdef inline pyMMM1D_tune(): - cdef char * log = NULL + cdef inline pyMMM1D_tune(bool verbose): cdef int resp resp = MMM1D_init() if resp: handle_errors("pyMMM1D_tune") - return resp - resp = MMM1D_sanity_checks() + resp = mmm1d_tune(verbose) if resp: handle_errors("pyMMM1D_tune") - return resp - resp = mmm1d_tune(& log) - if resp: - print(to_str(log)) - return resp IF ELECTROSTATICS and MMM1D_GPU: diff --git a/src/python/espressomd/electrostatics.pyx b/src/python/espressomd/electrostatics.pyx index 45ccd4fdcab..0e9b1491be0 100644 --- a/src/python/espressomd/electrostatics.pyx +++ b/src/python/espressomd/electrostatics.pyx @@ -524,11 +524,12 @@ IF ELECTROSTATICS: "far_switch_radius": -1, "bessel_cutoff": -1, "tune": True, - "check_neutrality": True} + "check_neutrality": True, + "verbose": True} def valid_keys(self): return ["prefactor", "maxPWerror", "far_switch_radius", - "bessel_cutoff", "tune", "check_neutrality"] + "bessel_cutoff", "tune", "check_neutrality", "verbose"] def required_keys(self): return ["prefactor", "maxPWerror"] @@ -550,9 +551,7 @@ IF ELECTROSTATICS: def _tune(self): cdef int resp - resp = pyMMM1D_tune() - if resp: - raise Exception("failed to tune mmm1d ") + pyMMM1D_tune(self._params["verbose"]) self._params.update(self._get_params_from_es_core()) def _activate_method(self): From f0de32ee441255a253dd0d81bb15bf78361fd6ce Mon Sep 17 00:00:00 2001 From: Alexander Reinauer Date: Thu, 17 Dec 2020 18:29:07 +0100 Subject: [PATCH 3/5] core: dp3m: replaced strcat_alloc with std::printf and added verbose parameter --- .../p3m-dipolar.cpp | 117 ++++++++++-------- .../p3m-dipolar.hpp | 4 +- src/python/espressomd/magnetostatics.pxd | 11 +- src/python/espressomd/magnetostatics.pyx | 16 +-- testsuite/python/p3m_tuning_exceptions.py | 6 +- 5 files changed, 82 insertions(+), 72 deletions(-) diff --git a/src/core/electrostatics_magnetostatics/p3m-dipolar.cpp b/src/core/electrostatics_magnetostatics/p3m-dipolar.cpp index 037e4724380..02bbce6992a 100644 --- a/src/core/electrostatics_magnetostatics/p3m-dipolar.cpp +++ b/src/core/electrostatics_magnetostatics/p3m-dipolar.cpp @@ -61,7 +61,6 @@ #include #include #include -#include #include #include @@ -73,8 +72,6 @@ #include #include -using Utils::strcat_alloc; - /************************************************ * DEFINES ************************************************/ @@ -831,7 +828,6 @@ static double dp3m_mcr_time(int mesh, int cao, double r_cut_iL, * * The @p _r_cut_iL is determined via a simple bisection. * - * @param[out] log log output * @param[in] mesh @copybrief P3MParameters::mesh * @param[in] cao @copybrief P3MParameters::cao * @param[in] r_cut_iL_min lower bound for @p _r_cut_iL @@ -839,18 +835,18 @@ static double dp3m_mcr_time(int mesh, int cao, double r_cut_iL, * @param[out] _r_cut_iL @copybrief P3MParameters::r_cut_iL * @param[out] _alpha_L @copybrief P3MParameters::alpha_L * @param[out] _accuracy @copybrief P3MParameters::accuracy + * @param[in] verbose printf output * * @returns The integration time in case of success, otherwise * -@ref P3M_TUNE_FAIL, -@ref P3M_TUNE_ACCURACY_TOO_LARGE, * -@ref P3M_TUNE_CAO_TOO_LARGE, -@ref P3M_TUNE_ELCTEST, or * -@ref P3M_TUNE_CUTOFF_TOO_LARGE */ -static double dp3m_mc_time(char **log, int mesh, int cao, double r_cut_iL_min, +static double dp3m_mc_time(int mesh, int cao, double r_cut_iL_min, double r_cut_iL_max, double *_r_cut_iL, - double *_alpha_L, double *_accuracy) { + double *_alpha_L, double *_accuracy, bool verbose) { double r_cut_iL; double rs_err, ks_err; - char b[3 * ES_INTEGER_SPACE + 3 * ES_DOUBLE_SPACE + 128]; /* initial checks. */ auto const mesh_size = box_geo.length()[0] / static_cast(mesh); @@ -861,8 +857,9 @@ static double dp3m_mc_time(char **log, int mesh, int cao, double r_cut_iL_min, if (cao >= mesh || k_cut >= std::min(min_box_l, min_local_box_l) - skin) { /* print result */ - sprintf(b, "%-4d %-3d cao too large for this mesh\n", mesh, cao); - *log = strcat_alloc(*log, b); + if (verbose) { + std::printf("%-4d %-3d cao too large for this mesh\n", mesh, cao); + } return -P3M_TUNE_CAO_TOO_LARGE; } @@ -876,9 +873,11 @@ static double dp3m_mc_time(char **log, int mesh, int cao, double r_cut_iL_min, return *_accuracy; if (*_accuracy > dp3m.params.accuracy) { /* print result */ - sprintf(b, "%-4d %-3d %.5e %.5e %.5e %.3e %.3e accuracy not achieved\n", - mesh, cao, r_cut_iL_max, *_alpha_L, *_accuracy, rs_err, ks_err); - *log = strcat_alloc(*log, b); + if (verbose) { + std::printf("%-4d %-3d %.5e %.5e %.5e %.3e %.3e accuracy not achieved\n", + mesh, cao, r_cut_iL_max, *_alpha_L, *_accuracy, rs_err, + ks_err); + } return -P3M_TUNE_ACCURACY_TOO_LARGE; } @@ -910,7 +909,9 @@ static double dp3m_mc_time(char **log, int mesh, int cao, double r_cut_iL_min, double const int_time = dp3m_mcr_time(mesh, cao, r_cut_iL, *_alpha_L); if (int_time == -P3M_TUNE_FAIL) { - *log = strcat_alloc(*log, "tuning failed, test integration not possible\n"); + if (verbose) { + std::printf("tuning failed, test integration not possible\n"); + } return int_time; } @@ -921,9 +922,10 @@ static double dp3m_mc_time(char **log, int mesh, int cao, double r_cut_iL_min, } /* print result */ - sprintf(b, "%-4d %-3d %.5e %.5e %.5e %.3e %.3e %-8.0f\n", mesh, cao, r_cut_iL, - *_alpha_L, *_accuracy, rs_err, ks_err, int_time); - *log = strcat_alloc(*log, b); + if (verbose) { + std::printf("%-4d %-3d %.5e %.5e %.5e %.3e %.3e %-8.0f\n", mesh, cao, + r_cut_iL, *_alpha_L, *_accuracy, rs_err, ks_err, int_time); + } return int_time; } @@ -932,7 +934,6 @@ static double dp3m_mc_time(char **log, int mesh, int cao, double r_cut_iL_min, * @p _cao should contain an initial guess, which is then adapted by stepping * up and down. * - * @param[out] log log output * @param[in] mesh @copybrief P3MParameters::mesh * @param[in] cao_min lower bound for @p _cao * @param[in] cao_max upper bound for @p _cao @@ -943,13 +944,14 @@ static double dp3m_mc_time(char **log, int mesh, int cao, double r_cut_iL_min, * @param[out] _r_cut_iL @copybrief P3MParameters::r_cut_iL * @param[out] _alpha_L @copybrief P3MParameters::alpha_L * @param[out] _accuracy @copybrief P3MParameters::accuracy + * @param[in] verbose printf output * * @returns The integration time in case of success, otherwise * -@ref P3M_TUNE_FAIL or -@ref P3M_TUNE_CAO_TOO_LARGE */ -static double dp3m_m_time(char **log, int mesh, int cao_min, int cao_max, - int *_cao, double r_cut_iL_min, double r_cut_iL_max, +static double dp3m_m_time(int mesh, int cao_min, int cao_max, int *_cao, + double r_cut_iL_min, double r_cut_iL_max, double *_r_cut_iL, double *_alpha_L, - double *_accuracy) { + double *_accuracy, bool verbose) { double best_time = -1, tmp_r_cut_iL = -1., tmp_alpha_L = 0.0, tmp_accuracy = 0.0; /* in which direction improvement is possible. Initially, we don't know it @@ -963,8 +965,9 @@ static double dp3m_m_time(char **log, int mesh, int cao_min, int cao_max, to increase cao to increase the obtainable precision of the far formula. */ double tmp_time; do { - tmp_time = dp3m_mc_time(log, mesh, cao, r_cut_iL_min, r_cut_iL_max, - &tmp_r_cut_iL, &tmp_alpha_L, &tmp_accuracy); + tmp_time = + dp3m_mc_time(mesh, cao, r_cut_iL_min, r_cut_iL_max, &tmp_r_cut_iL, + &tmp_alpha_L, &tmp_accuracy, verbose); /* bail out if the force evaluation is not working */ if (tmp_time == -P3M_TUNE_FAIL || tmp_time == -DP3M_RTBISECTION_ERROR) return tmp_time; @@ -1002,8 +1005,8 @@ static double dp3m_m_time(char **log, int mesh, int cao_min, int cao_max, double dir_times[3]; for (final_dir = -1; final_dir <= 1; final_dir += 2) { dir_times[final_dir + 1] = tmp_time = - dp3m_mc_time(log, mesh, cao + final_dir, r_cut_iL_min, r_cut_iL_max, - &tmp_r_cut_iL, &tmp_alpha_L, &tmp_accuracy); + dp3m_mc_time(mesh, cao + final_dir, r_cut_iL_min, r_cut_iL_max, + &tmp_r_cut_iL, &tmp_alpha_L, &tmp_accuracy, verbose); /* bail out on errors, as usual */ if (tmp_time == -P3M_TUNE_FAIL || tmp_time == -DP3M_RTBISECTION_ERROR) return tmp_time; @@ -1053,8 +1056,9 @@ static double dp3m_m_time(char **log, int mesh, int cao_min, int cao_max, /* move cao into the optimisation direction until we do not gain anymore. */ for (; cao >= cao_min && cao <= cao_max; cao += final_dir) { - tmp_time = dp3m_mc_time(log, mesh, cao, r_cut_iL_min, r_cut_iL_max, - &tmp_r_cut_iL, &tmp_alpha_L, &tmp_accuracy); + tmp_time = + dp3m_mc_time(mesh, cao, r_cut_iL_min, r_cut_iL_max, &tmp_r_cut_iL, + &tmp_alpha_L, &tmp_accuracy, verbose); /* bail out on errors, as usual */ if (tmp_time == -P3M_TUNE_FAIL || tmp_time == -DP3M_RTBISECTION_ERROR) return tmp_time; @@ -1076,7 +1080,7 @@ static double dp3m_m_time(char **log, int mesh, int cao_min, int cao_max, return best_time; } -int dp3m_adaptive_tune(char **logger) { +int dp3m_adaptive_tune(bool verbose) { /** Tuning of dipolar P3M. The algorithm basically determines the mesh, cao * and then the real space cutoff, in this nested order. * @@ -1101,26 +1105,24 @@ int dp3m_adaptive_tune(char **logger) { double alpha_L = -1, tmp_alpha_L = 0.0; double accuracy = -1, tmp_accuracy = 0.0; double time_best = 1e20, tmp_time; - char b[3 * ES_INTEGER_SPACE + 3 * ES_DOUBLE_SPACE + 128]; /* preparation */ mpi_call_all(dp3m_count_magnetic_particles); - /* Print Status */ - sprintf(b, - "Dipolar P3M tune parameters: Accuracy goal = %.5e prefactor " - "= %.5e\n", - dp3m.params.accuracy, dipole.prefactor); - *logger = strcat_alloc(*logger, b); - sprintf(b, "System: box_l = %.5e # charged part = %d Sum[q_i^2] = %.5e\n", - box_geo.length()[0], dp3m.sum_dip_part, dp3m.sum_mu2); - *logger = strcat_alloc(*logger, b); - if (dp3m.sum_dip_part == 0) { runtimeErrorMsg() << "no dipolar particles in the system"; return ES_ERROR; } + /* Print Status */ + if (verbose) { + std::printf("Dipolar P3M tune parameters: Accuracy goal = %.5e prefactor " + "= %.5e\n" + "System: box_l = %.5e # charged part = %d Sum[q_i^2] = %.5e\n", + dp3m.params.accuracy, dipole.prefactor, box_geo.length()[0], + dp3m.sum_dip_part, dp3m.sum_mu2); + } + /* parameter ranges */ if (dp3m.params.mesh[0] == 0) { double expo; @@ -1137,8 +1139,9 @@ int dp3m_adaptive_tune(char **logger) { } else { tmp_mesh = mesh_max = dp3m.params.mesh[0]; - sprintf(b, "fixed mesh %d\n", dp3m.params.mesh[0]); - *logger = strcat_alloc(*logger, b); + if (verbose) { + std::printf("fixed mesh %d\n", dp3m.params.mesh[0]); + } } if (dp3m.params.r_cut_iL == 0.0) { @@ -1152,8 +1155,9 @@ int dp3m_adaptive_tune(char **logger) { } else { r_cut_iL_min = r_cut_iL_max = dp3m.params.r_cut_iL; - sprintf(b, "fixed r_cut_iL %f\n", dp3m.params.r_cut_iL); - *logger = strcat_alloc(*logger, b); + if (verbose) { + std::printf("fixed r_cut_iL %f\n", dp3m.params.r_cut_iL); + } } if (dp3m.params.cao == 0) { @@ -1163,18 +1167,22 @@ int dp3m_adaptive_tune(char **logger) { } else { cao_min = cao_max = cao = dp3m.params.cao; - sprintf(b, "fixed cao %d\n", dp3m.params.cao); - *logger = strcat_alloc(*logger, b); + if (verbose) { + std::printf("fixed cao %d\n", dp3m.params.cao); + } + } + + if (verbose) { + std::printf("Dmesh cao Dr_cut_iL Dalpha_L Derr " + " Drs_err Dks_err time [ms]\n"); } - *logger = strcat_alloc(*logger, "Dmesh cao Dr_cut_iL Dalpha_L Derr " - " Drs_err Dks_err time [ms]\n"); /* mesh loop */ for (; tmp_mesh <= mesh_max; tmp_mesh += 2) { tmp_cao = cao; - tmp_time = - dp3m_m_time(logger, tmp_mesh, cao_min, cao_max, &tmp_cao, r_cut_iL_min, - r_cut_iL_max, &tmp_r_cut_iL, &tmp_alpha_L, &tmp_accuracy); + tmp_time = dp3m_m_time(tmp_mesh, cao_min, cao_max, &tmp_cao, r_cut_iL_min, + r_cut_iL_max, &tmp_r_cut_iL, &tmp_alpha_L, + &tmp_accuracy, verbose); /* some error occurred during the tuning force evaluation */ if (tmp_time == -P3M_TUNE_FAIL || tmp_time == -DP3M_RTBISECTION_ERROR) return ES_ERROR; @@ -1214,11 +1222,12 @@ int dp3m_adaptive_tune(char **logger) { /* broadcast tuned p3m parameters */ mpi_bcast_coulomb_params(); /* Tell the user about the outcome */ - sprintf(b, - "\nresulting parameters: mesh: %d, cao: %d, r_cut_iL: %.4e," - "\n alpha_L: %.4e, accuracy: %.4e, time: %.0f\n", - mesh, cao, r_cut_iL, alpha_L, accuracy, time_best); - *logger = strcat_alloc(*logger, b); + if (verbose) { + std::printf( + "\nresulting parameters: mesh: %d, cao: %d, r_cut_iL: %.4e," + "\n alpha_L: %.4e, accuracy: %.4e, time: %.0f\n", + mesh, cao, r_cut_iL, alpha_L, accuracy, time_best); + } return ES_OK; } diff --git a/src/core/electrostatics_magnetostatics/p3m-dipolar.hpp b/src/core/electrostatics_magnetostatics/p3m-dipolar.hpp index 32d8386674c..fc262d361ca 100644 --- a/src/core/electrostatics_magnetostatics/p3m-dipolar.hpp +++ b/src/core/electrostatics_magnetostatics/p3m-dipolar.hpp @@ -157,11 +157,11 @@ void dp3m_deactivate(); * The function is based on routines of the program HE_Q.cpp for charges * written by M. Deserno. * - * @param[out] log log output + * @param verbose printf output * @retval ES_OK * @retval ES_ERROR */ -int dp3m_adaptive_tune(char **log); +int dp3m_adaptive_tune(bool verbose); /** Compute the k-space part of forces and energies for the magnetic * dipole-dipole interaction diff --git a/src/python/espressomd/magnetostatics.pxd b/src/python/espressomd/magnetostatics.pxd index 2b11890a6a9..166f0cf3307 100644 --- a/src/python/espressomd/magnetostatics.pxd +++ b/src/python/espressomd/magnetostatics.pxd @@ -14,6 +14,10 @@ # # You should have received a copy of the GNU General Public License # along with this program. If not, see . + +from libcpp cimport bool +from .utils cimport handle_errors + include "myconfig.pxi" IF DIPOLES == 1: @@ -63,10 +67,15 @@ IF DP3M == 1: void dp3m_set_tune_params(double r_cut, int mesh, int cao, double alpha, double accuracy) int dp3m_set_mesh_offset(double x, double y, double z) int dp3m_set_eps(double eps) - int dp3m_adaptive_tune(char ** log) + int dp3m_adaptive_tune(bool verbose) int dp3m_deactivate() ctypedef struct dp3m_data_struct: P3MParameters params cdef extern dp3m_data_struct dp3m + + cdef inline python_dp3m_adaptive_tune(bool verbose): + cdef int response = dp3m_adaptive_tune(verbose) + if response: + handle_errors("python_dp3m_adaptive_tune") diff --git a/src/python/espressomd/magnetostatics.pyx b/src/python/espressomd/magnetostatics.pyx index 4b6a6c025d0..086748acc2f 100644 --- a/src/python/espressomd/magnetostatics.pyx +++ b/src/python/espressomd/magnetostatics.pyx @@ -131,7 +131,7 @@ IF DP3M == 1: def valid_keys(self): return ["prefactor", "alpha_L", "r_cut_iL", "mesh", "mesh_off", "cao", "accuracy", "epsilon", "cao_cut", "a", "ai", - "alpha", "r_cut", "cao3", "additional_mesh", "tune"] + "alpha", "r_cut", "cao3", "additional_mesh", "tune", "verbose"] def required_keys(self): return ["accuracy", ] @@ -143,7 +143,8 @@ IF DP3M == 1: "mesh": -1, "epsilon": 0.0, "mesh_off": [-1, -1, -1], - "tune": True} + "tune": True, + "verbose": True} def _get_params_from_es_core(self): params = {} @@ -166,9 +167,7 @@ IF DP3M == 1: self.python_dp3m_set_tune_params( self._params["r_cut"], self._params["mesh"], self._params["cao"], -1., self._params["accuracy"]) - resp, log = self.python_dp3m_adaptive_tune() - handle_errors("dipolar P3M tuning failed") - print(to_str(log)) + python_dp3m_adaptive_tune(self._params["verbose"]) self._params.update(self._get_params_from_es_core()) def _activate_method(self): @@ -190,13 +189,6 @@ IF DP3M == 1: return dp3m_set_mesh_offset( mesh_offset[0], mesh_offset[1], mesh_offset[2]) - def python_dp3m_adaptive_tune(self): - cdef char * log = NULL - cdef int response - response = dp3m_adaptive_tune(& log) - handle_errors("dipolar P3M tuning failed") - return response, log - def python_dp3m_set_params(self, p_r_cut, p_mesh, p_cao, p_alpha, p_accuracy): cdef int mesh diff --git a/testsuite/python/p3m_tuning_exceptions.py b/testsuite/python/p3m_tuning_exceptions.py index c5a2aa351c1..c3f27d3aec1 100644 --- a/testsuite/python/p3m_tuning_exceptions.py +++ b/testsuite/python/p3m_tuning_exceptions.py @@ -70,7 +70,7 @@ def test_01_time_not_set_dp3m_cpu(self): solver = espressomd.magnetostatics.DipolarP3M( prefactor=2, accuracy=1e-2) - with self.assertRaisesRegex(Exception, 'dipolar P3M tuning failed: ERROR: time_step not set'): + with self.assertRaisesRegex(Exception, 'python_dp3m_adaptive_tune: ERROR: time_step not set'): self.system.actors.add(solver) ############################################## @@ -106,7 +106,7 @@ def test_02_no_particles_dp3m_cpu(self): solver = espressomd.magnetostatics.DipolarP3M( prefactor=2, accuracy=1e-2) - with self.assertRaisesRegex(Exception, 'dipolar P3M tuning failed: ERROR: no dipolar particles in the system'): + with self.assertRaisesRegex(Exception, 'python_dp3m_adaptive_tune: ERROR: no dipolar particles in the system'): self.system.actors.add(solver) ####################################### @@ -150,7 +150,7 @@ def test_03_non_cubic_box_dp3m_cpu(self): solver = espressomd.magnetostatics.DipolarP3M( prefactor=2, accuracy=1e-2) - with self.assertRaisesRegex(Exception, 'dipolar P3M tuning failed: ERROR: dipolar P3M requires a cubic box'): + with self.assertRaisesRegex(Exception, 'python_dp3m_adaptive_tune: ERROR: dipolar P3M requires a cubic box'): self.system.actors.add(solver) ########################################################### From 3355d83b79d1dcee6fb3b7df6b5aa36ca2ad5a98 Mon Sep 17 00:00:00 2001 From: Alexander Reinauer Date: Thu, 17 Dec 2020 18:37:50 +0100 Subject: [PATCH 4/5] core: utils: removed strcat_alloc with unit tests --- src/utils/include/utils/strcat_alloc.hpp | 48 ------------------- src/utils/tests/CMakeLists.txt | 1 - src/utils/tests/strcat_alloc_test.cpp | 61 ------------------------ 3 files changed, 110 deletions(-) delete mode 100644 src/utils/include/utils/strcat_alloc.hpp delete mode 100644 src/utils/tests/strcat_alloc_test.cpp diff --git a/src/utils/include/utils/strcat_alloc.hpp b/src/utils/include/utils/strcat_alloc.hpp deleted file mode 100644 index 2986aff09e8..00000000000 --- a/src/utils/include/utils/strcat_alloc.hpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2010-2019 The ESPResSo project - * Copyright (C) 2002,2003,2004,2005,2006,2007,2008,2009,2010 - * Max-Planck-Institute for Polymer Research, Theory Group - * - * This file is part of ESPResSo. - * - * ESPResSo is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ESPResSo is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef UTILS_STRCAT_ALLOC_HPP -#define UTILS_STRCAT_ALLOC_HPP - -#include "memory.hpp" - -#include -#include - -namespace Utils { -/** Extend a string with another one. - * Like strcat, just automatically increases the string space. - */ -inline char *strcat_alloc(char *left, const char *right) { - if (!right) { - return left; - } - if (!left) { - return strdup(right); - } - size_t newlen = strlen(left) + strlen(right); - char *res = Utils::realloc(left, newlen + 1); - strncat(res, right, newlen); - return res; -} -} // namespace Utils - -#endif diff --git a/src/utils/tests/CMakeLists.txt b/src/utils/tests/CMakeLists.txt index 979f6b8371e..273a53e62a2 100644 --- a/src/utils/tests/CMakeLists.txt +++ b/src/utils/tests/CMakeLists.txt @@ -9,7 +9,6 @@ unit_test(NAME keys_test SRC keys_test.cpp DEPENDS EspressoUtils) unit_test(NAME Cache_test SRC Cache_test.cpp DEPENDS EspressoUtils) unit_test(NAME histogram SRC histogram.cpp DEPENDS EspressoUtils) unit_test(NAME accumulator SRC accumulator.cpp DEPENDS EspressoUtils) -unit_test(NAME strcat_alloc SRC strcat_alloc_test.cpp DEPENDS EspressoUtils) unit_test(NAME int_pow SRC int_pow_test.cpp DEPENDS EspressoUtils) unit_test(NAME sgn SRC sgn_test.cpp DEPENDS EspressoUtils) unit_test(NAME AS_erfc_part SRC AS_erfc_part_test.cpp DEPENDS EspressoUtils) diff --git a/src/utils/tests/strcat_alloc_test.cpp b/src/utils/tests/strcat_alloc_test.cpp deleted file mode 100644 index 2b593b4d3ee..00000000000 --- a/src/utils/tests/strcat_alloc_test.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2018-2019 The ESPResSo project - * - * This file is part of ESPResSo. - * - * ESPResSo is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * ESPResSo is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#define BOOST_TEST_MODULE Utils::strcat_alloc test -#define BOOST_TEST_DYN_LINK -#include - -#include -using Utils::strcat_alloc; - -#include -#include - -BOOST_AUTO_TEST_CASE(empty_left) { - const char *right = "right"; - auto res = strcat_alloc(nullptr, right); - - BOOST_REQUIRE(res); - BOOST_REQUIRE(strlen(res) == strlen(right)); - BOOST_CHECK(0 == strcmp(res, right)); - free(res); -} - -BOOST_AUTO_TEST_CASE(empty_right) { - char left[] = "left"; - auto res = strcat_alloc(left, nullptr); - - BOOST_REQUIRE(res == left); - BOOST_REQUIRE(strlen(res) == strlen(left)); - BOOST_CHECK(0 == strcmp(res, left)); -} - -BOOST_AUTO_TEST_CASE(nonempty) { - const char *left = "left"; - const char *right = "right"; - auto *str = static_cast(Utils::malloc(5)); - strncpy(str, left, 5); - - auto res = strcat_alloc(str, right); - - BOOST_REQUIRE(res); - BOOST_REQUIRE(strlen(res) == (strlen(left) + strlen(right))); - BOOST_CHECK(0 == strcmp(res, "leftright")); - free(res); -} From 0980513de05866d10fa436c80a85125ebba883c9 Mon Sep 17 00:00:00 2001 From: Alexander Reinauer Date: Thu, 17 Dec 2020 17:09:09 +0100 Subject: [PATCH 5/5] python: p3m: missing handle_errors call after p3m_gpu_init --- src/python/espressomd/electrostatics.pxd | 1 + 1 file changed, 1 insertion(+) diff --git a/src/python/espressomd/electrostatics.pxd b/src/python/espressomd/electrostatics.pxd index 43db7a9c6a1..ef1a218f48e 100644 --- a/src/python/espressomd/electrostatics.pxd +++ b/src/python/espressomd/electrostatics.pxd @@ -98,6 +98,7 @@ IF ELECTROSTATICS: mesh = params["mesh"] alpha = params["alpha"] p3m_gpu_init(cao, mesh, alpha) + handle_errors("python_p3m_gpu_init") cdef inline python_p3m_set_mesh_offset(mesh_off): cdef double mesh_offset[3]