From 9103fde6f48d5a171bcbf4fa93059f05984d424a Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 09:12:30 -0400 Subject: [PATCH 01/24] DRR - Cpptraj: Initial attempt to add '-ya' command line flag for input trajectory arguments. --- src/Cpptraj.cpp | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index 387118094b..eb65b52e49 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -263,11 +263,14 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { commandLine_.clear(); for (int i = 1; i < argc; i++) commandLine_.append( " " + std::string(argv[i]) ); + ArgList cmdLineArgs( commandLine_ ); + mprintf("DEBUG: CmdLine: %s\n", cmdLineArgs.ArgLine() ); bool hasInput = false; bool interactive = false; Sarray inputFiles; Sarray topFiles; Sarray trajinFiles; + Sarray trajinArgs; Sarray trajoutFiles; Sarray refFiles; Sarray dataFiles; @@ -333,6 +336,9 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { } else if ( arg == "-y" && i+1 != argc) { // -y: Trajectory file in. AddFiles( trajinFiles, argc, argv, i ); + } else if ( arg == "-ya" && i+1 != argc) { + // -ya: Trajectory file in arguments. + AddFiles( trajinArgs, argc, argv, i ); } else if ( arg == "-x" && i+1 != argc) { // -x: Trajectory file out trajoutFiles.push_back( argv[++i] ); @@ -419,10 +425,30 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { ++refName) if (State_.AddReference( *refName )) return ERROR; // Add all input trajectories specified on command line. - for (Sarray::const_iterator trajinName = trajinFiles.begin(); - trajinName != trajinFiles.end(); - ++trajinName) - if (State_.AddInputTrajectory( *trajinName )) return ERROR; + // If there are fewer input trajectory arguments than input trajectories, + // duplicate the last input trajectory argument. + if (!trajinArgs.empty()) { + mprintf("DEBUG: trajinArgs:\n"); + for (Sarray::const_iterator ta = trajinArgs.begin(); ta != trajinArgs.end(); ++ta) + mprintf("\t%s\n", ta->c_str()); + if (trajinFiles.empty()) + mprintf("Warning: Input trajectory arguments specified but no input trajectories.\n"); + else { + if (trajinArgs.size() < trajinFiles.size()) + trajinArgs.resize( trajinFiles.size(), trajinArgs.back() ); + else if (trajinArgs.size() > trajinFiles.size()) { + mprintf("Warning: More input trajectory arguments specified than input trajectories.\n"); + trajinArgs.resize( trajinFiles.size() ); + } + } + for (unsigned int it = 0; it != trajinFiles.size(); it++) + if (State_.AddInputTrajectory( trajinFiles[it] + " " + trajinArgs[it] )) return ERROR; + } else { + for (Sarray::const_iterator trajinName = trajinFiles.begin(); + trajinName != trajinFiles.end(); + ++trajinName) + if (State_.AddInputTrajectory( *trajinName )) return ERROR; + } // Add all output trajectories specified on command line. if (!trajoutFiles.empty()) { hasInput = true; // This allows direct traj conversion with no other input From 94f4d7b555e681e75545ec030382ed2e046904b0 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 09:59:52 -0400 Subject: [PATCH 02/24] DRR - Cpptraj: Use ArgList to process command line args instead of argc/argv to take advantage of things like quote enclosure --- src/Cpptraj.cpp | 105 ++++++++++++++++++++++++++++-------------------- src/Cpptraj.h | 2 +- 2 files changed, 62 insertions(+), 45 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index eb65b52e49..a0fe7a3809 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -251,20 +251,33 @@ int Cpptraj::ProcessMask( Sarray const& topFiles, Sarray const& refFiles, return 0; } -void Cpptraj::AddFiles(Sarray& Files, int argc, char** argv, int& idx) { - Files.push_back( argv[++idx] ); - // Assume all following args without leading '-' are also files. - while (idx+1 != argc && argv[idx+1][0] != '-') - Files.push_back( argv[++idx] ); +/** Add current argument and all following arguments without leading '-' to + * given string array. + */ +void Cpptraj::AddArgs(Sarray& Args, ArgList const& cmdLineArgs, int& idx) +{ + Args.push_back( cmdLineArgs[++idx] ); + while (idx+1 != cmdLineArgs.Nargs() && cmdLineArgs[idx+1][0] != '-') + Args.push_back( cmdLineArgs[++idx] ); +} + +/** \return True if given argument matches key and is not the final argument. + */ +static inline bool NotFinalArg(std::string const& arg, const char* key, int pos, int nargs) +{ + return (arg == key && pos+1 != nargs); } /** Read command line args. */ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { + // First convert argv to one continuous string. commandLine_.clear(); for (int i = 1; i < argc; i++) commandLine_.append( " " + std::string(argv[i]) ); + // Use ArgList to split into arguments. ArgList cmdLineArgs( commandLine_ ); mprintf("DEBUG: CmdLine: %s\n", cmdLineArgs.ArgLine() ); + // Process command line flags from ArgList bool hasInput = false; bool interactive = false; Sarray inputFiles; @@ -275,8 +288,10 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { Sarray refFiles; Sarray dataFiles; std::string dataOut; - for (int i = 1; i < argc; i++) { - std::string arg(argv[i]); + for (int iarg = 0; iarg < cmdLineArgs.Nargs(); iarg++) + { + std::string const& arg = cmdLineArgs[iarg]; + // ----- One-and-done flags ------------------ if ( arg == "--help" || arg == "-h" ) { // --help, -help: Print usage and exit SetWorldSilent(true); @@ -312,75 +327,77 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { if (State_.TrajLength( topFiles[0], trajinFiles )) return ERROR; return QUIT; } - if ( arg == "--interactive" ) + // ----- Single flags ------------------------ + if ( arg == "--interactive" ) { interactive = true; - else if ( arg == "--suppress-all-output") { + } else if ( arg == "--suppress-all-output") { mprintf("Info: All further output will be suppressed.\n"); SuppressAllOutput(); - } else if ( arg == "-debug" && i+1 != argc) { + // ----- Flags that precede values ----------- + } else if ( NotFinalArg(arg, "-debug", iarg, cmdLineArgs.Nargs()) ) { // -debug: Set overall debug level - ArgList dbgarg( argv[++i] ); + ArgList dbgarg( cmdLineArgs[++iarg] ); State_.SetListDebug( dbgarg ); - } else if ( arg == "--log" && i+1 != argc) + } else if ( NotFinalArg(arg, "--log", iarg, cmdLineArgs.Nargs()) ) { // --log: Set up log file for interactive mode - logfilename_ = argv[++i]; - else if ( arg == "-p" && i+1 != argc) { + logfilename_ = cmdLineArgs[++iarg]; + } else if ( NotFinalArg(arg, "-p", iarg, cmdLineArgs.Nargs()) ) { // -p: Topology file - AddFiles( topFiles, argc, argv, i ); - } else if ( arg == "-d" && i+1 != argc) { + AddArgs( topFiles, cmdLineArgs, iarg ); + } else if ( NotFinalArg(arg, "-d", iarg, cmdLineArgs.Nargs()) ) { // -d: Read data file - AddFiles( dataFiles, argc, argv, i ); - } else if ( arg == "-w" && i+1 != argc) { + AddArgs( dataFiles, cmdLineArgs, iarg ); + } else if ( NotFinalArg(arg, "-w", iarg, cmdLineArgs.Nargs()) ) { // -w: Write data file. Only one allowed. For data file conversion. - dataOut.assign( argv[++i] ); - } else if ( arg == "-y" && i+1 != argc) { + dataOut.assign( cmdLineArgs[++iarg] ); + } else if ( NotFinalArg(arg, "-y", iarg, cmdLineArgs.Nargs()) ) { // -y: Trajectory file in. - AddFiles( trajinFiles, argc, argv, i ); - } else if ( arg == "-ya" && i+1 != argc) { + AddArgs( trajinFiles, cmdLineArgs, iarg ); + } else if ( NotFinalArg(arg, "-ya", iarg, cmdLineArgs.Nargs()) ) { // -ya: Trajectory file in arguments. - AddFiles( trajinArgs, argc, argv, i ); - } else if ( arg == "-x" && i+1 != argc) { + AddArgs( trajinArgs, cmdLineArgs, iarg ); + } else if ( NotFinalArg(arg, "-x", iarg, cmdLineArgs.Nargs()) ) { // -x: Trajectory file out - trajoutFiles.push_back( argv[++i] ); - } else if ( arg == "-c" && i+1 != argc) { + trajoutFiles.push_back( cmdLineArgs[++iarg] ); + } else if ( NotFinalArg(arg, "-c", iarg, cmdLineArgs.Nargs()) ) { // -c: Reference file - AddFiles( refFiles, argc, argv, i ); - } else if (arg == "-i" && i+1 != argc) { + AddArgs( refFiles, cmdLineArgs, iarg ); + } else if ( NotFinalArg(arg, "-i", iarg, cmdLineArgs.Nargs()) ) { // -i: Input file(s) - AddFiles( inputFiles, argc, argv, i ); - } else if (arg == "-o" && i+1 != argc) { + AddArgs( inputFiles, cmdLineArgs, iarg ); + } else if ( NotFinalArg(arg, "-o", iarg, cmdLineArgs.Nargs()) ) { // -o: Output file - FileName ofilename(argv[++i]); + FileName ofilename(cmdLineArgs[++iarg]); if (ofilename.empty()) { mprinterr("Error: Could not set up output file with name '%s'\n", ofilename.full()); return ERROR; } if (OutputToFile(ofilename.full())) return ERROR; - } else if (arg == "-ms" && i+1 != argc) { + } else if ( NotFinalArg(arg, "-ms", iarg, cmdLineArgs.Nargs()) ) { // -ms: Parse mask string, print selected atom #s - if (ProcessMask( topFiles, refFiles, std::string(argv[++i]), false, false )) return ERROR; + if (ProcessMask( topFiles, refFiles, cmdLineArgs[++iarg], false, false )) return ERROR; return QUIT; - } else if (arg == "-mr" && i+1 != argc) { + } else if ( NotFinalArg(arg, "-mr", iarg, cmdLineArgs.Nargs()) ) { // -mr: Parse mask string, print selected res #s - if (ProcessMask( topFiles, refFiles, std::string(argv[++i]), false, true )) return ERROR; + if (ProcessMask( topFiles, refFiles, cmdLineArgs[++iarg], false, true )) return ERROR; return QUIT; - } else if (arg == "--mask" && i+1 != argc) { + } else if ( NotFinalArg(arg, "--mask", iarg, cmdLineArgs.Nargs()) ) { // --mask: Parse mask string, print selected atom details - if (ProcessMask( topFiles, refFiles, std::string(argv[++i]), true, false )) return ERROR; + if (ProcessMask( topFiles, refFiles, cmdLineArgs[++iarg], true, false )) return ERROR; return QUIT; - } else if (arg == "--resmask" && i+1 != argc) { + } else if ( NotFinalArg(arg, "--resmask", iarg, cmdLineArgs.Nargs()) ) { // --resmask: Parse mask string, print selected residue details - if (ProcessMask( topFiles, refFiles, std::string(argv[++i]), true, true )) return ERROR; + if (ProcessMask( topFiles, refFiles, cmdLineArgs[++iarg], true, true )) return ERROR; return QUIT; - } else if ( i == 1 ) { + } else if ( iarg == 0 ) { // For backwards compatibility with PTRAJ; Position 1 = TOP file - topFiles.push_back( argv[i] ); - } else if ( i == 2 ) { + topFiles.push_back( cmdLineArgs[iarg] ); + } else if ( iarg == 1 ) { // For backwards compatibility with PTRAJ; Position 2 = INPUT file - inputFiles.push_back( argv[i] ); + inputFiles.push_back( cmdLineArgs[iarg] ); } else { // Unrecognized - mprintf(" Unrecognized input on command line: %i: %s\n", i,argv[i]); + mprintf(" Unrecognized input on command line: %i: %s\n", iarg+1, cmdLineArgs[iarg].c_str()); Usage(); return ERROR; } diff --git a/src/Cpptraj.h b/src/Cpptraj.h index 9528bc1f33..39916eeebb 100644 --- a/src/Cpptraj.h +++ b/src/Cpptraj.h @@ -18,8 +18,8 @@ class Cpptraj { static void Usage(); static void Intro(); static void Finalize(); + static inline void AddArgs(Sarray&, ArgList const&, int&); int ProcessMask(Sarray const&, Sarray const&, std::string const&, bool,bool) const; - static inline void AddFiles(Sarray&, int, char**, int&); Mode ProcessCmdLineArgs(int, char**); int Interactive(); From eaa1cb5a7d18f9468d478f3462f74476981f897e Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 10:34:05 -0400 Subject: [PATCH 03/24] DRR - Cpptraj: Change automatic detection of topology and input files on command line to be position-independent. Add detection of input trajectory files on command line. --- src/Cpptraj.cpp | 39 +++++++++++++++++++++++++++++---------- src/ParmFile.h | 3 ++- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index a0fe7a3809..564f58fb57 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -389,19 +389,38 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { // --resmask: Parse mask string, print selected residue details if (ProcessMask( topFiles, refFiles, cmdLineArgs[++iarg], true, true )) return ERROR; return QUIT; - } else if ( iarg == 0 ) { - // For backwards compatibility with PTRAJ; Position 1 = TOP file - topFiles.push_back( cmdLineArgs[iarg] ); - } else if ( iarg == 1 ) { - // For backwards compatibility with PTRAJ; Position 2 = INPUT file - inputFiles.push_back( cmdLineArgs[iarg] ); } else { + // Check if this is a file. TODO only have master do this MPI + bool unrecognized = true; + if ( arg[0] != '-' && File::Exists(arg) ) { + unrecognized = false; + // Check if this is a topology file. + ParmFile::ParmFormatType ptype; + ParmIO* pio = ParmFile::DetectFormat( arg, ptype ); + if (pio != 0) { + topFiles.push_back( arg ); + } else { + // Check if this is a trajectory file. + TrajectoryFile::TrajFormatType ttype; + TrajectoryIO* tio = TrajectoryFile::DetectFormat( arg, ttype ); + if (tio != 0) { + trajinFiles.push_back( arg ); + } else { + mprintf("Warning: Assuming '%s' contains cpptraj input.\n", arg.c_str()); + // Assume input file + inputFiles.push_back( arg ); + } + } + } // Unrecognized - mprintf(" Unrecognized input on command line: %i: %s\n", iarg+1, cmdLineArgs[iarg].c_str()); - Usage(); - return ERROR; + if (unrecognized) { + mprinterr("Error: Unrecognized input on command line: %i: %s\n", + iarg+1, cmdLineArgs[iarg].c_str()); + Usage(); + return ERROR; + } } - } + } // END loop over command line flags Cpptraj::Intro(); // Add all data files specified on command lin. for (Sarray::const_iterator dataFilename = dataFiles.begin(); diff --git a/src/ParmFile.h b/src/ParmFile.h index f54c343c88..01c86fefc9 100644 --- a/src/ParmFile.h +++ b/src/ParmFile.h @@ -25,8 +25,9 @@ class ParmFile { return WriteTopology(t, n, ArgList(), f, d); } FileName const& ParmFilename() { return parmName_; } + /// \return Allocated ParmIO if given file matches known type, 0 otherwise. + static ParmIO* DetectFormat(FileName const&, ParmFormatType&); private : - ParmIO* DetectFormat(FileName const&, ParmFormatType&); FileName parmName_; ///< Topology input/output file name. }; #endif From 77687b2cfbed90dba8d9c04ad869ba12af7da21d Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 10:36:54 -0400 Subject: [PATCH 04/24] DRR - Cpptraj: Add command line test. --- test/Makefile | 6 +++++- test/Test_CmdLine/RunTest.sh | 31 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) create mode 100755 test/Test_CmdLine/RunTest.sh diff --git a/test/Makefile b/test/Makefile index 7b5481b4c4..cffaabb1ff 100644 --- a/test/Makefile +++ b/test/Makefile @@ -434,6 +434,9 @@ test.infraredspec: test.cphstats: @-cd Test_Cphstats && ./RunTest.sh $(OPT) +test.cmdline: + @-cd Test_CmdLine && ./RunTest.sh $(OPT) + # Every test target should go here. COMPLETETESTS=test.general \ test.strip \ @@ -573,7 +576,8 @@ COMPLETETESTS=test.general \ test.phipsi \ test.control \ test.infraredspec \ - test.cphstats + test.cphstats \ + test.cmdline test.all: $(MAKE) test.complete summary diff --git a/test/Test_CmdLine/RunTest.sh b/test/Test_CmdLine/RunTest.sh new file mode 100755 index 0000000000..c2f0a97d0f --- /dev/null +++ b/test/Test_CmdLine/RunTest.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +. ../MasterTest.sh + +# Clean +CleanFiles cmd.in test1.crd.save test1.crd + +TESTNAME='Command line tests' +# Required environment +Requires notparallel + +INPUT='-i cmd.in' + +# First test without command line +cat > cmd.in < Date: Mon, 18 Jun 2018 10:43:09 -0400 Subject: [PATCH 05/24] DRR - Cpptraj: Simplify NotFinalArg() --- src/Cpptraj.cpp | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index 564f58fb57..d097711849 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -261,11 +261,11 @@ void Cpptraj::AddArgs(Sarray& Args, ArgList const& cmdLineArgs, int& idx) Args.push_back( cmdLineArgs[++idx] ); } -/** \return True if given argument matches key and is not the final argument. +/** \return True if argument at position matches key and is not the final argument. */ -static inline bool NotFinalArg(std::string const& arg, const char* key, int pos, int nargs) +static inline bool NotFinalArg(ArgList const& cmdLineArgs, const char* key, int pos) { - return (arg == key && pos+1 != nargs); + return (cmdLineArgs[pos] == key && pos+1 != cmdLineArgs.Nargs()); } /** Read command line args. */ @@ -334,38 +334,38 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { mprintf("Info: All further output will be suppressed.\n"); SuppressAllOutput(); // ----- Flags that precede values ----------- - } else if ( NotFinalArg(arg, "-debug", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "-debug", iarg) ) { // -debug: Set overall debug level ArgList dbgarg( cmdLineArgs[++iarg] ); State_.SetListDebug( dbgarg ); - } else if ( NotFinalArg(arg, "--log", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "--log", iarg) ) { // --log: Set up log file for interactive mode logfilename_ = cmdLineArgs[++iarg]; - } else if ( NotFinalArg(arg, "-p", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "-p", iarg) ) { // -p: Topology file AddArgs( topFiles, cmdLineArgs, iarg ); - } else if ( NotFinalArg(arg, "-d", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "-d", iarg) ) { // -d: Read data file AddArgs( dataFiles, cmdLineArgs, iarg ); - } else if ( NotFinalArg(arg, "-w", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "-w", iarg) ) { // -w: Write data file. Only one allowed. For data file conversion. dataOut.assign( cmdLineArgs[++iarg] ); - } else if ( NotFinalArg(arg, "-y", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "-y", iarg) ) { // -y: Trajectory file in. AddArgs( trajinFiles, cmdLineArgs, iarg ); - } else if ( NotFinalArg(arg, "-ya", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "-ya", iarg) ) { // -ya: Trajectory file in arguments. AddArgs( trajinArgs, cmdLineArgs, iarg ); - } else if ( NotFinalArg(arg, "-x", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "-x", iarg) ) { // -x: Trajectory file out trajoutFiles.push_back( cmdLineArgs[++iarg] ); - } else if ( NotFinalArg(arg, "-c", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "-c", iarg) ) { // -c: Reference file AddArgs( refFiles, cmdLineArgs, iarg ); - } else if ( NotFinalArg(arg, "-i", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "-i", iarg) ) { // -i: Input file(s) AddArgs( inputFiles, cmdLineArgs, iarg ); - } else if ( NotFinalArg(arg, "-o", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "-o", iarg) ) { // -o: Output file FileName ofilename(cmdLineArgs[++iarg]); if (ofilename.empty()) { @@ -373,19 +373,19 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { return ERROR; } if (OutputToFile(ofilename.full())) return ERROR; - } else if ( NotFinalArg(arg, "-ms", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "-ms", iarg) ) { // -ms: Parse mask string, print selected atom #s if (ProcessMask( topFiles, refFiles, cmdLineArgs[++iarg], false, false )) return ERROR; return QUIT; - } else if ( NotFinalArg(arg, "-mr", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "-mr", iarg) ) { // -mr: Parse mask string, print selected res #s if (ProcessMask( topFiles, refFiles, cmdLineArgs[++iarg], false, true )) return ERROR; return QUIT; - } else if ( NotFinalArg(arg, "--mask", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "--mask", iarg) ) { // --mask: Parse mask string, print selected atom details if (ProcessMask( topFiles, refFiles, cmdLineArgs[++iarg], true, false )) return ERROR; return QUIT; - } else if ( NotFinalArg(arg, "--resmask", iarg, cmdLineArgs.Nargs()) ) { + } else if ( NotFinalArg(cmdLineArgs, "--resmask", iarg) ) { // --resmask: Parse mask string, print selected residue details if (ProcessMask( topFiles, refFiles, cmdLineArgs[++iarg], true, true )) return ERROR; return QUIT; From f5f018fd58e9d831af60c760d798eccd678242f1 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 10:53:18 -0400 Subject: [PATCH 06/24] DRR - Cpptraj: Fix memory leaks during automatic detection of traj/parm files on command line. --- src/Cpptraj.cpp | 10 ++++------ src/ParmFile.cpp | 8 ++++++++ src/ParmFile.h | 5 ++++- src/TrajectoryFile.cpp | 8 ++++++++ src/TrajectoryFile.h | 2 ++ 5 files changed, 26 insertions(+), 7 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index d097711849..165f71cf9c 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -395,15 +395,13 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { if ( arg[0] != '-' && File::Exists(arg) ) { unrecognized = false; // Check if this is a topology file. - ParmFile::ParmFormatType ptype; - ParmIO* pio = ParmFile::DetectFormat( arg, ptype ); - if (pio != 0) { + ParmFile::ParmFormatType ptype = ParmFile::DetectFormat( arg ); + if (ptype != ParmFile::UNKNOWN_PARM) { topFiles.push_back( arg ); } else { // Check if this is a trajectory file. - TrajectoryFile::TrajFormatType ttype; - TrajectoryIO* tio = TrajectoryFile::DetectFormat( arg, ttype ); - if (tio != 0) { + TrajectoryFile::TrajFormatType ttype = TrajectoryFile::DetectFormat( arg ); + if (ttype != TrajectoryFile::UNKNOWN_TRAJ) { trajinFiles.push_back( arg ); } else { mprintf("Warning: Assuming '%s' contains cpptraj input.\n", arg.c_str()); diff --git a/src/ParmFile.cpp b/src/ParmFile.cpp index dc7d8ef0a0..6e182840fb 100644 --- a/src/ParmFile.cpp +++ b/src/ParmFile.cpp @@ -59,6 +59,14 @@ ParmIO* ParmFile::DetectFormat(FileName const& fname, ParmFormatType& ptype) { return 0; } +// ParmFile::DetectFormat() +ParmFile::ParmFormatType ParmFile::DetectFormat(FileName const& fname) { + ParmFormatType ptype; + ParmIO* pio = DetectFormat(fname, ptype); + delete pio; + return ptype; +} + // ParmFile::ReadTopology() int ParmFile::ReadTopology(Topology& Top, FileName const& fnameIn, ArgList const& argListIn, int debugIn) diff --git a/src/ParmFile.h b/src/ParmFile.h index 01c86fefc9..ce2dafa717 100644 --- a/src/ParmFile.h +++ b/src/ParmFile.h @@ -25,9 +25,12 @@ class ParmFile { return WriteTopology(t, n, ArgList(), f, d); } FileName const& ParmFilename() { return parmName_; } + /// \return ParmFormatType of given file or UNKNOWN_PARM. + static ParmFormatType DetectFormat(FileName const&); + private : /// \return Allocated ParmIO if given file matches known type, 0 otherwise. static ParmIO* DetectFormat(FileName const&, ParmFormatType&); - private : + FileName parmName_; ///< Topology input/output file name. }; #endif diff --git a/src/TrajectoryFile.cpp b/src/TrajectoryFile.cpp index 7e05fe8e43..b4c5d34a49 100644 --- a/src/TrajectoryFile.cpp +++ b/src/TrajectoryFile.cpp @@ -128,3 +128,11 @@ TrajectoryIO* TrajectoryFile::DetectFormat(FileName const& fname, TrajFormatType ttype = UNKNOWN_TRAJ; return 0; } + +// TrajectoryFile::DetectFormat() +TrajectoryFile::TrajFormatType TrajectoryFile::DetectFormat(FileName const& fname) { + TrajFormatType ttype; + TrajectoryIO* tio = DetectFormat(fname, ttype); + delete tio; + return ttype; +} diff --git a/src/TrajectoryFile.h b/src/TrajectoryFile.h index 132d9a2b60..6525ee79f1 100644 --- a/src/TrajectoryFile.h +++ b/src/TrajectoryFile.h @@ -59,5 +59,7 @@ class TrajectoryFile { static TrajectoryIO* AllocTrajIO(TrajFormatType t) { return (TrajectoryIO*)FileTypes::AllocIO(TF_AllocArray, t, true); } + /// \return TrajFormatType of given file or UNKNOWN_TRAJ + static TrajFormatType DetectFormat(FileName const&); }; #endif From dfc8dbfc151bf03772ffac49d85dda31eaf861c7 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 11:25:18 -0400 Subject: [PATCH 07/24] DRR - Cpptraj: With MPI, only have master autodetect files on command line --- src/Cpptraj.cpp | 57 ++++++++++++++++++++++++++++++------------------- 1 file changed, 35 insertions(+), 22 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index 165f71cf9c..45c4dd3583 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -268,6 +268,25 @@ static inline bool NotFinalArg(ArgList const& cmdLineArgs, const char* key, int return (cmdLineArgs[pos] == key && pos+1 != cmdLineArgs.Nargs()); } +/** \return 0 if unknown, 1 if topology, 2 if trajectory, 3 if input. */ +static inline int AutoDetect(std::string const& arg) +{ + if (File::Exists(arg)) { + // Check if this is a topology file. + ParmFile::ParmFormatType ptype = ParmFile::DetectFormat( arg ); + if (ptype != ParmFile::UNKNOWN_PARM) + return 1; + // Check if this is a trajectory file. + TrajectoryFile::TrajFormatType ttype = TrajectoryFile::DetectFormat( arg ); + if (ttype != TrajectoryFile::UNKNOWN_TRAJ) + return 2; + // Assume input file + mprintf("Warning: Assuming '%s' contains cpptraj input.\n", arg.c_str()); + return 3; + } + return 0; +} + /** Read command line args. */ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { // First convert argv to one continuous string. @@ -390,28 +409,22 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { if (ProcessMask( topFiles, refFiles, cmdLineArgs[++iarg], true, true )) return ERROR; return QUIT; } else { - // Check if this is a file. TODO only have master do this MPI - bool unrecognized = true; - if ( arg[0] != '-' && File::Exists(arg) ) { - unrecognized = false; - // Check if this is a topology file. - ParmFile::ParmFormatType ptype = ParmFile::DetectFormat( arg ); - if (ptype != ParmFile::UNKNOWN_PARM) { - topFiles.push_back( arg ); - } else { - // Check if this is a trajectory file. - TrajectoryFile::TrajFormatType ttype = TrajectoryFile::DetectFormat( arg ); - if (ttype != TrajectoryFile::UNKNOWN_TRAJ) { - trajinFiles.push_back( arg ); - } else { - mprintf("Warning: Assuming '%s' contains cpptraj input.\n", arg.c_str()); - // Assume input file - inputFiles.push_back( arg ); - } - } - } - // Unrecognized - if (unrecognized) { + // Check if this is a file. +# ifdef MPI + int ftype; + if (Parallel::World().Master()) + ftype = AutoDetect( arg ); + Parallel::World().MasterBcast(&ftype, 1, MPI_INT); +# else + int ftype = AutoDetect( arg ); +# endif + if (ftype == 1) + topFiles.push_back( arg ); + else if (ftype == 2) + trajinFiles.push_back( arg ); + else if (ftype == 3) + inputFiles.push_back( arg ); + else { mprinterr("Error: Unrecognized input on command line: %i: %s\n", iarg+1, cmdLineArgs[iarg].c_str()); Usage(); From 05f87f288b3c3ab5140c1e393d7f7309a6dd17d7 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 11:29:39 -0400 Subject: [PATCH 08/24] DRR - Cpptraj: Test is good up to 8 threads --- test/Test_CmdLine/RunTest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Test_CmdLine/RunTest.sh b/test/Test_CmdLine/RunTest.sh index c2f0a97d0f..5533678709 100755 --- a/test/Test_CmdLine/RunTest.sh +++ b/test/Test_CmdLine/RunTest.sh @@ -7,7 +7,7 @@ CleanFiles cmd.in test1.crd.save test1.crd TESTNAME='Command line tests' # Required environment -Requires notparallel +Requires maxthreads 8 INPUT='-i cmd.in' From 60095ec1f54ce16d087acd508bbb5740515f7031 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 11:57:33 -0400 Subject: [PATCH 09/24] DRR - Cpptraj: Correct some references to MPI threads to MPI processes - only use 'threads' to refer to OpenMP. Report on number of OpenMP threads at beginning of run in additon to MPI processes. --- src/Cpptraj.cpp | 8 +++++- src/CpptrajState.cpp | 60 ++++++++++++++++++++-------------------- src/CpptrajState.h | 2 +- src/Exec_CrdAction.cpp | 2 +- src/Exec_CrdOut.cpp | 2 +- src/Exec_RunAnalysis.cpp | 2 +- src/Parallel.cpp | 44 ++++++++++++++--------------- src/Parallel.h | 16 +++++------ 8 files changed, 71 insertions(+), 65 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index 45c4dd3583..3abcf7f7b7 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -17,6 +17,9 @@ #ifdef CUDA # include #endif +#ifdef _OPENMP +# include +#endif /// CONSTRUCTOR - initializes all commands Cpptraj::Cpptraj() { @@ -77,7 +80,10 @@ void Cpptraj::Intro() { "\n ___ ___ ___ ___\n | \\/ | \\/ | \\/ | \n _|_/\\_|_/\\_|_/\\_|_\n\n", CPPTRAJ_VERSION_STRING); # ifdef MPI - mprintf("| Running on %i threads\n", Parallel::World().Size()); + mprintf("| Running on %i processes.\n", Parallel::World().Size()); +# endif +# ifdef _OPENMP + mprintf("| %i OpenMP threads available.\n", omp_get_max_threads()); # endif mprintf("| Date/time: %s\n", TimeString().c_str()); std::string available_mem = AvailableMemoryStr(); diff --git a/src/CpptrajState.cpp b/src/CpptrajState.cpp index b760c88e22..3c16fd3333 100644 --- a/src/CpptrajState.cpp +++ b/src/CpptrajState.cpp @@ -515,7 +515,7 @@ int CpptrajState::RunEnsemble() { // In parallel only two frames needed; one for reading, one for receiving. FramePtrArray SortedFrames( 2 ); FrameArray FrameEnsemble( 2 ); - // Each thread will process one member of the ensemble, so local ensemble + // Each process will handle one member of the ensemble, so local ensemble // size is effectively 1. ensembleSize = 1; # else @@ -533,7 +533,7 @@ int CpptrajState::RunEnsemble() { ActionEnsemble[0] = &actionList_; for (int member = 1; member < ensembleSize; member++) ActionEnsemble[member] = new ActionList(); - // If we are on a single thread, give each member its own copy of the + // If we are on a single process, give each member its own copy of the // current topology address. This way if topology is modified by a member, // e.g. in strip or closest, subsequent members wont be trying to modify // an already-modified topology. @@ -739,19 +739,19 @@ int CpptrajState::RunEnsemble() { } #ifdef MPI // ----------------------------------------------------------------------------- -void CpptrajState::DivideFramesAmongThreads(int& my_start, int& my_stop, int& my_frames, +void CpptrajState::DivideFramesAmongProcesses(int& my_start, int& my_stop, int& my_frames, int maxFrames, Parallel::Comm const& commIn) const { - my_frames = commIn.DivideAmongThreads(my_start, my_stop, maxFrames); - std::vector frames_per_thread( commIn.Size() ); - commIn.GatherMaster(&my_frames, 1, MPI_INT, &frames_per_thread[0]); + my_frames = commIn.DivideAmongProcesses(my_start, my_stop, maxFrames); + std::vector frames_per_process( commIn.Size() ); + commIn.GatherMaster(&my_frames, 1, MPI_INT, &frames_per_process[0]); // Print how many frames each rank will process. if (commIn.Master()) { mprintf("\nPARALLEL INFO:\n"); if (Parallel::EnsembleComm().Size() > 1) - mprintf(" %i threads per ensemble member.\n", commIn.Size()); + mprintf(" %i processes per ensemble member.\n", commIn.Size()); for (int rank = 0; rank != commIn.Size(); rank++) - mprintf(" Thread %i will process %i frames.\n", rank, frames_per_thread[rank]); + mprintf(" Process %i will handle %i frames.\n", rank, frames_per_process[rank]); } commIn.Barrier(); if (debug_ > 0) rprintf("Start %i Stop %i Frames %i\n", my_start+1, my_stop, my_frames); @@ -773,13 +773,13 @@ int CpptrajState::PreloadCheck(int my_start, int my_frames, return 1; } else if (my_frames == n_previous_frames) { rprinterr("Error: Number of preload frames is same as number of processed frames.\n" - "Error: Try reducing the number of threads.\n"); + "Error: Try reducing the number of processes.\n"); return 1; } if (n_previous_frames > (my_frames / 2)) rprintf("Warning: Number of preload frames is greater than half the " "number of processed frames.\n" - "Warning: Try reducing the number of threads.\n"); + "Warning: Try reducing the number of processes.\n"); rprintf("Warning: Preloading %i frames. These frames will NOT have Actions performed on them.\n", n_previous_frames); return 0; @@ -805,19 +805,19 @@ int CpptrajState::RunParaEnsemble() { int err = NAV.AddEnsembles(trajinList_.ensemble_begin(), trajinList_.ensemble_end()); if (Parallel::World().CheckError( err )) return 1; - // Divide frames among threads + // Divide frames among processes int my_start, my_stop, my_frames; - DivideFramesAmongThreads(my_start, my_stop, my_frames, NAV.IDX().MaxFrames(), TrajComm); - // Ensure at least 1 frame per thread, otherwise some ranks could cause hangups. + DivideFramesAmongProcesses(my_start, my_stop, my_frames, NAV.IDX().MaxFrames(), TrajComm); + // Ensure at least 1 frame per process, otherwise some ranks could cause hangups. if (my_frames > 0) err = 0; else { - rprinterr("Error: Thread is processing less than 1 frame. Try reducing # threads.\n"); + rprinterr("Error: Process is handling less than 1 frame. Try reducing # processes.\n"); err = 1; } if (Parallel::World().CheckError( err )) return 1; - // Allocate DataSets in the master DataSetList based on # frames to be read by this thread. + // Allocate DataSets in the master DataSetList based on # frames to be read by this process. DSL_.AllocateSets( my_frames ); // Any DataSets added to the DataSetList during run will need to be synced. DSL_.SetNewSetsNeedSync( true ); @@ -917,9 +917,9 @@ int CpptrajState::RunParaEnsemble() { ensembleOut_.CloseEnsembleOut(); DSL_.SetNewSetsNeedSync( false ); sync_time_.Start(); - // Sync Actions to master thread + // Sync Actions to master process actionList_.SyncActions(); - // Sync data sets to master thread + // Sync data sets to master process if (DSL_.SynchronizeData( TrajComm )) return 1; sync_time_.Stop(); mprintf("\nACTION OUTPUT:\n"); @@ -968,19 +968,19 @@ int CpptrajState::RunParallel() { if (input_traj.AddInputTraj( *traj )) { err = 1; break; } if (TrajComm.CheckError( err )) return 1; - // Divide frames among threads. + // Divide frames among processes. int my_start, my_stop, my_frames; - DivideFramesAmongThreads(my_start, my_stop, my_frames, input_traj.Size(), TrajComm); - // Ensure at least 1 frame per thread, otherwise some ranks could cause hangups. + DivideFramesAmongProcesses(my_start, my_stop, my_frames, input_traj.Size(), TrajComm); + // Ensure at least 1 frame per process, otherwise some ranks could cause hangups. if (my_frames > 0) err = 0; else { - rprinterr("Error: Thread is processing less than 1 frame. Try reducing # threads.\n"); + rprinterr("Error: Process is handling less than 1 frame. Try reducing # processes.\n"); err = 1; } if (TrajComm.CheckError( err )) return 1; - // Allocate DataSets in DataSetList based on # frames read by this thread. + // Allocate DataSets in DataSetList based on # frames read by this process. DSL_.AllocateSets( my_frames ); // Any DataSets added to the DataSetList during run will need to be synced. DSL_.SetNewSetsNeedSync( true ); @@ -1093,9 +1093,9 @@ int CpptrajState::RunParallel() { trajoutList_.CloseTrajout(); DSL_.SetNewSetsNeedSync( false ); sync_time_.Start(); - // Sync Actions to master thread + // Sync Actions to master process actionList_.SyncActions(); - // Sync data sets to master thread + // Sync data sets to master process if (DSL_.SynchronizeData( TrajComm )) return 1; sync_time_.Stop(); post_time_.Start(); @@ -1120,10 +1120,10 @@ int CpptrajState::RunSingleTrajParallel() { // Set up single trajectory for parallel read. Trajin* trajin = *(trajinList_.trajin_begin()); trajin->ParallelBeginTraj( Parallel::World() ); - // Divide frames among threads. + // Divide frames among processes. int total_read_frames = trajin->Traj().Counter().TotalReadFrames(); int my_start, my_stop, my_frames; - std::vector rank_frames = DivideFramesAmongThreads(my_start, my_stop, my_frames, + std::vector rank_frames = DivideFramesAmongProcesses(my_start, my_stop, my_frames, total_read_frames, Parallel::World().Size(), Parallel::World().Rank(), @@ -1135,7 +1135,7 @@ int CpptrajState::RunSingleTrajParallel() { rprintf("Start and stop adjusted for offset: %i to %i\n", traj_start, traj_stop); Parallel::World().Barrier(); - // Allocate DataSets in DataSetList based on # frames read by this thread. + // Allocate DataSets in DataSetList based on # frames read by this process. DSL_.AllocateSets( my_frames ); // ----- SETUP PHASE --------------------------- @@ -1189,11 +1189,11 @@ int CpptrajState::RunSingleTrajParallel() { mprintf("TIME: Avg. throughput= %.4f frames / second.\n", (double)total_read_frames / frames_time.Total()); trajoutList_.CloseTrajout(); - // Sync data sets to master thread + // Sync data sets to master process Timer time_sync; time_sync.Start(); if (DSL_.SynchronizeData( total_read_frames, rank_frames, Parallel::World() )) return 1; - // Sync Actions to master thread + // Sync Actions to master process actionList_.SyncActions(); time_sync.Stop(); time_sync.WriteTiming(1, "Data set/actions sync"); @@ -1368,7 +1368,7 @@ int CpptrajState::RunAnalyses() { # ifdef MPI // Only master performs analyses currently. if (Parallel::TrajComm().Size() > 1) - mprintf("Warning: Analysis does not currently use multiple MPI threads.\n"); + mprintf("Warning: Analysis does not currently use multiple MPI processes.\n"); if (Parallel::TrajComm().Master()) # endif err = analysisList_.DoAnalyses(); diff --git a/src/CpptrajState.h b/src/CpptrajState.h index a738286afe..7d274d2540 100644 --- a/src/CpptrajState.h +++ b/src/CpptrajState.h @@ -83,7 +83,7 @@ class CpptrajState { int RunNormal(); int RunEnsemble(); # ifdef MPI - void DivideFramesAmongThreads(int&, int&, int&, int, Parallel::Comm const&) const; + void DivideFramesAmongProcesses(int&, int&, int&, int, Parallel::Comm const&) const; int PreloadCheck(int, int, int&, int&) const; int RunParallel(); int RunParaEnsemble(); diff --git a/src/Exec_CrdAction.cpp b/src/Exec_CrdAction.cpp index 442733df2c..916ee8e3f5 100644 --- a/src/Exec_CrdAction.cpp +++ b/src/Exec_CrdAction.cpp @@ -110,7 +110,7 @@ Exec::RetType Exec_CrdAction::Execute(CpptrajState& State, ArgList& argIn) { //rprintf("DEBUG: About to create new comm, ID= %i\n", ID); trajComm_ = Parallel::World().Split( ID ); if (ID != MPI_UNDEFINED) { - mprintf("Warning: '%s' command does not yet use multiple MPI threads.\n", argIn.Command()); + mprintf("Warning: '%s' command does not yet use multiple MPI processes.\n", argIn.Command()); ret = ProcessArgs(State, argIn); if (ret != CpptrajState::OK) err = 1; diff --git a/src/Exec_CrdOut.cpp b/src/Exec_CrdOut.cpp index ad705c654c..965ec407c5 100644 --- a/src/Exec_CrdOut.cpp +++ b/src/Exec_CrdOut.cpp @@ -18,7 +18,7 @@ Exec::RetType Exec_CrdOut::Execute(CpptrajState& State, ArgList& argIn) { //rprintf("DEBUG: About to create new comm, ID= %i\n", ID); trajComm_ = Parallel::World().Split( ID ); if (ID != MPI_UNDEFINED) { - mprintf("Warning: '%s' command does not yet use multiple MPI threads.\n", argIn.Command()); + mprintf("Warning: '%s' command does not yet use multiple MPI processes.\n", argIn.Command()); ret = WriteCrd(State, argIn); if (ret != CpptrajState::OK) err = 1; diff --git a/src/Exec_RunAnalysis.cpp b/src/Exec_RunAnalysis.cpp index dfb7f596c1..0ee40a7fc9 100644 --- a/src/Exec_RunAnalysis.cpp +++ b/src/Exec_RunAnalysis.cpp @@ -24,7 +24,7 @@ Exec::RetType Exec_RunAnalysis::Execute(CpptrajState& State, ArgList& argIn) { # ifdef MPI // Only master performs analyses currently. if (Parallel::TrajComm().Size() > 1) - mprintf("Warning: Analysis does not currently use multiple MPI threads.\n"); + mprintf("Warning: Analysis does not currently use multiple MPI processes.\n"); if (Parallel::TrajComm().Master()) # endif err = DoRunAnalysis(State, argIn); diff --git a/src/Parallel.cpp b/src/Parallel.cpp index f1df3cce90..d5e77af9e0 100644 --- a/src/Parallel.cpp +++ b/src/Parallel.cpp @@ -58,10 +58,10 @@ void Parallel::dbgprintf(const char* format, ...) { return; } -/** Open a file named Thread.worldrank for this thread */ +/** Open a file named Process.worldrank for this process */ int Parallel::debug_init() { char outfilename[32]; - sprintf(outfilename, "Thread.%03i", world_.Rank()); + sprintf(outfilename, "Process.%03i", world_.Rank()); mpidebugfile_ = fopen(outfilename, "w"); if (mpidebugfile_ == NULL) { fprintf(stderr,"[%i]\tCould not open debug file:\n", world_.Rank()); @@ -74,7 +74,7 @@ int Parallel::debug_init() { return 0; } -/** Close Thread.worldrank file. */ +/** Close Process.worldrank file. */ int Parallel::debug_end() { if (mpidebugfile_ != 0) fclose(mpidebugfile_); @@ -97,7 +97,7 @@ int Parallel::Init(int argc, char** argv) { //char processor_name[MPI_MAX_PROCESSOR_NAME]; //int namelen; //MPI_Get_processor_name(processor_name, &namelen); - //printf("DEBUG: Thread %i of %i on %s\n", world_.Rank(), world_.Size(), processor_name); + //printf("DEBUG: Process %i of %i on %s\n", world_.Rank(), world_.Size(), processor_name); return 0; } @@ -125,13 +125,13 @@ int Parallel::Abort(int errcode) { /** Trajectory and Ensemble communicators are set up orthogonal to one * another. In row-major notation, Trajectory communicators are set up * across rows, and Ensemble communicators are set up down columns. For - * example, if reading in 2 ensemble members with 3 threads per member + * example, if reading in 2 ensemble members with 3 processes per member * (world size 6), the layout would be: * 0 1 2 (member 0) * 3 4 5 (member 1) - * Threads 0 and 3 would read the first third of the trajectories, etc. + * Processes 0 and 3 would read the first third of the trajectories, etc. */ -int Parallel::SetupComms(int ngroups, bool allowFewerThreadsThanGroups) { +int Parallel::SetupComms(int ngroups, bool allowFewerProcessesThanGroups) { if (ngroups < 1) { // If ngroups < 1 assume we want to reset comm info //fprintf(stdout, "DEBUG: Resetting ensemble/traj comm info.\n"); @@ -152,32 +152,32 @@ int Parallel::SetupComms(int ngroups, bool allowFewerThreadsThanGroups) { return 1; } } else if (world_.Size() < ngroups) { - // Fewer threads than groups. Make sure that # threads is a + // Fewer processes than groups. Make sure that # processes is a // multiple of ngroups. This is required for things like AllGather to work // properly. - if (!allowFewerThreadsThanGroups) { - fprintf(stderr,"Error: Fewer threads than groups currently not allowed.\n"); + if (!allowFewerProcessesThanGroups) { + fprintf(stderr,"Error: Fewer processes than groups currently not allowed.\n"); return 1; } trajComm_.Reset(); ensembleComm_.Reset(); if ( (ngroups % world_.Size()) != 0 ) { - fprintf(stderr,"Error: # of replicas (%i) must be a multiple of # threads (%i)\n", + fprintf(stderr,"Error: # of replicas (%i) must be a multiple of # processes (%i)\n", ngroups, world_.Size()); return 1; } ensemble_size_ = ngroups; - n_ens_members_ = world_.DivideAmongThreads( ensemble_beg_, ensemble_end_, ensemble_size_ ); + n_ens_members_ = world_.DivideAmongProcesses( ensemble_beg_, ensemble_end_, ensemble_size_ ); int ID = world_.Rank(); trajComm_ = world_.Split( ID ); // NOTE: This effectively duplicates World ensembleComm_ = world_.Split( 0 ); world_.Barrier(); } else { - // Threads >= groups. Make sure that ngroups is a multiple of total # threads. + // Processes >= groups. Make sure that ngroups is a multiple of total # processes. if ( (world_.Size() % ngroups) != 0 ) { if ( world_.Master() ) - fprintf(stderr,"Error: # of threads (%i) must be a multiple of # replicas (%i)\n", + fprintf(stderr,"Error: # of processes (%i) must be a multiple of # replicas (%i)\n", world_.Size(), ngroups); return 1; } @@ -233,7 +233,7 @@ int Parallel::SetupComms(int ngroups, bool allowFewerThreadsThanGroups) { /** Can be placed inside the code so debugger can be attached. */ void Parallel::Lock() { - fprintf(stdout,"[%i] Thread is locked. Waiting for debugger.\n", world_.Rank()); + fprintf(stdout,"[%i] Process is locked. Waiting for debugger.\n", world_.Rank()); int PleaseWait = 1; while (PleaseWait == 1) PleaseWait *= 1; @@ -300,20 +300,20 @@ void Parallel::Comm::Reset() { } /** Split given number of elements as evenly as possible among ranks. - * \return Number of elements this thread is responsible for. + * \return Number of elements this process is responsible for. */ -int Parallel::Comm::DivideAmongThreads(int& my_start, int& my_stop, int maxElts) const +int Parallel::Comm::DivideAmongProcesses(int& my_start, int& my_stop, int maxElts) const { - int frames_per_thread = maxElts / size_; + int frames_per_process = maxElts / size_; int remainder = maxElts % size_; - int my_frames = frames_per_thread + (int)(rank_ < remainder); - // Figure out where this thread starts and stops + int my_frames = frames_per_process + (int)(rank_ < remainder); + // Figure out where this process starts and stops my_start = 0; for (int rnk = 0; rnk != rank_; rnk++) if (rnk < remainder) - my_start += (frames_per_thread + 1); + my_start += (frames_per_process + 1); else - my_start += (frames_per_thread); + my_start += (frames_per_process); my_stop = my_start + my_frames; return my_frames; } diff --git a/src/Parallel.h b/src/Parallel.h index a1f02147a4..39157673af 100644 --- a/src/Parallel.h +++ b/src/Parallel.h @@ -51,7 +51,7 @@ class Parallel { static int Abort(int); /// Set up ensemble and trajectory communicators for given ensemble size static int SetupComms(int, bool); - /// Set up communicators - do not allow fewer threads than groups. TODO remove + /// Set up communicators - do not allow fewer processes than groups. TODO remove static int SetupComms(int n) { return SetupComms(n, false); } /// For DEBUG: infinite loop, gives time to attach a debugger. static void Lock(); @@ -61,11 +61,11 @@ class Parallel { static bool EnsembleIsSetup() { return ensemble_size_ > -1; } /// \return total ensemble size. static int Ensemble_Size() { return ensemble_size_; } - /// \return First ensemble member this thread is responsible for. + /// \return First ensemble member this process is responsible for. static int Ensemble_Beg() { return ensemble_beg_; } - /// \return Last+1 ensemble member this thread is responsible for. + /// \return Last+1 ensemble member this process is responsible for. static int Ensemble_End() { return ensemble_end_; } - /// \return Total number of ensemble members this thread is responsible for. + /// \return Total number of ensemble members this process is responsible for. static int N_Ens_Members() { return n_ens_members_; } /// \return Rank in ensemble comm. for given member. static int MemberEnsCommRank(int i) { return memberEnsRank_[i];} @@ -82,9 +82,9 @@ class Parallel { static void printMPIerr(int, const char*, int); static int checkMPIerr(int, const char*, int); static int ensemble_size_; ///< Total number of ensemble members. - static int ensemble_beg_; ///< Starting member for this ensemble thread. - static int ensemble_end_; ///< Ending member for this ensemble thread. - static int n_ens_members_; ///< Number of ensemble members thread is responsible for. + static int ensemble_beg_; ///< Starting member for this ensemble process. + static int ensemble_end_; ///< Ending member for this ensemble process. + static int n_ens_members_; ///< Number of ensemble members process is responsible for. static int* memberEnsRank_; ///< Rank in ensemble comm for each member. # ifdef PARALLEL_DEBUG_VERBOSE static void dbgprintf(const char*, ...); @@ -118,7 +118,7 @@ class Parallel::Comm { Comm Split(int) const; void Reset(); /// my_start, my_stop, maxElts - int DivideAmongThreads(int&, int&, int) const; + int DivideAmongProcesses(int&, int&, int) const; /// RecvBuffer, SendBuffer, Count, DataType, Op int ReduceMaster(void*, void*, int, MPI_Datatype, MPI_Op) const; /// Rank, RecvBuffer, SendBuffer, Count, DataType, Op From d3f760bff4f0ad660105a6a07d6595ba0b901004 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 12:14:09 -0400 Subject: [PATCH 10/24] DRR - Cpptraj: Middle version number bump; command line functionality changed (addition of new flags, file autodetection, order of topology/input without flags no longer matters). --- src/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Version.h b/src/Version.h index d950480a41..a3e32a96e9 100644 --- a/src/Version.h +++ b/src/Version.h @@ -18,5 +18,5 @@ * Whenever a number that precedes is incremented, all subsequent * numbers should be reset to 0. */ -#define CPPTRAJ_INTERNAL_VERSION "V4.3.11" +#define CPPTRAJ_INTERNAL_VERSION "V4.4.0" #endif From 4796babac9c6828c527100ac71835880ead451ab Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 12:38:42 -0400 Subject: [PATCH 11/24] DRR - Cpptraj: Make resizing of trajectory arguments a separate function. --- src/Cpptraj.cpp | 50 +++++++++++++++++++++++++++++++++++-------------- src/Cpptraj.h | 1 + 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index 3abcf7f7b7..85574ddab0 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -40,6 +40,7 @@ Cpptraj::~Cpptraj() { Command::Free(); } void Cpptraj::Usage() { mprinterr("\n" "Usage: cpptraj [-p ] [-i ] [-y ] [-x ]\n" + " [-ya ] [-xa ]\n" " [-c ] [-d ] [-w ] [-o ]\n" " [-h | --help] [-V | --version] [--defines] [-debug <#>]\n" " [--interactive] [--log ] [-tl]\n" @@ -48,7 +49,9 @@ void Cpptraj::Usage() { "\t-p : Load as a topology file. May be specified more than once.\n" "\t-i : Read input from . May be specified more than once.\n" "\t-y : Read from trajectory file ; same as input 'trajin '.\n" + "\t-ya : Input trajectory file arguments.\n" "\t-x : Write trajectory file ; same as input 'trajout '.\n" + "\t-xa : Output trajectory file arguments.\n" "\t-c : Read as reference coordinates; same as input 'reference '.\n" "\t-d : Read data in from file ('readdata ').\n" "\t-w : Write data from as file ('writedata ).\n" @@ -293,6 +296,32 @@ static inline int AutoDetect(std::string const& arg) return 0; } +/** Check that number of args are the same as files. If fewer args, + * replicate the last arg until sizes are equal. If more args, remove the + * extra args. If no files, print a warning. + */ +void Cpptraj::ResizeArgs(Sarray const& Files, Sarray& Args, const char* type) +{ + mprintf("DEBUG: %s Args:\n", type); + for (Sarray::const_iterator ta = Args.begin(); ta != Args.end(); ++ta) + mprintf("\t%s\n", ta->c_str()); + if (Files.empty()) + mprintf("Warning: No %s trajectories but %s trajectory arguments were specified.\n", + type, type); + else { + if (Args.size() < Files.size()) { + mprintf("Warning: Fewer %s trajectory arguments than %s trajectories.\n" + "Warning: Using final specified argument for remaining trajectories: '%s'\n", + type, type, Args.back().c_str()); + Args.resize( Files.size(), Args.back() ); + } else if (Args.size() > Files.size()) { + mprintf("Warning: More %s trajectory arguments specified than %s trajectories.\n", + type, type); + Args.resize( Files.size() ); + } + } +} + /** Read command line args. */ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { // First convert argv to one continuous string. @@ -301,7 +330,8 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { commandLine_.append( " " + std::string(argv[i]) ); // Use ArgList to split into arguments. ArgList cmdLineArgs( commandLine_ ); - mprintf("DEBUG: CmdLine: %s\n", cmdLineArgs.ArgLine() ); +// if (State_.Debug() > 0) + mprintf("DEBUG: CmdLine: %s\n", cmdLineArgs.ArgLine() ); // Process command line flags from ArgList bool hasInput = false; bool interactive = false; @@ -310,6 +340,7 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { Sarray trajinFiles; Sarray trajinArgs; Sarray trajoutFiles; + Sarray trajoutArgs; Sarray refFiles; Sarray dataFiles; std::string dataOut; @@ -384,6 +415,9 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { } else if ( NotFinalArg(cmdLineArgs, "-x", iarg) ) { // -x: Trajectory file out trajoutFiles.push_back( cmdLineArgs[++iarg] ); + } else if ( NotFinalArg(cmdLineArgs, "-xa", iarg) ) { + // -xa: Trajectory file out arguments. + AddArgs( trajoutArgs, cmdLineArgs, iarg ); } else if ( NotFinalArg(cmdLineArgs, "-c", iarg) ) { // -c: Reference file AddArgs( refFiles, cmdLineArgs, iarg ); @@ -481,19 +515,7 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { // If there are fewer input trajectory arguments than input trajectories, // duplicate the last input trajectory argument. if (!trajinArgs.empty()) { - mprintf("DEBUG: trajinArgs:\n"); - for (Sarray::const_iterator ta = trajinArgs.begin(); ta != trajinArgs.end(); ++ta) - mprintf("\t%s\n", ta->c_str()); - if (trajinFiles.empty()) - mprintf("Warning: Input trajectory arguments specified but no input trajectories.\n"); - else { - if (trajinArgs.size() < trajinFiles.size()) - trajinArgs.resize( trajinFiles.size(), trajinArgs.back() ); - else if (trajinArgs.size() > trajinFiles.size()) { - mprintf("Warning: More input trajectory arguments specified than input trajectories.\n"); - trajinArgs.resize( trajinFiles.size() ); - } - } + ResizeArgs( trajinFiles, trajinArgs, "input" ); for (unsigned int it = 0; it != trajinFiles.size(); it++) if (State_.AddInputTrajectory( trajinFiles[it] + " " + trajinArgs[it] )) return ERROR; } else { diff --git a/src/Cpptraj.h b/src/Cpptraj.h index 39916eeebb..00e27f3542 100644 --- a/src/Cpptraj.h +++ b/src/Cpptraj.h @@ -19,6 +19,7 @@ class Cpptraj { static void Intro(); static void Finalize(); static inline void AddArgs(Sarray&, ArgList const&, int&); + static inline void ResizeArgs(Sarray const&, Sarray&, const char*); int ProcessMask(Sarray const&, Sarray const&, std::string const&, bool,bool) const; Mode ProcessCmdLineArgs(int, char**); int Interactive(); From f96e7c1f3d66cbd6d7825e6ad0c86f317b62dfe6 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 12:43:44 -0400 Subject: [PATCH 12/24] DRR - Cpptraj: Process '-xa' flags. --- src/Cpptraj.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index 85574ddab0..2a10385b00 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -527,10 +527,16 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { // Add all output trajectories specified on command line. if (!trajoutFiles.empty()) { hasInput = true; // This allows direct traj conversion with no other input - for (Sarray::const_iterator trajoutName = trajoutFiles.begin(); - trajoutName != trajoutFiles.end(); - ++trajoutName) - if (State_.AddOutputTrajectory( *trajoutName )) return ERROR; + if (!trajoutArgs.empty()) { + ResizeArgs( trajoutFiles, trajoutArgs, "output" ); + for (unsigned int it = 0; it != trajoutFiles.size(); it++) + if (State_.AddOutputTrajectory( trajoutFiles[it] + " " + trajoutArgs[it] )) return ERROR; + } else { + for (Sarray::const_iterator trajoutName = trajoutFiles.begin(); + trajoutName != trajoutFiles.end(); + ++trajoutName) + if (State_.AddOutputTrajectory( *trajoutName )) return ERROR; + } } // Process all input files specified on command line. if ( !inputFiles.empty() ) { From 50e23c8ec6b0835d74f9fdd959d51caf5f508f84 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 15:45:18 -0400 Subject: [PATCH 13/24] DRR - Cpptraj: Hide debug info. Print which trajin/trajout arguments are actually being used. --- src/Cpptraj.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index 2a10385b00..53e452e1b9 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -302,9 +302,6 @@ static inline int AutoDetect(std::string const& arg) */ void Cpptraj::ResizeArgs(Sarray const& Files, Sarray& Args, const char* type) { - mprintf("DEBUG: %s Args:\n", type); - for (Sarray::const_iterator ta = Args.begin(); ta != Args.end(); ++ta) - mprintf("\t%s\n", ta->c_str()); if (Files.empty()) mprintf("Warning: No %s trajectories but %s trajectory arguments were specified.\n", type, type); @@ -320,6 +317,10 @@ void Cpptraj::ResizeArgs(Sarray const& Files, Sarray& Args, const char* type) Args.resize( Files.size() ); } } + mprintf("\tArguments for %zu %s trajectories:\n", Files.size(), type); + Sarray::const_iterator tf = Files.begin(); + for (Sarray::const_iterator ta = Args.begin(); ta != Args.end(); ++ta, ++tf) + mprintf("\t %s %s\n", tf->c_str(), ta->c_str()); } /** Read command line args. */ @@ -330,8 +331,7 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { commandLine_.append( " " + std::string(argv[i]) ); // Use ArgList to split into arguments. ArgList cmdLineArgs( commandLine_ ); -// if (State_.Debug() > 0) - mprintf("DEBUG: CmdLine: %s\n", cmdLineArgs.ArgLine() ); + // mprintf("DEBUG: CmdLine: %s\n", cmdLineArgs.ArgLine() ); // Process command line flags from ArgList bool hasInput = false; bool interactive = false; From 010fde2c37cd1bbcf910c4ad00d5231edc62d240 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 15:58:06 -0400 Subject: [PATCH 14/24] DRR - Cpptraj: Test output args from command line --- test/Test_CmdLine/RunTest.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Test_CmdLine/RunTest.sh b/test/Test_CmdLine/RunTest.sh index 5533678709..9b35411384 100755 --- a/test/Test_CmdLine/RunTest.sh +++ b/test/Test_CmdLine/RunTest.sh @@ -16,12 +16,12 @@ cat > cmd.in < Date: Mon, 18 Jun 2018 15:58:24 -0400 Subject: [PATCH 15/24] DRR - Cpptraj: Test printing host name. Hopefully this works on the windows platform as well. --- src/Cpptraj.cpp | 1 + src/StringRoutines.cpp | 14 ++++++++++++++ src/StringRoutines.h | 2 ++ 3 files changed, 17 insertions(+) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index 53e452e1b9..5fc2640623 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -82,6 +82,7 @@ void Cpptraj::Intro() { # endif "\n ___ ___ ___ ___\n | \\/ | \\/ | \\/ | \n _|_/\\_|_/\\_|_/\\_|_\n\n", CPPTRAJ_VERSION_STRING); + mprintf("| Host: %s\n", HostName().c_str()); # ifdef MPI mprintf("| Running on %i processes.\n", Parallel::World().Size()); # endif diff --git a/src/StringRoutines.cpp b/src/StringRoutines.cpp index 413fb56f4b..239804f260 100644 --- a/src/StringRoutines.cpp +++ b/src/StringRoutines.cpp @@ -9,6 +9,7 @@ # include #else # include +# include #endif #ifdef __APPLE__ # include @@ -250,6 +251,19 @@ std::string TimeString() { return oss.str(); } +// ----------------------------------------------------------------------------- +/** HostName() */ +std::string HostName() { +# ifdef _MSC_VER + TCHAR hostname[INFO_BUFFER_SIZE]; + DWORD bufCharCount = INFO_BUFFER_SIZE; + GetComputerName( hostname, &bufCharCount ); +# else + char hostname[HOST_NAME_MAX]; + gethostname(hostname, HOST_NAME_MAX); +# endif + return std::string(hostname); +} // ----------------------------------------------------------------------------- std::string ByteString(unsigned long long sizeInBytes, ByteType bt) { static const char* BytePrefix[] = { " kB", " MB", " GB", " TB", " PB", " EB" }; diff --git a/src/StringRoutines.h b/src/StringRoutines.h index c58e4337f0..63813ae68e 100644 --- a/src/StringRoutines.h +++ b/src/StringRoutines.h @@ -44,6 +44,8 @@ bool validInteger(std::string const&); bool validDouble(std::string const&); /// \return the current date/time with format 'mm/dd/yy hh:mm:ss' std::string TimeString(); +/// \return current host name +std::string HostName(); /// BYTE_BINARY: Sizes are based on 1024^X. BYTE_DECIMAL: Sizes are based on 1000^X. enum ByteType { BYTE_BINARY = 0, BYTE_DECIMAL }; /// \return Given size in bytes as a human-readable string. From 0f3eb1a9e106ccb0b494db5c0b1292d0f4074c50 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Mon, 18 Jun 2018 15:59:57 -0400 Subject: [PATCH 16/24] DRR - Cpptraj: I think I need this include on windows for HostName() to work. --- src/StringRoutines.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/StringRoutines.cpp b/src/StringRoutines.cpp index 239804f260..5d63c7a9b4 100644 --- a/src/StringRoutines.cpp +++ b/src/StringRoutines.cpp @@ -7,6 +7,7 @@ #include "CpptrajStdio.h" #ifdef _MSC_VER # include +# include #else # include # include From c0736158b27400b229897c87397e03d853a31e60 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 19 Jun 2018 08:27:34 -0400 Subject: [PATCH 17/24] DRR - Cpptraj: Decided the last number should be incremented instead of middle - no functionality has actually changed, just enhancements added. --- src/Version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Version.h b/src/Version.h index a3e32a96e9..d85aaf1897 100644 --- a/src/Version.h +++ b/src/Version.h @@ -18,5 +18,5 @@ * Whenever a number that precedes is incremented, all subsequent * numbers should be reset to 0. */ -#define CPPTRAJ_INTERNAL_VERSION "V4.4.0" +#define CPPTRAJ_INTERNAL_VERSION "V4.3.12" #endif From 65dbec10130756ea94b45b8fb17ef7a266b29628 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 19 Jun 2018 08:35:38 -0400 Subject: [PATCH 18/24] DRR - Cpptraj: Fix up help text. --- src/Cpptraj.cpp | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index 5fc2640623..09c952f8f2 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -40,20 +40,20 @@ Cpptraj::~Cpptraj() { Command::Free(); } void Cpptraj::Usage() { mprinterr("\n" "Usage: cpptraj [-p ] [-i ] [-y ] [-x ]\n" - " [-ya ] [-xa ]\n" + " [-ya ] [-xa ] []\n" " [-c ] [-d ] [-w ] [-o ]\n" " [-h | --help] [-V | --version] [--defines] [-debug <#>]\n" " [--interactive] [--log ] [-tl]\n" " [-ms ] [-mr ] [--mask ] [--resmask ]\n" - " cpptraj \n" - "\t-p : Load as a topology file. May be specified more than once.\n" - "\t-i : Read input from . May be specified more than once.\n" - "\t-y : Read from trajectory file ; same as input 'trajin '.\n" - "\t-ya : Input trajectory file arguments.\n" - "\t-x : Write trajectory file ; same as input 'trajout '.\n" - "\t-xa : Output trajectory file arguments.\n" - "\t-c : Read as reference coordinates; same as input 'reference '.\n" - "\t-d : Read data in from file ('readdata ').\n" + "\t-p : * Load as a topology file.\n" + "\t-i : * Read input from file .\n" + "\t-y : * Read from trajectory file ; same as input 'trajin '.\n" + "\t-x : * Write trajectory file ; same as input 'trajout '.\n" + "\t-ya : * Input trajectory file arguments.\n" + "\t-xa : * Output trajectory file arguments.\n" + "\t : * A topology, input trajectory, or file containing cpptraj input.\n" + "\t-c : * Read as reference coordinates; same as input 'reference '.\n" + "\t-d : * Read data in from file ('readdata ').\n" "\t-w : Write data from as file ('writedata ).\n" "\t-o : Write CPPTRAJ STDOUT output to file .\n" "\t-h | --help : Print command line help and exit.\n" @@ -62,11 +62,13 @@ void Cpptraj::Usage() { "\t-debug <#> : Set global debug level to <#>; same as input 'debug <#>'.\n" "\t--interactive : Force interactive mode.\n" "\t--log : Record commands to (interactive mode only). Default is 'cpptraj.log'.\n" - "\t-tl : Print length of trajectories specified with '-y' to STDOUT.\n" + "\t-tl : Print length of all input trajectories specified on the command line to STDOUT.\n" "\t-ms : Print selected atom numbers to STDOUT.\n" "\t-mr : Print selected residue numbers to STDOUT.\n" "\t--mask : Print detailed atom selection to STDOUT.\n" - "\t--resmask : Print detailed residue selection to STDOUT.\n\n"); + "\t--resmask : Print detailed residue selection to STDOUT.\n" + " * Denotes flag may be specified multiple times.\n" + "\n"); } void Cpptraj::Intro() { From 9bf2e8c7325e60c884f8cf93215f83c2c1284587 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 19 Jun 2018 08:55:32 -0400 Subject: [PATCH 19/24] DRR - Cpptraj: Warn if less than 3 atoms selected for RMSD, and skip if debug level is 0. Addresses #600. --- src/Action_Rmsd.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/Action_Rmsd.cpp b/src/Action_Rmsd.cpp index 78ddc2eafb..2341065412 100644 --- a/src/Action_Rmsd.cpp +++ b/src/Action_Rmsd.cpp @@ -320,6 +320,14 @@ Action::RetType Action_Rmsd::Setup(ActionSetup& setup) { mprintf("Warning: No atoms in mask '%s'.\n", tgtMask_.MaskString()); return Action::SKIP; } + if ( tgtMask_.Nselected() < 3 ) { + mprintf("Warning: Less than 3 atoms selected for RMSD. Cannot fully" + "Warning: populate the coordinate covariance matrix.\n"); + if (debug_ == 0) { + mprintf("Warning: Skipping.\n"); + return Action::SKIP; + } + } // Allocate space for selected atoms in the frame. This will also put the // correct masses in based on the mask. tgtFrame_.SetupFrameFromMask(tgtMask_, setup.Top().Atoms()); From 3a1cb40e05739a5980b0012943a80fc22608a6c5 Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 19 Jun 2018 09:50:30 -0400 Subject: [PATCH 20/24] DRR - Cpptraj: Fix tests in parallel at higher process counts (#599). Good up to 32 processes now. --- test/Test_2DRMS/RunTest.sh | 2 +- test/Test_Align/RunTest.sh | 2 +- test/Test_AnalysisRunAvg/RunTest.sh | 2 +- test/Test_Closest/RunTest.sh | 2 +- test/Test_Datafile/RunTest.sh | 4 +++- test/Test_Diffusion/RunTest.sh | 2 +- test/Test_DihCovar/RunTest.sh | 2 +- test/Test_Ensemble_MREMD/RunTest.sh | 16 ++++++++++------ test/Test_Esander/RunTest.sh | 12 ++++++++---- test/Test_FixAtomOrder/RunTest.sh | 4 +++- test/Test_GromacsTrr/RunTest.sh | 3 +++ test/Test_Hbond/RunTest.sh | 4 ++-- test/Test_LIE/RunTest.sh | 2 +- test/Test_Mask/RunTest.sh | 2 +- test/Test_Matrix/RunTest.sh | 5 ++++- test/Test_Molsurf/RunTest.sh | 2 +- test/Test_Multidihedral/RunTest.sh | 3 +++ test/Test_NetcdfTraj/RunTest.sh | 2 +- test/Test_Outtraj/RunTest.sh | 2 +- test/Test_Parallel/RunTest.sh | 2 +- test/Test_Principal/RunTest.sh | 3 +++ test/Test_RMSD/RunTest.sh | 24 ++++++++++++++---------- test/Test_RemdTraj/RunTest.sh | 3 +++ test/Test_Rotate/RunTest.sh | 3 +++ test/Test_Runavg/RunTest.sh | 2 +- test/Test_SPAM/RunTest.sh | 2 +- test/Test_Temperature/RunTest.sh | 2 +- test/Test_TrajinOffset/RunTest.sh | 2 ++ test/Test_Watershell/RunTest.sh | 2 +- test/Test_systemVF/RunTest.sh | 2 +- 30 files changed, 78 insertions(+), 42 deletions(-) diff --git a/test/Test_2DRMS/RunTest.sh b/test/Test_2DRMS/RunTest.sh index 9c4ee0b8be..4011f1f4f2 100755 --- a/test/Test_2DRMS/RunTest.sh +++ b/test/Test_2DRMS/RunTest.sh @@ -6,7 +6,7 @@ CleanFiles rms.in rmsd1.dat rmsd2.dat ref.nc rmsd.mass.dat dme.dat trp.dat nofit.dat TESTNAME='2D RMSD tests' -Requires netcdf +Requires netcdf maxthreads 10 TOP="../tz2.parm7" CRD="../tz2.nc" INPUT="rms.in" diff --git a/test/Test_Align/RunTest.sh b/test/Test_Align/RunTest.sh index 8b1942a894..68ce1636b4 100755 --- a/test/Test_Align/RunTest.sh +++ b/test/Test_Align/RunTest.sh @@ -6,7 +6,7 @@ CleanFiles rms.in rmsd.dat rmsd.mass.dat rmsd.reftraj.dat TESTNAME='Align tests' -Requires netcdf +Requires netcdf maxthreads 10 TOP="../tz2.truncoct.parm7" INPUT="rms.in" diff --git a/test/Test_AnalysisRunAvg/RunTest.sh b/test/Test_AnalysisRunAvg/RunTest.sh index b9607b6037..3452d8dac4 100755 --- a/test/Test_AnalysisRunAvg/RunTest.sh +++ b/test/Test_AnalysisRunAvg/RunTest.sh @@ -4,7 +4,7 @@ CleanFiles runavg.in running_avg.dat cumulative_avg.dat distances.dat TESTNAME='Analysis Running Average' -Requires netcdf +Requires netcdf maxthreads 14 INPUT="runavg.in" TOP="../tz2.parm7" cat > $INPUT < prec.in <_X.xmgr, X = {a,r,x,y,z} diff --git a/test/Test_DihCovar/RunTest.sh b/test/Test_DihCovar/RunTest.sh index c2fe123f38..d4d2d9264e 100755 --- a/test/Test_DihCovar/RunTest.sh +++ b/test/Test_DihCovar/RunTest.sh @@ -6,7 +6,7 @@ CleanFiles matrix.in mtest.dat.save mtest.*.dat dihcovar.dat modes.dihcovar.dat dih.project.dat dih.project.agr dihedrals.dat TESTNAME='Dihedral Covariance Matrix Test' -Requires mathlib +Requires mathlib maxthreads 10 INPUT="-i matrix.in" if [ -z "$DO_PARALLEL" ] ; then diff --git a/test/Test_Ensemble_MREMD/RunTest.sh b/test/Test_Ensemble_MREMD/RunTest.sh index e5813f9c8a..7359858965 100755 --- a/test/Test_Ensemble_MREMD/RunTest.sh +++ b/test/Test_Ensemble_MREMD/RunTest.sh @@ -81,18 +81,22 @@ EOF # Test M-REMD process, no sort, running average (tests preload in parallel) RunAvgTest() { - cat > mremd.in < mremd.in < all.RA.dat && DoTest all.RA.dat.save all.RA.dat + RunCpptraj "$UNITNAME" + if [ -z "$DO_PARALLEL" ] ; then + DoTest RA.dat.save RA.dat + else + cat RA.dat.? > all.RA.dat && DoTest all.RA.dat.save all.RA.dat + fi fi } diff --git a/test/Test_Esander/RunTest.sh b/test/Test_Esander/RunTest.sh index 4c577effa7..18efb1232c 100755 --- a/test/Test_Esander/RunTest.sh +++ b/test/Test_Esander/RunTest.sh @@ -10,7 +10,7 @@ INPUT="-i ene.in" TestPME() { UNITNAME='SANDER energy test, PME' - CheckFor pnetcdf + CheckFor pnetcdf maxthreads 10 if [ $? -eq 0 ] ; then cat > ene.in < ene.in < ene.in < fix.in < hbond.in < hbond.in < matrix.in < molsurf.in < para.in < rms.in < rms.in < rms.in < rms.in < rotate.in < temp.in < cpptraj.offset.in < systemVF.in < Date: Tue, 19 Jun 2018 10:26:36 -0400 Subject: [PATCH 21/24] DRR - Cpptraj: Only warn about assuming file contains cpptraj input if not in the "classic" command line position. --- src/Cpptraj.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index 09c952f8f2..ad33cc5c09 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -292,8 +292,7 @@ static inline int AutoDetect(std::string const& arg) TrajectoryFile::TrajFormatType ttype = TrajectoryFile::DetectFormat( arg ); if (ttype != TrajectoryFile::UNKNOWN_TRAJ) return 2; - // Assume input file - mprintf("Warning: Assuming '%s' contains cpptraj input.\n", arg.c_str()); + // Assume input file. return 3; } return 0; @@ -465,9 +464,10 @@ Cpptraj::Mode Cpptraj::ProcessCmdLineArgs(int argc, char** argv) { topFiles.push_back( arg ); else if (ftype == 2) trajinFiles.push_back( arg ); - else if (ftype == 3) + else if (ftype == 3) { + if (iarg != 1) mprintf("Warning: Assuming '%s' contains cpptraj input.\n", arg.c_str()); inputFiles.push_back( arg ); - else { + } else { mprinterr("Error: Unrecognized input on command line: %i: %s\n", iarg+1, cmdLineArgs[iarg].c_str()); Usage(); From 22d30e6c4ea9412ff82603df3d17ab1fcfd781af Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Tue, 19 Jun 2018 10:51:20 -0400 Subject: [PATCH 22/24] DRR - Cpptraj: Add command line wildcard test --- test/Test_CmdLine/RunTest.sh | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/test/Test_CmdLine/RunTest.sh b/test/Test_CmdLine/RunTest.sh index 9b35411384..75df09f947 100755 --- a/test/Test_CmdLine/RunTest.sh +++ b/test/Test_CmdLine/RunTest.sh @@ -3,13 +3,12 @@ . ../MasterTest.sh # Clean -CleanFiles cmd.in test1.crd.save test1.crd +CleanFiles cmd.in test1.crd.save test1.crd res res.save TESTNAME='Command line tests' # Required environment Requires maxthreads 8 -INPUT='-i cmd.in' # First test without command line cat > cmd.in < cmd.in < cmd.in < Date: Tue, 19 Jun 2018 11:42:25 -0400 Subject: [PATCH 23/24] DRR - Cpptraj: Update test name. --- test/Test_CmdLine/RunTest.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/Test_CmdLine/RunTest.sh b/test/Test_CmdLine/RunTest.sh index 75df09f947..84ae786588 100755 --- a/test/Test_CmdLine/RunTest.sh +++ b/test/Test_CmdLine/RunTest.sh @@ -18,11 +18,11 @@ trajin ../tz2.crd 98 last trajout test1.crd.save title MyTitle EOF INPUT='-i cmd.in' -RunCpptraj "Command line test, part 1" +RunCpptraj "Command line trajectory args test, part 1" # Now test using the command line. Hijack the INPUT variable. INPUT="-p ../tz2.parm7 -y ../tz2.crd -ya \"2 13 3\" -y ../tz2.crd -ya \"98 last\" -x test1.crd -xa \"title MyTitle\"" -RunCpptraj "Command line test, part 2" +RunCpptraj "Command line test trajectory args test, part 2" DoTest test1.crd.save test1.crd # Test loading multiple topology files From c088e4e1a51ba7fd1f35d8dd60d31856cf46f7dc Mon Sep 17 00:00:00 2001 From: "Daniel R. Roe" Date: Wed, 20 Jun 2018 08:23:54 -0400 Subject: [PATCH 24/24] DRR - Cpptraj: Remove hostname printout for now. I don't have the time or patience right now to debug it cross-platform. --- src/Cpptraj.cpp | 1 - src/StringRoutines.cpp | 15 --------------- src/StringRoutines.h | 2 -- 3 files changed, 18 deletions(-) diff --git a/src/Cpptraj.cpp b/src/Cpptraj.cpp index ad33cc5c09..7798aab60a 100644 --- a/src/Cpptraj.cpp +++ b/src/Cpptraj.cpp @@ -84,7 +84,6 @@ void Cpptraj::Intro() { # endif "\n ___ ___ ___ ___\n | \\/ | \\/ | \\/ | \n _|_/\\_|_/\\_|_/\\_|_\n\n", CPPTRAJ_VERSION_STRING); - mprintf("| Host: %s\n", HostName().c_str()); # ifdef MPI mprintf("| Running on %i processes.\n", Parallel::World().Size()); # endif diff --git a/src/StringRoutines.cpp b/src/StringRoutines.cpp index 5d63c7a9b4..413fb56f4b 100644 --- a/src/StringRoutines.cpp +++ b/src/StringRoutines.cpp @@ -7,10 +7,8 @@ #include "CpptrajStdio.h" #ifdef _MSC_VER # include -# include #else # include -# include #endif #ifdef __APPLE__ # include @@ -252,19 +250,6 @@ std::string TimeString() { return oss.str(); } -// ----------------------------------------------------------------------------- -/** HostName() */ -std::string HostName() { -# ifdef _MSC_VER - TCHAR hostname[INFO_BUFFER_SIZE]; - DWORD bufCharCount = INFO_BUFFER_SIZE; - GetComputerName( hostname, &bufCharCount ); -# else - char hostname[HOST_NAME_MAX]; - gethostname(hostname, HOST_NAME_MAX); -# endif - return std::string(hostname); -} // ----------------------------------------------------------------------------- std::string ByteString(unsigned long long sizeInBytes, ByteType bt) { static const char* BytePrefix[] = { " kB", " MB", " GB", " TB", " PB", " EB" }; diff --git a/src/StringRoutines.h b/src/StringRoutines.h index 63813ae68e..c58e4337f0 100644 --- a/src/StringRoutines.h +++ b/src/StringRoutines.h @@ -44,8 +44,6 @@ bool validInteger(std::string const&); bool validDouble(std::string const&); /// \return the current date/time with format 'mm/dd/yy hh:mm:ss' std::string TimeString(); -/// \return current host name -std::string HostName(); /// BYTE_BINARY: Sizes are based on 1024^X. BYTE_DECIMAL: Sizes are based on 1000^X. enum ByteType { BYTE_BINARY = 0, BYTE_DECIMAL }; /// \return Given size in bytes as a human-readable string.