1/* 2 * This file is part of the GROMACS molecular simulation package. 3 * 4 * Copyright (c) 1991-2000, University of Groningen, The Netherlands. 5 * Copyright (c) 2001-2004, The GROMACS development team. 6 * Copyright (c) 2011,2012,2013,2014,2015,2016,2017,2018, by the GROMACS development team, led by 7 * Mark Abraham, David van der Spoel, Berk Hess, and Erik Lindahl, 8 * and including many others, as listed in the AUTHORS file in the 9 * top-level source directory and at http://www.gromacs.org. 10 * 11 * GROMACS is free software; you can redistribute it and/or 12 * modify it under the terms of the GNU Lesser General Public License 13 * as published by the Free Software Foundation; either version 2.1 14 * of the License, or (at your option) any later version. 15 * 16 * GROMACS is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19 * Lesser General Public License for more details. 20 * 21 * You should have received a copy of the GNU Lesser General Public 22 * License along with GROMACS; if not, see 23 * http://www.gnu.org/licenses, or write to the Free Software Foundation, 24 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 25 * 26 * If you want to redistribute modifications to GROMACS, please 27 * consider that scientific software is very special. Version 28 * control is crucial - bugs must be traceable. We will be happy to 29 * consider code for inclusion in the official distribution, but 30 * derived work must not be called official GROMACS. Details are found 31 * in the README & COPYING files - if they are missing, get the 32 * official version at http://www.gromacs.org. 33 * 34 * To help us fund GROMACS development, we humbly ask that you cite 35 * the research papers on the package. Check out http://www.gromacs.org. 36 */ 37/*! \internal \file 38 * 39 * \brief This file declares helper functionality for legacy option handling for mdrun 40 * 41 * \author Berk Hess <hess@kth.se> 42 * \author David van der Spoel <david.vanderspoel@icm.uu.se> 43 * \author Erik Lindahl <erik@kth.se> 44 * \author Mark Abraham <mark.j.abraham@gmail.com> 45 * 46 * \ingroup module_mdrun 47 */ 48#include "gmxpre.h" 49 50#include "legacymdrunoptions.h" 51 52#include "config.h" 53 54#include <cstring> 55 56#include "gromacs/gmxlib/network.h" 57#include "gromacs/math/functions.h" 58#include "gromacs/mdrun/multisim.h" 59#include "gromacs/mdrunutility/handlerestart.h" 60#include "gromacs/mdtypes/commrec.h" 61#include "gromacs/utility/arraysize.h" 62#include "gromacs/utility/fatalerror.h" 63 64namespace gmx 65{ 66 67/*! \brief Return whether the command-line parameter that 68 * will trigger a multi-simulation is set */ 69static bool is_multisim_option_set(int argc, const char *const argv[]) 70{ 71 for (int i = 0; i < argc; ++i) 72 { 73 if (strcmp(argv[i], "-multidir") == 0) 74 { 75 return true; 76 } 77 } 78 return false; 79} 80 81int LegacyMdrunOptions::updateFromCommandLine(int argc, char **argv, ArrayRef<const char *> desc) 82{ 83 unsigned long PCA_Flags = PCA_CAN_SET_DEFFNM; 84 // With -multidir, the working directory still needs to be 85 // changed, so we can't check for the existence of files during 86 // parsing. It isn't useful to do any completion based on file 87 // system contents, either. 88 if (is_multisim_option_set(argc, argv)) 89 { 90 PCA_Flags |= PCA_DISABLE_INPUT_FILE_CHECKING; 91 } 92 93 if (!parse_common_args(&argc, argv, PCA_Flags, 94 static_cast<int>(filenames.size()), filenames.data(), asize(pa), pa, 95 static_cast<int>(desc.size()), desc.data(), 0, nullptr, &oenv)) 96 { 97 return 0; 98 } 99 100 // Handle the options that permits the user to either declare 101 // which compatible GPUs are available for use, or to select a GPU 102 // task assignment. Either could be in an environment variable (so 103 // that there is a way to customize it, when using MPI in 104 // heterogeneous contexts). 105 { 106 // TODO Argument parsing can't handle std::string. We should 107 // fix that by changing the parsing, once more of the roles of 108 // handling, validating and implementing defaults for user 109 // command-line options have been separated. 110 hw_opt.gpuIdsAvailable = gpuIdsAvailable; 111 hw_opt.userGpuTaskAssignment = userGpuTaskAssignment; 112 113 const char *env = getenv("GMX_GPU_ID"); 114 if (env != nullptr) 115 { 116 if (!hw_opt.gpuIdsAvailable.empty()) 117 { 118 gmx_fatal(FARGS, "GMX_GPU_ID and -gpu_id can not be used at the same time"); 119 } 120 hw_opt.gpuIdsAvailable = env; 121 } 122 123 env = getenv("GMX_GPUTASKS"); 124 if (env != nullptr) 125 { 126 if (!hw_opt.userGpuTaskAssignment.empty()) 127 { 128 gmx_fatal(FARGS, "GMX_GPUTASKS and -gputasks can not be used at the same time"); 129 } 130 hw_opt.userGpuTaskAssignment = env; 131 } 132 133 if (!hw_opt.gpuIdsAvailable.empty() && !hw_opt.userGpuTaskAssignment.empty()) 134 { 135 gmx_fatal(FARGS, "-gpu_id and -gputasks cannot be used at the same time"); 136 } 137 } 138 139 hw_opt.thread_affinity = nenum(thread_aff_opt_choices); 140 141 // now check for a multi-simulation 142 ArrayRef<const std::string> multidir = opt2fnsIfOptionSet("-multidir", 143 static_cast<int>(filenames.size()), 144 filenames.data()); 145 146 if (replExParams.exchangeInterval != 0 && multidir.size() < 2) 147 { 148 gmx_fatal(FARGS, "Need at least two replicas for replica exchange (use option -multidir)"); 149 } 150 151 if (replExParams.numExchanges < 0) 152 { 153 gmx_fatal(FARGS, "Replica exchange number of exchanges needs to be positive"); 154 } 155 156 ms = init_multisystem(MPI_COMM_WORLD, multidir); 157 158 /* Prepare the intra-simulation communication */ 159 // TODO consolidate this with init_commrec, after changing the 160 // relative ordering of init_commrec and init_multisystem 161#if GMX_MPI 162 if (ms != nullptr) 163 { 164 cr->nnodes = cr->nnodes / ms->nsim; 165 MPI_Comm_split(MPI_COMM_WORLD, ms->sim, cr->sim_nodeid, &cr->mpi_comm_mysim); 166 cr->mpi_comm_mygroup = cr->mpi_comm_mysim; 167 MPI_Comm_rank(cr->mpi_comm_mysim, &cr->sim_nodeid); 168 MPI_Comm_rank(cr->mpi_comm_mygroup, &cr->nodeid); 169 } 170#endif 171 172 if (!opt2bSet("-cpi", 173 static_cast<int>(filenames.size()), filenames.data())) 174 { 175 // If we are not starting from a checkpoint we never allow files to be appended 176 // to, since that has caused a ton of strange behaviour and bugs in the past. 177 if (opt2parg_bSet("-append", asize(pa), pa)) 178 { 179 // If the user explicitly used the -append option, explain that it is not possible. 180 gmx_fatal(FARGS, "GROMACS can only append to files when restarting from a checkpoint."); 181 } 182 else 183 { 184 // If the user did not say anything explicit, just disable appending. 185 bTryToAppendFiles = FALSE; 186 } 187 } 188 189 ContinuationOptions &continuationOptions = mdrunOptions.continuationOptions; 190 191 continuationOptions.appendFilesOptionSet = opt2parg_bSet("-append", asize(pa), pa); 192 193 handleRestart(cr, ms, bTryToAppendFiles, 194 static_cast<int>(filenames.size()), 195 filenames.data(), 196 &continuationOptions.appendFiles, 197 &continuationOptions.startedFromCheckpoint); 198 199 mdrunOptions.rerun = opt2bSet("-rerun", 200 static_cast<int>(filenames.size()), 201 filenames.data()); 202 mdrunOptions.ntompOptionIsSet = opt2parg_bSet("-ntomp", asize(pa), pa); 203 204 domdecOptions.rankOrder = static_cast<DdRankOrder>(nenum(ddrank_opt_choices)); 205 domdecOptions.dlbOption = static_cast<DlbOption>(nenum(dddlb_opt_choices)); 206 domdecOptions.numCells[XX] = roundToInt(realddxyz[XX]); 207 domdecOptions.numCells[YY] = roundToInt(realddxyz[YY]); 208 domdecOptions.numCells[ZZ] = roundToInt(realddxyz[ZZ]); 209 210 return 1; 211} 212 213LegacyMdrunOptions::~LegacyMdrunOptions() 214{ 215 if (GMX_LIB_MPI) 216 { 217 done_commrec(cr); 218 } 219 done_multisim(ms); 220} 221 222} // namespace gmx 223