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