From eb5870d0bb3738ce102e4183c4cd6c6445fa9039 Mon Sep 17 00:00:00 2001 From: Eliane Briand Date: Fri, 28 May 2021 07:11:10 +0000 Subject: [PATCH] Reworked convert-tpr runtime extension Fixes extension of run using -until flag. Fixes #4056 --- docs/release-notes/2021/2021.3.rst | 8 + src/gromacs/tools/convert_tpr.cpp | 187 ++++++++++-------- .../HelpwritingTest_ConvertTprWritesHelp.xml | 2 +- 3 files changed, 118 insertions(+), 79 deletions(-) diff --git a/docs/release-notes/2021/2021.3.rst b/docs/release-notes/2021/2021.3.rst index 049bc1cdde..e2548d3617 100644 --- a/docs/release-notes/2021/2021.3.rst +++ b/docs/release-notes/2021/2021.3.rst @@ -34,6 +34,14 @@ The tool now reports correct values. :issue:`4080` +Make sure gmx convert-tpr -until works +"""""""""""""""""""""""""""""""""""""" + +This got broken during reworking the internals of the tool and didn't +calculate the number of remaining steps correctly. + +:issue:`4056` + Fixes that affect portability ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/gromacs/tools/convert_tpr.cpp b/src/gromacs/tools/convert_tpr.cpp index fe66b9f588..eea5932015 100644 --- a/src/gromacs/tools/convert_tpr.cpp +++ b/src/gromacs/tools/convert_tpr.cpp @@ -4,7 +4,7 @@ * Copyright (c) 1991-2000, University of Groningen, The Netherlands. * Copyright (c) 2001-2004, The GROMACS development team. * Copyright (c) 2013,2014,2015,2016,2017 by the GROMACS development team. - * Copyright (c) 2018,2019,2020, by the GROMACS development team, led by + * Copyright (c) 2018,2019,2020,2021, by the GROMACS development team, led by * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, * and including many others, as listed in the AUTHORS file in the * top-level source directory and at http://www.gromacs.org. @@ -271,6 +271,19 @@ static void zeroq(const int index[], gmx_mtop_t* mtop) } } +static void print_runtime_info(t_inputrec* ir) +{ + char buf[STEPSTRSIZE]; + + printf(" Run start step %22s \n", gmx_step_str(ir->init_step, buf)); + printf(" Run start time %22g ps \n", ir->init_step * ir->delta_t + ir->init_t); + printf(" Step to be made during run %22s \n", gmx_step_str(ir->nsteps, buf)); + printf(" Runtime for the run %22g ps \n", ir->nsteps * ir->delta_t); + printf(" Run end step %22s \n", gmx_step_str(ir->init_step + ir->nsteps, buf)); + printf(" Run end time %22g ps \n\n", + (ir->init_step + ir->nsteps) * ir->delta_t + ir->init_t); +} + namespace gmx { @@ -364,8 +377,10 @@ void ConvertTpr::initOptions(IOptionsContainer* options, ICommandLineOptionsModu .storeIsSet(&runToMaxTimeIsSet_) .timeValue() .description("Extend runtime until this ending time (ps)")); - options->addOption( - Int64Option("nsteps").store(&maxSteps_).storeIsSet(&maxStepsIsSet_).description("Change the number of steps")); + options->addOption(Int64Option("nsteps") + .store(&maxSteps_) + .storeIsSet(&maxStepsIsSet_) + .description("Change the number of steps remaining to be made")); options->addOption( BooleanOption("zeroq").store(&zeroQIsSet_).description("Set the charges of a group (from the index) to zero")); } @@ -377,107 +392,123 @@ int ConvertTpr::run() gmx_mtop_t mtop; t_atoms atoms; t_state state; - char buf[200], buf2[200]; + char buf[STEPSTRSIZE]; + + if (static_cast(extendTimeIsSet_) + static_cast(maxStepsIsSet_) + static_cast(runToMaxTimeIsSet_) + > 1) + { + printf("Multiple runtime modification operations cannot be done in a single call.\n"); + return 1; + } + + if ((extendTimeIsSet_ || maxStepsIsSet_ || runToMaxTimeIsSet_) && (zeroQIsSet_ || haveReadIndexFile_)) + { + printf("Cannot do both runtime modification and charge-zeroing/index group extraction in a " + "single call.\n"); + return 1; + } + + if (zeroQIsSet_ && !haveReadIndexFile_) + { + printf("Charge zeroing need an index file.\n"); + return 1; + } - fprintf(stderr, "Reading toplogy and stuff from %s\n", inputTprFileName_.c_str()); t_inputrec irInstance; t_inputrec* ir = &irInstance; read_tpx_state(inputTprFileName_.c_str(), ir, &state, &mtop); - int64_t currentMaxStep = ir->init_step; - double currentRunTime = ir->init_step * ir->delta_t + ir->init_t; - real currentMaxRunTime = 0.0; - if (maxStepsIsSet_) - { - fprintf(stderr, "Setting nsteps to %s\n", gmx_step_str(maxSteps_, buf)); - ir->nsteps = maxSteps_; - } - else + + if (extendTimeIsSet_ || maxStepsIsSet_ || runToMaxTimeIsSet_) { - /* Determine total number of steps remaining */ - if (extendTimeIsSet_) - { - ir->nsteps = ir->nsteps - (currentMaxStep - ir->init_step) - + gmx::roundToInt64(extendTime_ / ir->delta_t); - printf("Extending remaining runtime of by %g ps (now %s steps)\n", extendTime_, - gmx_step_str(ir->nsteps, buf)); - } - else if (runToMaxTimeIsSet_) + // Doing runtime modification + + const double inputTimeAtStartOfRun = ir->init_step * ir->delta_t + ir->init_t; + const int64_t inputStepAtEndOfRun = ir->init_step + ir->nsteps; + const double inputTimeAtEndOfRun = inputStepAtEndOfRun * ir->delta_t + ir->init_t; + + printf("Input file:\n"); + print_runtime_info(ir); + + if (maxStepsIsSet_) { - printf("nsteps = %s, run_step = %s, current_t = %g, until = %g\n", - gmx_step_str(ir->nsteps, buf), gmx_step_str(currentMaxStep, buf2), - currentRunTime, runToMaxTime_); - ir->nsteps = gmx::roundToInt64((currentMaxRunTime - currentRunTime) / ir->delta_t); - printf("Extending remaining runtime until %g ps (now %s steps)\n", currentMaxRunTime, - gmx_step_str(ir->nsteps, buf)); + fprintf(stderr, "Setting nsteps to %s\n", gmx_step_str(maxSteps_, buf)); + ir->nsteps = maxSteps_; } - else + else if (extendTimeIsSet_) { - ir->nsteps -= currentMaxStep - ir->init_step; - /* Print message */ - printf("%s steps (%g ps) remaining from first run.\n", gmx_step_str(ir->nsteps, buf), - ir->nsteps * ir->delta_t); + printf("Extending remaining runtime by %g ps\n", extendTime_); + ir->nsteps += gmx::roundToInt64(extendTime_ / ir->delta_t); } - } - - if (maxStepsIsSet_ || zeroQIsSet_ || (ir->nsteps > 0)) - { - ir->init_step = currentMaxStep; - - if (haveReadIndexFile_ || !(maxStepsIsSet_ || extendTimeIsSet_ || runToMaxTimeIsSet_)) + else if (runToMaxTimeIsSet_) { - atoms = gmx_mtop_global_atoms(&mtop); - int gnx = 0; - int* index = nullptr; - char* grpname = nullptr; - get_index(&atoms, inputIndexFileName_.c_str(), 1, &gnx, &index, &grpname); - bool bSel = false; - if (!zeroQIsSet_) + if (runToMaxTime_ <= inputTimeAtStartOfRun) { - bSel = (gnx != state.natoms); - for (int i = 0; ((i < gnx) && (!bSel)); i++) - { - bSel = (i != index[i]); - } + printf("The requested run end time is at/before the run start time.\n"); + return 1; } - else + if (runToMaxTime_ < inputTimeAtEndOfRun) { - bSel = false; - } - if (bSel) - { - fprintf(stderr, - "Will write subset %s of original tpx containing %d " - "atoms\n", - grpname, gnx); - reduce_topology_x(gnx, index, &mtop, state.x.rvec_array(), state.v.rvec_array()); - state.natoms = gnx; - } - else if (zeroQIsSet_) - { - zeroq(index, &mtop); - fprintf(stderr, "Zero-ing charges for group %s\n", grpname); + printf("The requested run end time is before the original run end time.\n"); + printf("Reducing remaining runtime to %g ps\n", runToMaxTime_); } else { - fprintf(stderr, "Will write full tpx file (no selection)\n"); + printf("Extending remaining runtime to %g ps\n", runToMaxTime_); } + ir->nsteps = gmx::roundToInt64((runToMaxTime_ - inputTimeAtStartOfRun) / ir->delta_t); } - double stateTime = ir->init_t + ir->init_step * ir->delta_t; - sprintf(buf, "Writing statusfile with starting step %s%s and length %s%s steps...\n", "%10", - PRId64, "%10", PRId64); - fprintf(stderr, buf, ir->init_step, ir->nsteps); - fprintf(stderr, " time %10.3f and length %10.3f ps\n", - stateTime, ir->nsteps * ir->delta_t); - write_tpx_state(outputTprFileName_.c_str(), ir, &state, &mtop); + printf("\nOutput file:\n"); + print_runtime_info(ir); } else { - printf("You've simulated long enough. Not writing tpr file\n"); + // If zeroQIsSet_, then we are doing charge zero-ing; otherwise index group extraction + // In both cases an index filename has been provided + + atoms = gmx_mtop_global_atoms(&mtop); + int gnx = 0; + int* index = nullptr; + char* grpname = nullptr; + get_index(&atoms, inputIndexFileName_.c_str(), 1, &gnx, &index, &grpname); + bool bSel = false; + if (!zeroQIsSet_) + { + bSel = (gnx != state.natoms); + for (int i = 0; ((i < gnx) && (!bSel)); i++) + { + bSel = (i != index[i]); + } + } + else + { + bSel = false; + } + if (bSel) + { + fprintf(stderr, + "Will write subset %s of original tpx containing %d " + "atoms\n", + grpname, gnx); + reduce_topology_x(gnx, index, &mtop, state.x.rvec_array(), state.v.rvec_array()); + state.natoms = gnx; + } + else if (zeroQIsSet_) + { + zeroq(index, &mtop); + fprintf(stderr, "Zero-ing charges for group %s\n", grpname); + } + else + { + fprintf(stderr, "Will write full tpx file (no selection)\n"); + } } + // Writing output tpx regardless of the operation performed + write_tpx_state(outputTprFileName_.c_str(), ir, &state, &mtop); + return 0; } diff --git a/src/gromacs/tools/tests/refdata/HelpwritingTest_ConvertTprWritesHelp.xml b/src/gromacs/tools/tests/refdata/HelpwritingTest_ConvertTprWritesHelp.xml index b0c890552b..25765ad1f3 100644 --- a/src/gromacs/tools/tests/refdata/HelpwritingTest_ConvertTprWritesHelp.xml +++ b/src/gromacs/tools/tests/refdata/HelpwritingTest_ConvertTprWritesHelp.xml @@ -44,7 +44,7 @@ Other options: -until