Merge branch 'master' into pygromacs
[alexxy/gromacs.git] / src / gromacs / gmxana / gmx_tune_pme.cpp
similarity index 95%
rename from src/gromacs/gmxana/gmx_tune_pme.c
rename to src/gromacs/gmxana/gmx_tune_pme.cpp
index 838b98e72b57d0c2c09e93493d483999df411c12..bee0529b0a2858852a142a0ae2461b73258727a5 100644 (file)
 
 #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[] */
@@ -130,7 +137,7 @@ static int gmx_system_call(char *command)
 /* 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);
 }
 
 
@@ -219,7 +226,7 @@ static int parse_logfile(const char *logfile, const char *errfile,
         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);
@@ -229,9 +236,9 @@ static int parse_logfile(const char *logfile, const char *errfile,
         /* 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)
@@ -240,8 +247,8 @@ static int parse_logfile(const char *logfile, const char *errfile,
                 }
                 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);
@@ -306,7 +313,7 @@ static int parse_logfile(const char *logfile, const char *errfile,
                 /* 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))
@@ -483,10 +490,10 @@ static gmx_bool analyze_data(
                     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,
@@ -595,7 +602,6 @@ static gmx_bool analyze_data(
 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";
 
@@ -659,12 +665,12 @@ static void check_mdrun_works(gmx_bool    bThreads,
     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);
@@ -751,13 +757,14 @@ typedef struct eligible_gpu_ids
 /* 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;
 
@@ -770,7 +777,7 @@ static char *make_gpu_id_command_line(int numRanks, int numPmeRanks, const t_eli
         int   gpu_id, rank;
 
         /* Write the option flag */
-        strcpy(ptr, flag);
+        std::strcpy(ptr, flag);
         ptr += flag_length;
 
         numPpRanks                 = numRanks - numPmeRanks;
@@ -821,7 +828,7 @@ static void launch_simulation(
 
     /* 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);
 
@@ -872,7 +879,7 @@ static void modify_PMEsettings(
     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);
@@ -917,11 +924,11 @@ static void make_benchmark_tprs(
 
 
     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;
     }
@@ -976,7 +983,7 @@ static void make_benchmark_tprs(
         {
             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)
@@ -1003,7 +1010,7 @@ static void make_benchmark_tprs(
     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);
@@ -1104,7 +1111,7 @@ static void make_benchmark_tprs(
                 else
                 {
                     /* For vdw cutoff, rvdw >= rlist */
-                    ir->rvdw = max(info->rvdw[0], ir->rlist);
+                    ir->rvdw = std::max(info->rvdw[0], ir->rlist);
                 }
             }
 
@@ -1126,11 +1133,11 @@ static void make_benchmark_tprs(
         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);
@@ -1196,12 +1203,12 @@ static void cleanup(const t_filenm *fnm, int nfile, int k, int nnodes,
     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';
@@ -1217,7 +1224,7 @@ static void cleanup(const t_filenm *fnm, int nfile, int k, int nnodes,
                 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. */
@@ -1244,7 +1251,7 @@ static void cleanup(const t_filenm *fnm, int nfile, int k, int nnodes,
             }
         }
         /* 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));
         }
@@ -1276,11 +1283,11 @@ static void make_npme_list(
 
 
     /* 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;
     }
@@ -1332,7 +1339,7 @@ static void make_npme_list(
             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");
@@ -1384,11 +1391,9 @@ static void init_perfdata(t_perf *perfdata[], int ntprs, int datasets, int repea
 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);
 
@@ -1462,7 +1467,6 @@ static void do_the_tests(
     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 */
@@ -1485,11 +1489,11 @@ static void do_the_tests(
 
     /* 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);
 
@@ -1696,7 +1700,7 @@ static void check_input(
     }
 
     /* 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");
@@ -1774,13 +1778,13 @@ static void check_input(
     /* 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)
@@ -1822,7 +1826,7 @@ static void check_input(
     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");
     }
 
@@ -1854,7 +1858,7 @@ static void check_input(
         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))
         {
@@ -1868,15 +1872,15 @@ static void check_input(
 /* 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;
     }
@@ -1890,12 +1894,12 @@ static gmx_bool is_bench_file(char *opt, gmx_bool bSet, gmx_bool bOptional, gmx_
 {
     /* 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)
         {
@@ -1928,14 +1932,14 @@ static gmx_bool is_bench_file(char *opt, gmx_bool bSet, gmx_bool bOptional, gmx_
 
 
 /* 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);
 }
 
 
@@ -2002,7 +2006,7 @@ static void create_command_line_snippets(
         {
             /* 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);
             }
@@ -2028,7 +2032,7 @@ static void setopt(const char *opt, int nfile, t_filenm fnm[])
 
     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;
         }
@@ -2103,7 +2107,7 @@ static void couple_files_options(int nfile, t_filenm fnm[])
     {
         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 */
@@ -2222,7 +2226,6 @@ int gmx_tune_pme(int argc, char *argv[])
     t_inputinfo        *info;
     int                 i;
     FILE               *fp;
-    t_commrec          *cr;
 
     /* Print out how long the tuning took */
     double          seconds;
@@ -2373,6 +2376,9 @@ int gmx_tune_pme(int argc, char *argv[])
         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);
@@ -2414,7 +2420,7 @@ int gmx_tune_pme(int argc, char *argv[])
     {
         /* 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);
         }
@@ -2461,7 +2467,7 @@ int gmx_tune_pme(int argc, char *argv[])
      * 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)
@@ -2473,17 +2479,17 @@ int gmx_tune_pme(int argc, char *argv[])
             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)
             {
@@ -2515,7 +2521,7 @@ int gmx_tune_pme(int argc, char *argv[])
     {
         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]);
         }
@@ -2532,13 +2538,13 @@ int gmx_tune_pme(int argc, char *argv[])
     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);
@@ -2547,10 +2553,10 @@ int gmx_tune_pme(int argc, char *argv[])
     {
         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)
@@ -2600,6 +2606,7 @@ int gmx_tune_pme(int argc, char *argv[])
     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);