#include "config.h"
-#include <stdlib.h>
-#include <time.h>
+#include <cmath>
+#include <cstdlib>
+#include <cstring>
+#include <ctime>
+
+#include <algorithm>
#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
#include "gromacs/utility/cstringutil.h"
#include "gromacs/utility/fatalerror.h"
#include "gromacs/utility/futil.h"
+#include "gromacs/utility/gmxassert.h"
#include "gromacs/utility/smalloc.h"
+#include "gmx_ana.h"
+
/* Enum for situations that can occur during log file parsing, the
* corresponding string entries can be found in do_the_tests() in
* const char* ParseLog[] */
/* Check if string starts with substring */
static gmx_bool str_starts(const char *string, const char *substring)
{
- return ( strncmp(string, substring, strlen(substring)) == 0);
+ return ( std::strncmp(string, substring, std::strlen(substring)) == 0);
}
ltrim(line);
/* Check for TERM and INT signals from user: */
- if (strstr(line, errSIG) != NULL)
+ if (std::strstr(line, errSIG) != NULL)
{
fclose(fp);
cleandata(perfdata, test_nr);
/* Check whether cycle resetting worked */
if (presteps > 0 && !bFoundResetStr)
{
- if (strstr(line, matchstrcr) != NULL)
+ if (std::strstr(line, matchstrcr) != NULL)
{
- sprintf(dumstring, "step %s", "%"GMX_SCNd64);
+ sprintf(dumstring, "step %s", "%" GMX_SCNd64);
sscanf(line, dumstring, &resetsteps);
bFoundResetStr = TRUE;
if (resetsteps == presteps+cpt_steps)
}
else
{
- sprintf(dumstring, "%"GMX_PRId64, resetsteps);
- sprintf(dumstring2, "%"GMX_PRId64, presteps+cpt_steps);
+ sprintf(dumstring, "%" GMX_PRId64, resetsteps);
+ sprintf(dumstring2, "%" GMX_PRId64, presteps+cpt_steps);
fprintf(stderr, "WARNING: Time step counters were reset at step %s,\n"
" though they were supposed to be reset at step %s!\n",
dumstring, dumstring2);
/* Look for PME mesh/force balance (not necessarily present, though) */
else if (str_starts(line, matchstrbal))
{
- sscanf(&line[strlen(matchstrbal)], "%f", &(perfdata->PME_f_load[test_nr]));
+ sscanf(&line[std::strlen(matchstrbal)], "%f", &(perfdata->PME_f_load[test_nr]));
}
/* Look for matchstring */
else if (str_starts(line, matchstring))
s = 0.0;
for (j = 0; j < nrepeats; j++)
{
- s += pow( pd->Gcycles[j] - pd->Gcycles_Av, 2 );
+ s += std::pow( pd->Gcycles[j] - pd->Gcycles_Av, 2 );
}
s /= (nrepeats - 1);
- s = sqrt(s);
+ s = std::sqrt(s);
fprintf(fp, "%4d %3d %4d%s %12.3f %12.3f %12.3f %s",
line, k, pd->nPMEnodes, strbuf, pd->Gcycles_Av, s,
static void get_program_paths(gmx_bool bThreads, char *cmd_mpirun[], char *cmd_mdrun[])
{
char *cp;
- FILE *fp;
const char def_mpirun[] = "mpirun";
const char def_mdrun[] = "mdrun";
fprintf(stdout, "Making sure that mdrun can be executed. ");
if (bThreads)
{
- snew(command, strlen(cmd_mdrun) + strlen(cmd_np) + strlen(filename) + 50);
+ snew(command, std::strlen(cmd_mdrun) + std::strlen(cmd_np) + std::strlen(filename) + 50);
sprintf(command, "%s%s-version -maxh 0.001 1> %s 2>&1", cmd_mdrun, cmd_np, filename);
}
else
{
- snew(command, strlen(cmd_mpirun) + strlen(cmd_np) + strlen(cmd_mdrun) + strlen(filename) + 50);
+ snew(command, std::strlen(cmd_mpirun) + std::strlen(cmd_np) + std::strlen(cmd_mdrun) + std::strlen(filename) + 50);
sprintf(command, "%s%s%s -version -maxh 0.001 1> %s 2>&1", cmd_mpirun, cmd_np, cmd_mdrun, filename);
}
fprintf(stdout, "Trying '%s' ... ", command);
/* Handles the no-GPU case by emitting an empty string. */
static char *make_gpu_id_command_line(int numRanks, int numPmeRanks, const t_eligible_gpu_ids *gpu_ids)
{
- char *command_line, *flag = "-gpu_id ", *ptr;
- int flag_length;
+ char *command_line, *ptr;
+ const char *flag = "-gpu_id ";
+ int flag_length;
/* Reserve enough room for the option name, enough single-digit
GPU ids (since that is currently all that is possible to use
with mdrun), and a terminating NULL. */
- flag_length = strlen(flag);
+ flag_length = std::strlen(flag);
snew(command_line, flag_length + numRanks + 1);
ptr = command_line;
int gpu_id, rank;
/* Write the option flag */
- strcpy(ptr, flag);
+ std::strcpy(ptr, flag);
ptr += flag_length;
numPpRanks = numRanks - numPmeRanks;
/* Make enough space for the system call command,
* (200 extra chars for -npme ... etc. options should suffice): */
- snew(command, strlen(cmd_mpirun)+strlen(cmd_mdrun)+strlen(cmd_np)+strlen(args_for_mdrun)+strlen(simulation_tpr)+200);
+ snew(command, std::strlen(cmd_mpirun)+std::strlen(cmd_mdrun)+std::strlen(cmd_np)+std::strlen(args_for_mdrun)+std::strlen(simulation_tpr)+200);
cmd_gpu_ids = make_gpu_id_command_line(nnodes, nPMEnodes, gpu_ids);
ir->init_step = init_step;
/* Write the tpr file which will be launched */
- sprintf(buf, "Writing optimized simulation file %s with nsteps=%s.\n", fn_sim_tpr, "%"GMX_PRId64);
+ sprintf(buf, "Writing optimized simulation file %s with nsteps=%s.\n", fn_sim_tpr, "%" GMX_PRId64);
fprintf(stdout, buf, ir->nsteps);
fflush(stdout);
write_tpx_state(fn_sim_tpr, ir, &state, &mtop);
sprintf(buf, "Making benchmark tpr file%s with %s time step%s",
- *ntprs > 1 ? "s" : "", "%"GMX_PRId64, benchsteps > 1 ? "s" : "");
+ *ntprs > 1 ? "s" : "", "%" GMX_PRId64, benchsteps > 1 ? "s" : "");
fprintf(stdout, buf, benchsteps);
if (statesteps > 0)
{
- sprintf(buf, " (adding %s steps from checkpoint file)", "%"GMX_PRId64);
+ sprintf(buf, " (adding %s steps from checkpoint file)", "%" GMX_PRId64);
fprintf(stdout, buf, statesteps);
benchsteps += statesteps;
}
{
box_size[d] += state.box[d][i]*state.box[d][i];
}
- box_size[d] = sqrt(box_size[d]);
+ box_size[d] = std::sqrt(box_size[d]);
}
if (ir->fourier_spacing > 0)
else
{
/* Use the maximum observed spacing */
- fourierspacing = max(max(info->fsx[0], info->fsy[0]), info->fsz[0]);
+ fourierspacing = std::max(std::max(info->fsx[0], info->fsy[0]), info->fsz[0]);
}
fprintf(stdout, "Calculating PME grid points on the basis of a fourierspacing of %f nm\n", fourierspacing);
else
{
/* For vdw cutoff, rvdw >= rlist */
- ir->rvdw = max(info->rvdw[0], ir->rlist);
+ ir->rvdw = std::max(info->rvdw[0], ir->rlist);
}
}
info->fsz[j] = fac*fourierspacing;
/* Write the benchmark tpr file */
- strncpy(fn_bench_tprs[j], fn_sim_tpr, strlen(fn_sim_tpr)-strlen(".tpr"));
+ std::strncpy(fn_bench_tprs[j], fn_sim_tpr, std::strlen(fn_sim_tpr)-std::strlen(".tpr"));
sprintf(buf, "_bench%.2d.tpr", j);
- strcat(fn_bench_tprs[j], buf);
+ std::strcat(fn_bench_tprs[j], buf);
fprintf(stdout, "Writing benchmark tpr %s with nsteps=", fn_bench_tprs[j]);
- fprintf(stdout, "%"GMX_PRId64, ir->nsteps);
+ fprintf(stdout, "%" GMX_PRId64, ir->nsteps);
if (j > 0)
{
fprintf(stdout, ", scaling factor %f\n", fac);
for (i = 0; i < nfile; i++)
{
opt = (char *)fnm[i].opt;
- if (strcmp(opt, "-p") == 0)
+ if (std::strcmp(opt, "-p") == 0)
{
/* do nothing; keep this file */
;
}
- else if (strcmp(opt, "-bg") == 0)
+ else if (std::strcmp(opt, "-bg") == 0)
{
/* Give the log file a nice name so one can later see which parameters were used */
numstring[0] = '\0';
rename(opt2fn("-bg", nfile, fnm), newfilename);
}
}
- else if (strcmp(opt, "-err") == 0)
+ else if (std::strcmp(opt, "-err") == 0)
{
/* This file contains the output of stderr. We want to keep it in
* cases where there have been problems. */
}
}
/* Delete the files which are created for each benchmark run: (options -b*) */
- else if ( (0 == strncmp(opt, "-b", 2)) && (opt2bSet(opt, nfile, fnm) || !is_optional(&fnm[i])) )
+ else if ( (0 == std::strncmp(opt, "-b", 2)) && (opt2bSet(opt, nfile, fnm) || !is_optional(&fnm[i])) )
{
remove_if_exists(opt2fn(opt, nfile, fnm));
}
/* Do we need to check all possible values for -npme or is a reduced list enough? */
- if (0 == strcmp(npmevalues_opt, "all") )
+ if (!std::strcmp(npmevalues_opt, "all") )
{
eNPME = eNpmeAll;
}
- else if (0 == strcmp(npmevalues_opt, "subset") )
+ else if (!std::strcmp(npmevalues_opt, "subset") )
{
eNPME = eNpmeSubset;
}
case eNpmeSubset:
/* For 2d PME we want a common largest factor of at least the cube
* root of the number of PP nodes */
- min_factor = (int) pow(npp, 1.0/3.0);
+ min_factor = static_cast<int>(std::pow(npp, 1.0/3.0));
break;
default:
gmx_fatal(FARGS, "Unknown option for eNPME in make_npme_list");
static void make_sure_it_runs(char *mdrun_cmd_line, int length, FILE *fp,
const t_filenm *fnm, int nfile)
{
- const char *fn = NULL;
char *command, *msg;
int ret;
-
snew(command, length + 15);
snew(msg, length + 500);
char buf[STRLEN];
gmx_bool bResetProblem = FALSE;
gmx_bool bFirst = TRUE;
- gmx_bool bUsingGpus = 0 < gpu_ids->n;
/* This string array corresponds to the eParselog enum type at the start
* of this file */
/* Allocate space for the mdrun command line. 100 extra characters should
be more than enough for the -npme etcetera arguments */
- cmdline_length = strlen(cmd_mpirun)
- + strlen(cmd_np)
- + strlen(cmd_mdrun)
- + strlen(cmd_args_bench)
- + strlen(tpr_names[0]) + 100;
+ cmdline_length = std::strlen(cmd_mpirun)
+ + std::strlen(cmd_np)
+ + std::strlen(cmd_mdrun)
+ + std::strlen(cmd_args_bench)
+ + std::strlen(tpr_names[0]) + 100;
snew(command, cmdline_length);
snew(cmd_stub, cmdline_length);
}
/* Make sure that the checkpoint file is not overwritten during benchmarking */
- if ( (0 == strcmp(opt2fn("-cpi", nfile, fnm), opt2fn("-bcpo", nfile, fnm)) ) && (sim_part > 1) )
+ if ( (0 == std::strcmp(opt2fn("-cpi", nfile, fnm), opt2fn("-bcpo", nfile, fnm)) ) && (sim_part > 1) )
{
gmx_fatal(FARGS, "Checkpoint input (-cpi) and benchmark checkpoint output (-bcpo) files must not be identical.\n"
"The checkpoint input file must not be overwritten during the benchmarks.\n");
/* If one of rmin, rmax is set, we need 2 tpr files at minimum */
if (!gmx_within_tol(*rmax, rcoulomb, GMX_REAL_EPS) || !gmx_within_tol(*rmin, rcoulomb, GMX_REAL_EPS) )
{
- *ntprs = max(*ntprs, 2);
+ *ntprs = std::max(*ntprs, 2);
}
/* If both rmin, rmax are set, we need 3 tpr files at minimum */
if (!gmx_within_tol(*rmax, rcoulomb, GMX_REAL_EPS) && !gmx_within_tol(*rmin, rcoulomb, GMX_REAL_EPS) )
{
- *ntprs = max(*ntprs, 3);
+ *ntprs = std::max(*ntprs, 3);
}
if (old != *ntprs)
if (bench_nsteps > 10000 || bench_nsteps < 100)
{
fprintf(stderr, "WARNING: steps=");
- fprintf(stderr, "%"GMX_PRId64, bench_nsteps);
+ fprintf(stderr, "%" GMX_PRId64, bench_nsteps);
fprintf(stderr, ". Are you sure you want to perform so %s steps for each benchmark?\n", (bench_nsteps < 100) ? "few" : "many");
}
if ((npme_fixed > 0) && (5*npme_fixed < nnodes))
{
fprintf(stderr, "WARNING: Only %g percent of the ranks are assigned as PME-only ranks.\n",
- 100.0*((real)npme_fixed / (real)nnodes));
+ (100.0*npme_fixed)/nnodes);
}
if (opt2parg_bSet("-min", npargs, pa) || opt2parg_bSet("-max", npargs, pa))
{
/* Returns TRUE when "opt" is needed at launch time */
static gmx_bool is_launch_file(char *opt, gmx_bool bSet)
{
- if (0 == strncmp(opt, "-swap", 5))
+ if (0 == std::strncmp(opt, "-swap", 5))
{
return bSet;
}
/* Apart from the input .tpr and the output log files we need all options that
* were set on the command line and that do not start with -b */
- if (0 == strncmp(opt, "-b", 2) || 0 == strncmp(opt, "-s", 2)
- || 0 == strncmp(opt, "-err", 4) || 0 == strncmp(opt, "-p", 2) )
+ if (0 == std::strncmp(opt, "-b", 2) || 0 == std::strncmp(opt, "-s", 2)
+ || 0 == std::strncmp(opt, "-err", 4) || 0 == std::strncmp(opt, "-p", 2) )
{
return FALSE;
}
{
/* Apart from the input .tpr, all files starting with "-b" are for
* _b_enchmark files exclusively */
- if (0 == strncmp(opt, "-s", 2))
+ if (0 == std::strncmp(opt, "-s", 2))
{
return FALSE;
}
- if (0 == strncmp(opt, "-b", 2) || 0 == strncmp(opt, "-s", 2))
+ if (0 == std::strncmp(opt, "-b", 2) || 0 == std::strncmp(opt, "-s", 2))
{
if (!bOptional || bSet)
{
/* Adds 'buf' to 'str' */
-static void add_to_string(char **str, char *buf)
+static void add_to_string(char **str, const char *buf)
{
int len;
- len = strlen(*str) + strlen(buf) + 1;
+ len = std::strlen(*str) + std::strlen(buf) + 1;
srenew(*str, len);
- strcat(*str, buf);
+ std::strcat(*str, buf);
}
{
/* All options starting with -b* need the 'b' removed,
* therefore overwrite strbuf */
- if (0 == strncmp(opt, "-b", 2))
+ if (0 == std::strncmp(opt, "-b", 2))
{
sprintf(strbuf, "-%s %s ", &opt[2], name);
}
for (i = 0; (i < nfile); i++)
{
- if (strcmp(opt, fnm[i].opt) == 0)
+ if (std::strcmp(opt, fnm[i].opt) == 0)
{
fnm[i].flag |= ffSET;
}
{
opt = (char *)fnm[i].opt;
bSet = ((fnm[i].flag & ffSET) != 0);
- bBench = (0 == strncmp(opt, "-b", 2));
+ bBench = (0 == std::strncmp(opt, "-b", 2));
/* Check optional files */
/* If e.g. -eo is set, then -beo also needs to be set */
t_inputinfo *info;
int i;
FILE *fp;
- t_commrec *cr;
/* Print out how long the tuning took */
double seconds;
return 0;
}
+ // procstring[0] is used inside two different conditionals further down
+ GMX_RELEASE_ASSERT(procstring[0] != NULL, "Options inconsistency; procstring[0] is NULL");
+
/* Store the remaining unparsed command line entries in a string which
* is then attached to the mdrun command line */
snew(ExtraArgs, 1);
{
/* This string will be used for MPI runs and will appear after the
* mpirun command. */
- if (strcmp(procstring[0], "none") != 0)
+ if (std::strcmp(procstring[0], "none") != 0)
{
sprintf(bbuf, " %s %d ", procstring[0], nnodes);
}
* the actual list of settings is build in do_the_tests(). */
if ((nnodes > 2) && (npme_fixed < -1))
{
- if (0 == strcmp(npmevalues_opt[0], "auto"))
+ if (0 == std::strcmp(npmevalues_opt[0], "auto"))
{
/* Determine the npme range automatically based on the PME:PP load guess */
if (guessPMEratio > 1.0)
else
{
/* PME : PP load is in the range 0..1, let's test around the guess */
- guessPMEnodes = nnodes/(1.0 + 1.0/guessPMEratio);
- minPMEnodes = floor(0.7*guessPMEnodes);
- maxPMEnodes = ceil(1.6*guessPMEnodes);
- maxPMEnodes = min(maxPMEnodes, nnodes/2);
+ guessPMEnodes = static_cast<int>(nnodes/(1.0 + 1.0/guessPMEratio));
+ minPMEnodes = static_cast<int>(std::floor(0.7*guessPMEnodes));
+ maxPMEnodes = static_cast<int>(std::ceil(1.6*guessPMEnodes));
+ maxPMEnodes = std::min(maxPMEnodes, nnodes/2);
}
}
else
{
/* Determine the npme range based on user input */
- maxPMEnodes = floor(maxPMEfraction*nnodes);
- minPMEnodes = max(floor(minPMEfraction*nnodes), 0);
+ maxPMEnodes = static_cast<int>(std::floor(maxPMEfraction*nnodes));
+ minPMEnodes = std::max(static_cast<int>(std::floor(minPMEfraction*nnodes)), 0);
fprintf(stdout, "Will try runs with %d ", minPMEnodes);
if (maxPMEnodes != minPMEnodes)
{
{
fprintf(fp, "Number of ranks : %d\n", nnodes);
fprintf(fp, "The mpirun command is : %s\n", cmd_mpirun);
- if (strcmp(procstring[0], "none") != 0)
+ if (std::strcmp(procstring[0], "none") != 0)
{
fprintf(fp, "Passing # of ranks via : %s\n", procstring[0]);
}
fprintf(fp, "The mdrun command is : %s\n", cmd_mdrun);
fprintf(fp, "mdrun args benchmarks : %s\n", cmd_args_bench);
fprintf(fp, "Benchmark steps : ");
- fprintf(fp, "%"GMX_PRId64, bench_nsteps);
+ fprintf(fp, "%" GMX_PRId64, bench_nsteps);
fprintf(fp, "\n");
fprintf(fp, "dlb equilibration steps : %d\n", presteps);
if (sim_part > 1)
{
fprintf(fp, "Checkpoint time step : ");
- fprintf(fp, "%"GMX_PRId64, cpt_steps);
+ fprintf(fp, "%" GMX_PRId64, cpt_steps);
fprintf(fp, "\n");
}
fprintf(fp, "mdrun args at launchtime: %s\n", cmd_args_launch);
{
bOverwrite = TRUE;
fprintf(stderr, "Note: Simulation input file %s will have ", opt2fn("-so", NFILE, fnm));
- fprintf(stderr, "%"GMX_PRId64, new_sim_nsteps+cpt_steps);
+ fprintf(stderr, "%" GMX_PRId64, new_sim_nsteps+cpt_steps);
fprintf(stderr, " steps.\n");
fprintf(fp, "Simulation steps : ");
- fprintf(fp, "%"GMX_PRId64, new_sim_nsteps);
+ fprintf(fp, "%" GMX_PRId64, new_sim_nsteps);
fprintf(fp, "\n");
}
if (repeats > 1)
snew(perfdata, ntprs);
if (bBenchmark)
{
+ GMX_RELEASE_ASSERT(npmevalues_opt[0] != NULL, "Options inconsistency; npmevalues_opt[0] is NULL");
do_the_tests(fp, tpr_names, maxPMEnodes, minPMEnodes, npme_fixed, npmevalues_opt[0], perfdata, &pmeentries,
repeats, nnodes, ntprs, bThreads, cmd_mpirun, cmd_np, cmd_mdrun,
cmd_args_bench, fnm, NFILE, presteps, cpt_steps, bCheck, gpu_ids);