ENH: support command-line specification of MPI threads (#2791)
- MPI_THREAD_MULTIPLE is usually undesirable for performance reasons, but in some cases may be necessary if a linked library expects it. Provide a '-mpi-threads' option to explicitly request it. ENH: consolidate some looping logic within argList
This commit is contained in:
parent
b2217d5e6b
commit
4412566c58
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -124,6 +124,9 @@ int main(int argc, char *argv[])
|
||||
argList::addDryRunOption("Just for testing");
|
||||
argList::addVerboseOption("Increase verbosity");
|
||||
|
||||
// Check -verbose before initialisation
|
||||
UPstream::debug = argList::verbose(argc, argv);
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
Pout<< "command-line ("
|
||||
|
@ -42,6 +42,7 @@ Description
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
void printInfo(const label comm)
|
||||
{
|
||||
@ -65,20 +66,10 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noBanner();
|
||||
argList::noCheckProcessorDirectories();
|
||||
argList::addBoolOption("verbose", "Set debug level");
|
||||
|
||||
// Capture manually. We need values before proper startup
|
||||
int nVerbose = 0;
|
||||
for (int argi = 1; argi < argc; ++argi)
|
||||
{
|
||||
if (strcmp(argv[argi], "-verbose") == 0)
|
||||
{
|
||||
++nVerbose;
|
||||
}
|
||||
}
|
||||
|
||||
UPstream::debug = nVerbose;
|
||||
argList::addVerboseOption("Set UPstream::debug level");
|
||||
|
||||
// Check -verbose before initialisation
|
||||
UPstream::debug = argList::verbose(argc, argv);
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
|
@ -44,6 +44,8 @@ Description
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
void rankInfo(const label comm)
|
||||
{
|
||||
const int ranki = UPstream::myProcNo(comm);
|
||||
@ -63,7 +65,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noBanner();
|
||||
argList::noCheckProcessorDirectories();
|
||||
argList::addBoolOption("verbose", "Set debug level");
|
||||
argList::addVerboseOption("Set UPstream::debug level");
|
||||
argList::addBoolOption("info", "information");
|
||||
argList::addBoolOption("print-tree", "Report tree(s) as graph");
|
||||
argList::addBoolOption("comm-split", "Test simple comm split");
|
||||
@ -71,17 +73,8 @@ int main(int argc, char *argv[])
|
||||
argList::addBoolOption("host-comm", "Test Pstream host-comm");
|
||||
argList::addBoolOption("host-broadcast", "Test host-base broadcasts");
|
||||
|
||||
// Capture manually. We need values before proper startup
|
||||
int nVerbose = 0;
|
||||
for (int argi = 1; argi < argc; ++argi)
|
||||
{
|
||||
if (strcmp(argv[argi], "-verbose") == 0)
|
||||
{
|
||||
++nVerbose;
|
||||
}
|
||||
}
|
||||
|
||||
UPstream::debug = nVerbose;
|
||||
// Check -verbose before initialisation
|
||||
UPstream::debug = argList::verbose(argc, argv);
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
|
@ -44,6 +44,7 @@ Description
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
bool startMPI()
|
||||
{
|
||||
@ -121,19 +122,10 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noBanner();
|
||||
argList::noCheckProcessorDirectories();
|
||||
argList::addBoolOption("verbose", "Set debug level");
|
||||
argList::addVerboseOption("Set UPstream::debug level");
|
||||
|
||||
// Need to capture manually, since we need values before proper startup
|
||||
int nVerbose = 0;
|
||||
for (int argi = 1; argi < argc; ++argi)
|
||||
{
|
||||
if (strcmp(argv[argi], "-verbose") == 0)
|
||||
{
|
||||
++nVerbose;
|
||||
}
|
||||
}
|
||||
|
||||
UPstream::debug = nVerbose;
|
||||
// Check -verbose before initialisation
|
||||
UPstream::debug = argList::verbose(argc, argv);
|
||||
|
||||
startMPI();
|
||||
|
||||
|
@ -43,24 +43,15 @@ using namespace Foam;
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noFunctionObjects();
|
||||
argList::addBoolOption("verbose", "Set debug level");
|
||||
argList::addVerboseOption("Set UPstream::debug level");
|
||||
argList::addBoolOption("comm-graph", "Test simple graph communicator");
|
||||
argList::addNote
|
||||
(
|
||||
"Create graph of OpenFOAM mesh connections"
|
||||
);
|
||||
|
||||
// Capture manually. We need values before proper startup
|
||||
int nVerbose = 0;
|
||||
for (int argi = 1; argi < argc; ++argi)
|
||||
{
|
||||
if (strcmp(argv[argi], "-verbose") == 0)
|
||||
{
|
||||
++nVerbose;
|
||||
}
|
||||
}
|
||||
|
||||
UPstream::debug = nVerbose;
|
||||
// Check -verbose before initialisation
|
||||
UPstream::debug = argList::verbose(argc, argv);
|
||||
|
||||
#include "setRootCase.H"
|
||||
|
||||
|
@ -264,7 +264,7 @@ int main(int argc, char *argv[])
|
||||
// enable noConstant by switching
|
||||
if (!args.found("noConstant"))
|
||||
{
|
||||
args.setOption("constant", "");
|
||||
args.setOption("constant");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -402,7 +402,6 @@ int main(int argc, char *argv[])
|
||||
|
||||
timeSelector::addOptions();
|
||||
|
||||
argList::addOptionCompat("dry-run", {"test", 1806});
|
||||
argList::addDryRunOption
|
||||
(
|
||||
"Test only do not change any files"
|
||||
@ -425,7 +424,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
instantList timeDirs = timeSelector::select0(runTime, args);
|
||||
|
||||
const bool dryrun = args.found("dry-run");
|
||||
const bool dryrun = args.dryRun();
|
||||
if (dryrun)
|
||||
{
|
||||
Info<< "-dry-run option: no changes made" << nl << endl;
|
||||
|
@ -166,10 +166,13 @@ void Foam::Time::readDict()
|
||||
}
|
||||
controlDict_.watchIndices().clear();
|
||||
|
||||
// The new handler, create with some verbosity
|
||||
// Reporting verbosity corresponding to detail level
|
||||
const bool verbose = (::Foam::infoDetailLevel > 0);
|
||||
|
||||
// The new handler
|
||||
refPtr<fileOperation> newHandler
|
||||
(
|
||||
fileOperation::New(fileHandlerName, true)
|
||||
fileOperation::New(fileHandlerName, verbose)
|
||||
);
|
||||
|
||||
// Install the new handler
|
||||
@ -206,6 +209,9 @@ void Foam::Time::readDict()
|
||||
|
||||
IStringStream dummyIs("");
|
||||
|
||||
// Reporting verbosity corresponding to detail level
|
||||
const bool verbose = (::Foam::infoDetailLevel > 0);
|
||||
|
||||
forAllConstIters(objs, iter)
|
||||
{
|
||||
const List<simpleRegIOobject*>& objects = *iter;
|
||||
@ -214,7 +220,7 @@ void Foam::Time::readDict()
|
||||
{
|
||||
obj->readData(dummyIs);
|
||||
|
||||
if (Foam::infoDetailLevel > 0)
|
||||
if (verbose)
|
||||
{
|
||||
Info<< " ";
|
||||
obj->writeData(Info);
|
||||
|
@ -54,6 +54,7 @@ License
|
||||
|
||||
bool Foam::argList::argsMandatory_ = true;
|
||||
bool Foam::argList::checkProcessorDirectories_ = true;
|
||||
bool Foam::argList::parallelThreads_ = false;
|
||||
|
||||
Foam::SLList<Foam::string> Foam::argList::validArgs;
|
||||
Foam::HashSet<Foam::string> Foam::argList::advancedOptions;
|
||||
@ -122,6 +123,14 @@ Foam::argList::initValidTables::initValidTables()
|
||||
|
||||
argList::addBoolOption("parallel", "Run in parallel");
|
||||
validParOptions.set("parallel", "");
|
||||
|
||||
argList::addBoolOption
|
||||
(
|
||||
"mpi-threads",
|
||||
"Request use of MPI threads",
|
||||
true // advanced option
|
||||
);
|
||||
|
||||
argList::addOption
|
||||
(
|
||||
"roots",
|
||||
@ -401,7 +410,7 @@ void Foam::argList::addOption
|
||||
|
||||
void Foam::argList::setAdvanced(const word& optName, bool advanced)
|
||||
{
|
||||
if (advanced && validOptions.found(optName))
|
||||
if (advanced && validOptions.contains(optName))
|
||||
{
|
||||
advancedOptions.set(optName);
|
||||
}
|
||||
@ -504,7 +513,13 @@ void Foam::argList::addDryRunOption
|
||||
bool advanced
|
||||
)
|
||||
{
|
||||
argList::addBoolOption("dry-run", usage, advanced);
|
||||
const word optName("dry-run", false);
|
||||
|
||||
argList::addBoolOption(optName, usage, advanced);
|
||||
if (!advanced)
|
||||
{
|
||||
advancedOptions.erase(optName); // Avoid 'stickiness'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -514,13 +529,24 @@ void Foam::argList::addVerboseOption
|
||||
bool advanced
|
||||
)
|
||||
{
|
||||
const word optName("verbose", false);
|
||||
|
||||
if (usage.empty())
|
||||
{
|
||||
argList::addBoolOption("verbose", "Additional verbosity", advanced);
|
||||
argList::addBoolOption
|
||||
(
|
||||
optName,
|
||||
"Additional verbosity (can be used multiple times)",
|
||||
advanced
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
argList::addBoolOption("verbose", usage, advanced);
|
||||
argList::addBoolOption(optName, usage, advanced);
|
||||
}
|
||||
if (!advanced)
|
||||
{
|
||||
advancedOptions.erase(optName); // Avoid 'stickiness'
|
||||
}
|
||||
}
|
||||
|
||||
@ -569,10 +595,17 @@ void Foam::argList::noParallel()
|
||||
removeOption("decomposeParDict");
|
||||
removeOption("hostRoots");
|
||||
removeOption("world");
|
||||
removeOption("mpi-threads");
|
||||
validParOptions.clear();
|
||||
}
|
||||
|
||||
|
||||
void Foam::argList::parallelThreads_on()
|
||||
{
|
||||
parallelThreads_ = true;
|
||||
}
|
||||
|
||||
|
||||
void Foam::argList::noCheckProcessorDirectories()
|
||||
{
|
||||
checkProcessorDirectories_ = false;
|
||||
@ -581,18 +614,39 @@ void Foam::argList::noCheckProcessorDirectories()
|
||||
|
||||
bool Foam::argList::postProcess(int argc, char *argv[])
|
||||
{
|
||||
for (int i=1; i<argc; ++i)
|
||||
for (int argi = 1; argi < argc; ++argi)
|
||||
{
|
||||
if (argv[i] == '-' + postProcessOptionName)
|
||||
const char *optName = argv[argi];
|
||||
|
||||
if (optName[0] == '-')
|
||||
{
|
||||
++optName; // Looks like an option, skip leading '-'
|
||||
|
||||
if (optName == postProcessOptionName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
int Foam::argList::verbose(int argc, char *argv[])
|
||||
{
|
||||
int num = 0;
|
||||
for (int argi = 1; argi < argc; ++argi)
|
||||
{
|
||||
if (strcmp(argv[argi], "-verbose") == 0)
|
||||
{
|
||||
++num;
|
||||
}
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
Foam::word Foam::argList::envExecutable()
|
||||
@ -694,6 +748,8 @@ int Foam::argList::optionIgnore(const word& optName)
|
||||
}
|
||||
}
|
||||
|
||||
// TBD: could ignore -verbose, -dry-run etc if they are not active...
|
||||
|
||||
return 0; // Do not skip
|
||||
}
|
||||
|
||||
@ -711,15 +767,19 @@ bool Foam::argList::regroupArgv(int& argc, char**& argv)
|
||||
args_[0] = fileName(argv[0]);
|
||||
for (int argi = 1; argi < argc; ++argi)
|
||||
{
|
||||
if (strcmp(argv[argi], "(") == 0)
|
||||
const char *optName = argv[argi];
|
||||
|
||||
if (optName[0] == '(' && optName[1] == '\0')
|
||||
{
|
||||
// Begin list
|
||||
++depth;
|
||||
group += '(';
|
||||
}
|
||||
else if (strcmp(argv[argi], ")") == 0)
|
||||
else if (optName[0] == ')' && optName[1] == '\0')
|
||||
{
|
||||
if (depth)
|
||||
{
|
||||
// End list
|
||||
--depth;
|
||||
group += ')';
|
||||
if (!depth)
|
||||
@ -730,6 +790,7 @@ bool Foam::argList::regroupArgv(int& argc, char**& argv)
|
||||
}
|
||||
else
|
||||
{
|
||||
// A stray ')' - likely never happens
|
||||
args_[nArgs++] = argv[argi];
|
||||
}
|
||||
}
|
||||
@ -740,12 +801,11 @@ bool Foam::argList::regroupArgv(int& argc, char**& argv)
|
||||
group += argv[argi];
|
||||
group += '"';
|
||||
}
|
||||
else if (argv[argi][0] == '-')
|
||||
else if (optName[0] == '-')
|
||||
{
|
||||
// Appears to be an option
|
||||
const char *optName = &argv[argi][1];
|
||||
++optName; // Looks like an option, skip leading '-'
|
||||
|
||||
if (validOptions.found(optName))
|
||||
if (validOptions.contains(optName))
|
||||
{
|
||||
// Known option name
|
||||
args_[nArgs++] = argv[argi];
|
||||
@ -848,59 +908,117 @@ Foam::argList::argList
|
||||
bool initialise
|
||||
)
|
||||
:
|
||||
runControl_(),
|
||||
args_(argc),
|
||||
options_(argc),
|
||||
libs_()
|
||||
{
|
||||
// Check for -fileHandler, which requires an argument.
|
||||
word handlerType;
|
||||
for (int argi = argc-2; argi > 0; --argi)
|
||||
{
|
||||
if (argv[argi][0] == '-')
|
||||
{
|
||||
const char *optName = &argv[argi][1];
|
||||
// Pre-scan for some options needed for initial setup:
|
||||
// -fileHandler (takes an argument)
|
||||
// -mpi-threads (bool option)
|
||||
//
|
||||
// Also handle -dry-run and -verbose counting
|
||||
// (it is left to the application to decide what to do with them).
|
||||
// Detect any parallel run options
|
||||
|
||||
if (strcmp(optName, "fileHandler") == 0)
|
||||
word fileHandlerName;
|
||||
|
||||
if (parallelThreads_)
|
||||
{
|
||||
handlerType = argv[argi+1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (handlerType.empty())
|
||||
{
|
||||
handlerType = Foam::getEnv("FOAM_FILEHANDLER");
|
||||
if (handlerType.empty())
|
||||
{
|
||||
handlerType = fileOperation::defaultFileHandler;
|
||||
}
|
||||
// Default -mpi-threads configured statically from application
|
||||
runControl_.threads(true);
|
||||
}
|
||||
|
||||
// Detect any parallel options
|
||||
const bool needsThread = fileOperations::fileOperationInitialise::New
|
||||
(
|
||||
handlerType,
|
||||
argc,
|
||||
argv
|
||||
)().needsThreading();
|
||||
|
||||
|
||||
// Check if this run is a parallel run by searching for any parallel option
|
||||
// If found call runPar which might filter argv
|
||||
for (int argi = 1; argi < argc; ++argi)
|
||||
{
|
||||
if (argv[argi][0] == '-')
|
||||
{
|
||||
const char *optName = &argv[argi][1];
|
||||
const char *optName = argv[argi];
|
||||
|
||||
if (validParOptions.found(optName))
|
||||
if (optName[0] == '-')
|
||||
{
|
||||
runControl_.runPar(argc, argv, needsThread);
|
||||
break;
|
||||
++optName; // Looks like an option, skip leading '-'
|
||||
bool emitErrorMessage = false;
|
||||
|
||||
if (strcmp(optName, "dry-run") == 0)
|
||||
{
|
||||
runControl_.incrDryRun();
|
||||
}
|
||||
else if (strcmp(optName, "verbose") == 0)
|
||||
{
|
||||
runControl_.incrVerbose();
|
||||
}
|
||||
else if (strcmp(optName, "mpi-threads") == 0)
|
||||
{
|
||||
runControl_.threads(true);
|
||||
}
|
||||
else if (strcmp(optName, "fileHandler") == 0)
|
||||
{
|
||||
// Requires a parameter
|
||||
if (argi < argc-1)
|
||||
{
|
||||
++argi;
|
||||
fileHandlerName = argv[argi];
|
||||
}
|
||||
else
|
||||
{
|
||||
emitErrorMessage = true;
|
||||
}
|
||||
}
|
||||
else if (validParOptions.contains(optName))
|
||||
{
|
||||
// Contains a parallel run option
|
||||
runControl_.parRun(true);
|
||||
}
|
||||
|
||||
if (emitErrorMessage)
|
||||
{
|
||||
// Missing argument: emit message but not exit or
|
||||
// FatalError since Pstream etc are not yet initialised
|
||||
|
||||
Info<< nl
|
||||
<< "Error: option '-" << optName
|
||||
<< "' requires an argument" << nl << nl;
|
||||
|
||||
//NO: UPstream::exit(1); // works for serial and parallel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// No -fileHandler specifed, get from environment or use default
|
||||
if (fileHandlerName.empty())
|
||||
{
|
||||
fileHandlerName = Foam::getEnv("FOAM_FILEHANDLER");
|
||||
if (fileHandlerName.empty())
|
||||
{
|
||||
fileHandlerName = fileOperation::defaultFileHandler;
|
||||
}
|
||||
}
|
||||
|
||||
// Parse out any additional fileHandler-specific options
|
||||
// (may alter argv list). Recover its threading requirements
|
||||
{
|
||||
auto fileOperationInit = fileOperations::fileOperationInitialise::New
|
||||
(
|
||||
fileHandlerName,
|
||||
argc,
|
||||
argv
|
||||
);
|
||||
|
||||
if (fileOperationInit && fileOperationInit->needsThreading())
|
||||
{
|
||||
runControl_.threads(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Parallel job options detected?
|
||||
// - start parallel run (possibly filters argv as a side-effect)
|
||||
if (runControl_.parRun())
|
||||
{
|
||||
runControl_.runPar(argc, argv);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
// Convert argv -> args_ and capture ( ... ) lists
|
||||
regroupArgv(argc, argv);
|
||||
commandLine_ += args_[0];
|
||||
@ -908,9 +1026,6 @@ Foam::argList::argList
|
||||
// Set executable name immediately - useful when emitting errors.
|
||||
executable_ = fileName(args_[0]).name();
|
||||
|
||||
// Count -dry-run and -verbose switches
|
||||
int numDryRun = 0, numVerbose = 0;
|
||||
|
||||
// Check arguments and options, argv[0] was already handled
|
||||
int nArgs = 1;
|
||||
for (int argi = 1; argi < args_.size(); ++argi)
|
||||
@ -918,9 +1033,11 @@ Foam::argList::argList
|
||||
commandLine_ += ' ';
|
||||
commandLine_ += args_[argi];
|
||||
|
||||
if (args_[argi][0] == '-')
|
||||
const char *optName = args_[argi].data();
|
||||
|
||||
if (optName[0] == '-')
|
||||
{
|
||||
const char *optName = &args_[argi][1];
|
||||
++optName; // Looks like an option, skip leading '-'
|
||||
|
||||
if (!*optName)
|
||||
{
|
||||
@ -949,7 +1066,7 @@ Foam::argList::argList
|
||||
|
||||
if (wantArg)
|
||||
{
|
||||
// Known option and expects a parameter
|
||||
// Option expects a parameter
|
||||
// - get it or emit a FatalError.
|
||||
|
||||
++argi;
|
||||
@ -1019,18 +1136,11 @@ Foam::argList::argList
|
||||
|
||||
options_.insert(optName, "");
|
||||
|
||||
// Special increment handling for some known flags
|
||||
if (wantArg.good())
|
||||
{
|
||||
if (strcmp(optName, "dry-run") == 0)
|
||||
{
|
||||
++numDryRun;
|
||||
}
|
||||
else if (strcmp(optName, "verbose") == 0)
|
||||
{
|
||||
++numVerbose;
|
||||
}
|
||||
}
|
||||
// // Special increment handling for some known flags
|
||||
// if (wantArg.good())
|
||||
// {
|
||||
// ...
|
||||
// }
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1043,10 +1153,6 @@ Foam::argList::argList
|
||||
}
|
||||
}
|
||||
|
||||
// Commit number of -dry-run and -verbose flag occurrences
|
||||
runControl_.dryRun(numDryRun);
|
||||
runControl_.verbose(numVerbose);
|
||||
|
||||
args_.resize(nArgs);
|
||||
|
||||
parse(checkArgs, checkOpts, initialise);
|
||||
@ -1093,42 +1199,42 @@ void Foam::argList::parse
|
||||
bool quickExit = false;
|
||||
|
||||
// Display either application or source documentation, not both
|
||||
if (options_.found("doc"))
|
||||
if (options_.contains("doc"))
|
||||
{
|
||||
displayDoc(false);
|
||||
quickExit = true;
|
||||
}
|
||||
else if (options_.found("doc-source"))
|
||||
else if (options_.contains("doc-source"))
|
||||
{
|
||||
displayDoc(true);
|
||||
quickExit = true;
|
||||
}
|
||||
|
||||
// Display either short or full help, not both
|
||||
if (options_.found("help-full"))
|
||||
if (options_.contains("help-full"))
|
||||
{
|
||||
printUsage(true);
|
||||
quickExit = true;
|
||||
}
|
||||
else if (options_.found("help-notes"))
|
||||
else if (options_.contains("help-notes"))
|
||||
{
|
||||
printNotes();
|
||||
Info<< nl;
|
||||
quickExit = true;
|
||||
}
|
||||
else if (options_.found("help"))
|
||||
else if (options_.contains("help"))
|
||||
{
|
||||
printUsage(false);
|
||||
quickExit = true;
|
||||
}
|
||||
else if (options_.found("help-man"))
|
||||
else if (options_.contains("help-man"))
|
||||
{
|
||||
printMan();
|
||||
quickExit = true;
|
||||
}
|
||||
|
||||
// Allow independent display of compatibility information
|
||||
if (options_.found("help-compat"))
|
||||
if (options_.contains("help-compat"))
|
||||
{
|
||||
printCompat();
|
||||
quickExit = true;
|
||||
@ -1221,19 +1327,19 @@ void Foam::argList::parse
|
||||
// 5. '-fileHandler' commmand-line option
|
||||
|
||||
{
|
||||
word handlerType
|
||||
word fileHandlerName
|
||||
(
|
||||
options_.lookup("fileHandler", Foam::getEnv("FOAM_FILEHANDLER"))
|
||||
);
|
||||
|
||||
if (handlerType.empty())
|
||||
if (fileHandlerName.empty())
|
||||
{
|
||||
handlerType = fileOperation::defaultFileHandler;
|
||||
fileHandlerName = fileOperation::defaultFileHandler;
|
||||
}
|
||||
|
||||
(void) fileOperation::fileHandler
|
||||
(
|
||||
fileOperation::New(handlerType, bannerEnabled())
|
||||
fileOperation::New(fileHandlerName, bannerEnabled())
|
||||
);
|
||||
}
|
||||
|
||||
@ -1346,7 +1452,7 @@ void Foam::argList::parse
|
||||
dictNProcs = roots.size()+1;
|
||||
}
|
||||
}
|
||||
else if (options_.found("hostRoots"))
|
||||
else if (options_.contains("hostRoots"))
|
||||
{
|
||||
source = "-hostRoots";
|
||||
runControl_.distributed(true);
|
||||
@ -1546,7 +1652,7 @@ void Foam::argList::parse
|
||||
}
|
||||
|
||||
// Distribute the master's argument list (with new root)
|
||||
const bool hadCaseOpt = options_.found("case");
|
||||
const bool hadCaseOpt = options_.contains("case");
|
||||
for (const int subproci : Pstream::subProcs())
|
||||
{
|
||||
options_.set("case", roots[subproci-1]/globalCase_);
|
||||
@ -1841,15 +1947,15 @@ Foam::argList::~argList()
|
||||
|
||||
bool Foam::argList::allowFunctionObjects() const
|
||||
{
|
||||
if (validOptions.found("withFunctionObjects"))
|
||||
if (validOptions.contains("withFunctionObjects"))
|
||||
{
|
||||
// '-withFunctionObjects' is available and explicitly enabled
|
||||
return options_.found("withFunctionObjects");
|
||||
return options_.contains("withFunctionObjects");
|
||||
}
|
||||
else if (validOptions.found("noFunctionObjects"))
|
||||
else if (validOptions.contains("noFunctionObjects"))
|
||||
{
|
||||
// '-noFunctionObjects' is available and not explicitly disabled
|
||||
return !options_.found("noFunctionObjects");
|
||||
return !options_.contains("noFunctionObjects");
|
||||
}
|
||||
|
||||
// Disallow functions if there is no way to enable/disable them
|
||||
@ -1859,7 +1965,7 @@ bool Foam::argList::allowFunctionObjects() const
|
||||
|
||||
bool Foam::argList::allowLibs() const
|
||||
{
|
||||
return !options_.found("no-libs");
|
||||
return !options_.contains("no-libs");
|
||||
}
|
||||
|
||||
|
||||
@ -1867,32 +1973,29 @@ bool Foam::argList::allowLibs() const
|
||||
|
||||
Foam::label Foam::argList::count(const UList<word>& optionNames) const
|
||||
{
|
||||
label n = 0;
|
||||
label num = 0;
|
||||
for (const word& optName : optionNames)
|
||||
{
|
||||
if (options_.found(optName))
|
||||
if (options_.contains(optName))
|
||||
{
|
||||
++n;
|
||||
++num;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::argList::count
|
||||
(
|
||||
std::initializer_list<word> optionNames
|
||||
) const
|
||||
Foam::label Foam::argList::count(std::initializer_list<word> optionNames) const
|
||||
{
|
||||
label n = 0;
|
||||
label num = 0;
|
||||
for (const word& optName : optionNames)
|
||||
{
|
||||
if (options_.found(optName))
|
||||
if (options_.contains(optName))
|
||||
{
|
||||
++n;
|
||||
++num;
|
||||
}
|
||||
}
|
||||
return n;
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
@ -1912,7 +2015,9 @@ bool Foam::argList::setOption(const word& optName, const string& param)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (options_.found(optName) ? (options_[optName] != param) : true)
|
||||
const auto optIter = options_.cfind(optName);
|
||||
|
||||
if (!optIter.good() || (optIter.val() != param))
|
||||
{
|
||||
options_.set(optName, param);
|
||||
return true;
|
||||
@ -1930,7 +2035,6 @@ bool Foam::argList::unsetOption(const word& optName)
|
||||
optName == "case"
|
||||
|| optName == "parallel"
|
||||
|| optName == "roots"
|
||||
|| optName == "hostRoots"
|
||||
)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
@ -2040,8 +2144,8 @@ bool Foam::argList::check(bool checkArgs, bool checkOpts) const
|
||||
const word& optName = iter.key();
|
||||
if
|
||||
(
|
||||
!validOptions.found(optName)
|
||||
&& !validParOptions.found(optName)
|
||||
!validOptions.contains(optName)
|
||||
&& !validParOptions.contains(optName)
|
||||
)
|
||||
{
|
||||
FatalError
|
||||
|
@ -124,12 +124,15 @@ class argList
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- Track if command arguments are mandatory/optional
|
||||
//- Command arguments are mandatory (default) or optional
|
||||
static bool argsMandatory_;
|
||||
|
||||
//- Track enabled/disabled checking of processor directories state
|
||||
//- Check presence of processor directories (default: on)
|
||||
static bool checkProcessorDirectories_;
|
||||
|
||||
//- MPI threads are desired for the application (default: off)
|
||||
static bool parallelThreads_;
|
||||
|
||||
//- Switch on/off parallel mode, dry-run etc.
|
||||
// Construct first so destructor is done last.
|
||||
ParRunControl runControl_;
|
||||
@ -645,11 +648,11 @@ public:
|
||||
//- Remove the parallel options
|
||||
static void noParallel();
|
||||
|
||||
//- Remove checking of processor directories
|
||||
//- Disable checking of processor directories
|
||||
static void noCheckProcessorDirectories();
|
||||
|
||||
//- Return true if the post-processing option is specified
|
||||
static bool postProcess(int argc, char *argv[]);
|
||||
//- MPI threads are desired for the application
|
||||
static void parallelThreads_on();
|
||||
|
||||
//- Set option directly (use with caution)
|
||||
// An option with an empty param is a bool option.
|
||||
@ -664,6 +667,15 @@ public:
|
||||
bool unsetOption(const word& optName);
|
||||
|
||||
|
||||
// Helpers
|
||||
|
||||
//- True if the post-processing option is found in the \c argv list
|
||||
static bool postProcess(int argc, char *argv[]);
|
||||
|
||||
//- The number of times -verbose is found in the \c argv list
|
||||
static int verbose(int argc, char *argv[]);
|
||||
|
||||
|
||||
// Print
|
||||
|
||||
//- Print option compatibility
|
||||
|
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2018-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -102,7 +102,7 @@ static void printManOption(const word& optName)
|
||||
argList::optionUsage.lookup(optName, string::null)
|
||||
);
|
||||
|
||||
if (argList::validParOptions.found(optName))
|
||||
if (argList::validParOptions.contains(optName))
|
||||
{
|
||||
Info<< "\\fB[Parallel option]\\fR" << nl;
|
||||
}
|
||||
@ -314,7 +314,7 @@ void Foam::argList::printMan() const
|
||||
for (const word& optName : validOptions.sortedToc())
|
||||
{
|
||||
// Normal (non-advanced) options
|
||||
if (!advancedOptions.found(optName))
|
||||
if (!advancedOptions.contains(optName))
|
||||
{
|
||||
printManOption(optName);
|
||||
}
|
||||
@ -333,7 +333,7 @@ void Foam::argList::printMan() const
|
||||
for (const word& optName : validOptions.sortedToc())
|
||||
{
|
||||
// Advanced options
|
||||
if (advancedOptions.found(optName))
|
||||
if (advancedOptions.contains(optName))
|
||||
{
|
||||
printManOption(optName);
|
||||
}
|
||||
@ -418,7 +418,7 @@ void Foam::argList::printUsage(bool full) const
|
||||
for (const word& optName : validOptions.sortedToc())
|
||||
{
|
||||
// Suppress advanced options for regular -help.
|
||||
if (full || !advancedOptions.found(optName))
|
||||
if (full || !advancedOptions.contains(optName))
|
||||
{
|
||||
printOption(optName);
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2011-2013 OpenFOAM Foundation
|
||||
Copyright (C) 2017-2021 OpenCFD Ltd.
|
||||
Copyright (C) 2017-2023 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -37,7 +37,7 @@ inline void Foam::argList::readList(ITstream& is, List<T>& list)
|
||||
{
|
||||
// Single token - treat like List with one entry
|
||||
list.resize(1);
|
||||
is >> list.first();
|
||||
is >> list.front();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -177,7 +177,7 @@ Foam::argList::options() noexcept
|
||||
|
||||
inline bool Foam::argList::found(const word& optName) const
|
||||
{
|
||||
return options_.found(optName);
|
||||
return options_.contains(optName);
|
||||
}
|
||||
|
||||
|
||||
@ -309,7 +309,7 @@ inline T Foam::argList::getOrDefault
|
||||
const T& deflt
|
||||
) const
|
||||
{
|
||||
if (found(optName))
|
||||
if (options_.contains(optName))
|
||||
{
|
||||
return get<T>(optName);
|
||||
}
|
||||
@ -325,7 +325,7 @@ inline bool Foam::argList::readIfPresent
|
||||
T& val
|
||||
) const
|
||||
{
|
||||
if (found(optName))
|
||||
if (options_.contains(optName))
|
||||
{
|
||||
val = get<T>(optName);
|
||||
return true;
|
||||
@ -376,7 +376,7 @@ inline Foam::List<T> Foam::argList::getList
|
||||
{
|
||||
List<T> list;
|
||||
|
||||
if (mandatory || found(optName))
|
||||
if (mandatory || options_.contains(optName))
|
||||
{
|
||||
ITstream is(options_[optName]);
|
||||
|
||||
@ -396,7 +396,7 @@ inline bool Foam::argList::readListIfPresent
|
||||
List<T>& list
|
||||
) const
|
||||
{
|
||||
if (found(optName))
|
||||
if (options_.contains(optName))
|
||||
{
|
||||
ITstream is(options_[optName]);
|
||||
|
||||
|
@ -37,10 +37,10 @@ Note
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef argListRunControl_H
|
||||
#define argListRunControl_H
|
||||
#ifndef Foam_argListRunControl_H
|
||||
#define Foam_argListRunControl_H
|
||||
|
||||
#include "Pstream.H"
|
||||
#include "UPstream.H"
|
||||
#include "IOstreams.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -54,22 +54,39 @@ namespace Foam
|
||||
|
||||
class ParRunControl
|
||||
{
|
||||
// Private Data
|
||||
|
||||
//- The dry-run level
|
||||
int dryRun_;
|
||||
|
||||
//- The verbosity level
|
||||
int verbose_;
|
||||
|
||||
//- True if this is (or will be) a parallel run
|
||||
bool parallel_;
|
||||
|
||||
//- Uses distributed roots
|
||||
bool distributed_;
|
||||
|
||||
//- MPI threads are desired
|
||||
bool needsThread_;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Default construct
|
||||
ParRunControl()
|
||||
ParRunControl() noexcept
|
||||
:
|
||||
dryRun_(0),
|
||||
verbose_(0),
|
||||
parallel_(false),
|
||||
distributed_(false)
|
||||
distributed_(false),
|
||||
needsThread_(false)
|
||||
{}
|
||||
|
||||
|
||||
//- Destructor. Shutdown (finalize) MPI as required
|
||||
~ParRunControl()
|
||||
{
|
||||
@ -81,27 +98,56 @@ public:
|
||||
}
|
||||
|
||||
|
||||
// Parallel Control
|
||||
// Member Functions - General Control
|
||||
|
||||
//- Initialize Pstream for a parallel run
|
||||
void runPar(int& argc, char**& argv, bool needsThread)
|
||||
//- Return the dry-run level (default: 0)
|
||||
int dryRun() const noexcept { return dryRun_; }
|
||||
|
||||
//- Increase the dry-run level
|
||||
void incrDryRun(int level = 1) noexcept { dryRun_ += level; }
|
||||
|
||||
//- Change dry-run level, returns old value
|
||||
int dryRun(const int level) noexcept
|
||||
{
|
||||
if (!UPstream::init(argc, argv, needsThread))
|
||||
{
|
||||
Info<< "Failed to start parallel run" << endl;
|
||||
UPstream::exit(1);
|
||||
int old(dryRun_);
|
||||
dryRun_ = level;
|
||||
return old;
|
||||
}
|
||||
parallel_ = true;
|
||||
|
||||
//- Return the verbosity level (default: 0)
|
||||
int verbose() const noexcept { return verbose_; }
|
||||
|
||||
//- Increase the verbosity level
|
||||
void incrVerbose(int level = 1) noexcept { verbose_ += level; }
|
||||
|
||||
//- Change verbosity level, returns old value
|
||||
int verbose(const int level) noexcept
|
||||
{
|
||||
int old(verbose_);
|
||||
verbose_ = level;
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
//- True if this is a parallel run
|
||||
// Member Functions - Parallel Control
|
||||
|
||||
//- True if this is (or will be) a parallel run
|
||||
bool parRun() const noexcept
|
||||
{
|
||||
return parallel_;
|
||||
}
|
||||
|
||||
//- True if this is a parallel run and uses distributed roots.
|
||||
//- Set as parallel run on/off, return the previous value.
|
||||
// Use with \b extreme caution if runPar() has already been
|
||||
// called.
|
||||
bool parRun(const bool on) noexcept
|
||||
{
|
||||
bool old(parallel_);
|
||||
parallel_ = on;
|
||||
return old;
|
||||
}
|
||||
|
||||
//- True if a parallel run and uses distributed roots.
|
||||
bool distributed() const noexcept
|
||||
{
|
||||
return (parallel_ && distributed_);
|
||||
@ -113,35 +159,27 @@ public:
|
||||
distributed_ = (parallel_ && on);
|
||||
}
|
||||
|
||||
|
||||
// General Control
|
||||
|
||||
//- Non-zero if set as 'dry-run'
|
||||
int dryRun() const noexcept
|
||||
//- True if MPI threads are desired (default: false)
|
||||
bool threads() const noexcept
|
||||
{
|
||||
return dryRun_;
|
||||
return needsThread_;
|
||||
}
|
||||
|
||||
//- Change 'dry-run', return old value
|
||||
int dryRun(const int level) noexcept
|
||||
//- Set preference for use of MPI threads
|
||||
void threads(bool on) noexcept
|
||||
{
|
||||
int old(dryRun_);
|
||||
dryRun_ = level;
|
||||
return old;
|
||||
needsThread_ = on;
|
||||
}
|
||||
|
||||
//- Non-zero if set as 'verbose'
|
||||
int verbose() const noexcept
|
||||
//- Initialize UPstream for a parallel run
|
||||
void runPar(int& argc, char**& argv)
|
||||
{
|
||||
return verbose_;
|
||||
if (!UPstream::init(argc, argv, needsThread_))
|
||||
{
|
||||
Info<< "Failed to start parallel run" << endl;
|
||||
UPstream::exit(1);
|
||||
}
|
||||
|
||||
//- Change 'verbose', return old value
|
||||
int verbose(const int level) noexcept
|
||||
{
|
||||
int old(verbose_);
|
||||
verbose_ = level;
|
||||
return old;
|
||||
parallel_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -282,12 +282,16 @@ bool Foam::UPstream::init(int& argc, char**& argv, const bool needsThread)
|
||||
if (UPstream::debug)
|
||||
{
|
||||
Pout<< "UPstream::init :"
|
||||
<< " thread-support : wanted:" << needsThread
|
||||
<< " thread-support : requested:" << needsThread
|
||||
<< " obtained:"
|
||||
<< (
|
||||
provided_thread_support == MPI_THREAD_MULTIPLE
|
||||
? "MPI_THREAD_MULTIPLE"
|
||||
: "MPI_THREAD_SINGLE"
|
||||
(provided_thread_support == MPI_THREAD_SINGLE)
|
||||
? "SINGLE"
|
||||
: (provided_thread_support == MPI_THREAD_SERIALIZED)
|
||||
? "SERIALIZED"
|
||||
: (provided_thread_support == MPI_THREAD_MULTIPLE)
|
||||
? "MULTIPLE"
|
||||
: "other"
|
||||
)
|
||||
<< " procs:" << numprocs
|
||||
<< " rank:" << myRank
|
||||
|
Loading…
Reference in New Issue
Block a user