X-Git-Url: http://biod.pnpi.spb.ru/gitweb/?a=blobdiff_plain;f=src%2Fgromacs%2Fgmxana%2Fgmx_tune_pme.cpp;fp=src%2Fgromacs%2Fgmxana%2Fgmx_tune_pme.c;h=bee0529b0a2858852a142a0ae2461b73258727a5;hb=c3f2d46e4047f0c465f7234b3784a2fa6f02a065;hp=838b98e72b57d0c2c09e93493d483999df411c12;hpb=0595b4a4c763a0bc574658992081abf8b0abc3fe;p=alexxy%2Fgromacs.git diff --git a/src/gromacs/gmxana/gmx_tune_pme.c b/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 838b98e72b..bee0529b0a 100644 --- a/src/gromacs/gmxana/gmx_tune_pme.c +++ b/src/gromacs/gmxana/gmx_tune_pme.cpp @@ -36,8 +36,12 @@ #include "config.h" -#include -#include +#include +#include +#include +#include + +#include #ifdef HAVE_SYS_TIME_H #include @@ -62,8 +66,11 @@ #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(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(nnodes/(1.0 + 1.0/guessPMEratio)); + minPMEnodes = static_cast(std::floor(0.7*guessPMEnodes)); + maxPMEnodes = static_cast(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(std::floor(maxPMEfraction*nnodes)); + minPMEnodes = std::max(static_cast(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);