diff --git a/applications/test/argList/Test-argList.C b/applications/test/argList/Test-argList.C index 44edb17aad..fafa778517 100644 --- a/applications/test/argList/Test-argList.C +++ b/applications/test/argList/Test-argList.C @@ -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 (" diff --git a/applications/test/parallel-comm0/Test-parallel-comm0.C b/applications/test/parallel-comm0/Test-parallel-comm0.C index 3abb70d6ba..5212eda189 100644 --- a/applications/test/parallel-comm0/Test-parallel-comm0.C +++ b/applications/test/parallel-comm0/Test-parallel-comm0.C @@ -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" diff --git a/applications/test/parallel-comm2/Test-parallel-comm2.C b/applications/test/parallel-comm2/Test-parallel-comm2.C index d38f35c1b3..5f9f575bf6 100644 --- a/applications/test/parallel-comm2/Test-parallel-comm2.C +++ b/applications/test/parallel-comm2/Test-parallel-comm2.C @@ -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" diff --git a/applications/test/parallel-external-init/Test-parallel-external-init.C b/applications/test/parallel-external-init/Test-parallel-external-init.C index 362dc0b382..a838739ee1 100644 --- a/applications/test/parallel-external-init/Test-parallel-external-init.C +++ b/applications/test/parallel-external-init/Test-parallel-external-init.C @@ -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(); diff --git a/applications/test/processorTopology/Test-processorTopology.C b/applications/test/processorTopology/Test-processorTopology.C index 0150221d86..ffad839c58 100644 --- a/applications/test/processorTopology/Test-processorTopology.C +++ b/applications/test/processorTopology/Test-processorTopology.C @@ -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" diff --git a/applications/utilities/miscellaneous/foamFormatConvert/foamFormatConvert.C b/applications/utilities/miscellaneous/foamFormatConvert/foamFormatConvert.C index 443d4d32d8..760474570f 100644 --- a/applications/utilities/miscellaneous/foamFormatConvert/foamFormatConvert.C +++ b/applications/utilities/miscellaneous/foamFormatConvert/foamFormatConvert.C @@ -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 { diff --git a/applications/utilities/preProcessing/foamUpgradeCyclics/foamUpgradeCyclics.C b/applications/utilities/preProcessing/foamUpgradeCyclics/foamUpgradeCyclics.C index f1c9fca80a..695e2a961e 100644 --- a/applications/utilities/preProcessing/foamUpgradeCyclics/foamUpgradeCyclics.C +++ b/applications/utilities/preProcessing/foamUpgradeCyclics/foamUpgradeCyclics.C @@ -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; diff --git a/src/OpenFOAM/db/Time/TimeIO.C b/src/OpenFOAM/db/Time/TimeIO.C index 3a7fa55ae4..aff2757899 100644 --- a/src/OpenFOAM/db/Time/TimeIO.C +++ b/src/OpenFOAM/db/Time/TimeIO.C @@ -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 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& objects = *iter; @@ -214,7 +220,7 @@ void Foam::Time::readDict() { obj->readData(dummyIs); - if (Foam::infoDetailLevel > 0) + if (verbose) { Info<< " "; obj->writeData(Info); diff --git a/src/OpenFOAM/global/argList/argList.C b/src/OpenFOAM/global/argList/argList.C index a19a57e842..6ded4cec85 100644 --- a/src/OpenFOAM/global/argList/argList.C +++ b/src/OpenFOAM/global/argList/argList.C @@ -54,6 +54,7 @@ License bool Foam::argList::argsMandatory_ = true; bool Foam::argList::checkProcessorDirectories_ = true; +bool Foam::argList::parallelThreads_ = false; Foam::SLList Foam::argList::validArgs; Foam::HashSet 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,11 +614,18 @@ void Foam::argList::noCheckProcessorDirectories() bool Foam::argList::postProcess(int argc, char *argv[]) { - for (int i=1; i 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) - { - handlerType = argv[argi+1]; - break; - } - } - } - if (handlerType.empty()) + word fileHandlerName; + + if (parallelThreads_) { - 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] == '-') + { + ++optName; // Looks like an option, skip leading '-' + bool emitErrorMessage = false; + + if (strcmp(optName, "dry-run") == 0) { - runControl_.runPar(argc, argv, needsThread); - break; + 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& 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 optionNames -) const +Foam::label Foam::argList::count(std::initializer_list 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 diff --git a/src/OpenFOAM/global/argList/argList.H b/src/OpenFOAM/global/argList/argList.H index 8a101e8781..0b0efa5844 100644 --- a/src/OpenFOAM/global/argList/argList.H +++ b/src/OpenFOAM/global/argList/argList.H @@ -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 diff --git a/src/OpenFOAM/global/argList/argListHelp.C b/src/OpenFOAM/global/argList/argListHelp.C index 883fbebb93..042e429734 100644 --- a/src/OpenFOAM/global/argList/argListHelp.C +++ b/src/OpenFOAM/global/argList/argListHelp.C @@ -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); } diff --git a/src/OpenFOAM/global/argList/argListI.H b/src/OpenFOAM/global/argList/argListI.H index e58279e41c..e5ef0046c6 100644 --- a/src/OpenFOAM/global/argList/argListI.H +++ b/src/OpenFOAM/global/argList/argListI.H @@ -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& 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(optName); } @@ -325,7 +325,7 @@ inline bool Foam::argList::readIfPresent T& val ) const { - if (found(optName)) + if (options_.contains(optName)) { val = get(optName); return true; @@ -376,7 +376,7 @@ inline Foam::List Foam::argList::getList { List list; - if (mandatory || found(optName)) + if (mandatory || options_.contains(optName)) { ITstream is(options_[optName]); @@ -396,7 +396,7 @@ inline bool Foam::argList::readListIfPresent List& list ) const { - if (found(optName)) + if (options_.contains(optName)) { ITstream is(options_[optName]); diff --git a/src/OpenFOAM/global/argList/parRun.H b/src/OpenFOAM/global/argList/parRun.H index 3610ab67c0..0b7d8e3412 100644 --- a/src/OpenFOAM/global/argList/parRun.H +++ b/src/OpenFOAM/global/argList/parRun.H @@ -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,21 +54,38 @@ namespace Foam class ParRunControl { - int dryRun_; - int verbose_; - bool parallel_; - bool distributed_; + // 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: - //- Default construct - ParRunControl() - : - dryRun_(0), - verbose_(0), - parallel_(false), - distributed_(false) - {} + // Constructors + + //- Default construct + ParRunControl() noexcept + : + dryRun_(0), + verbose_(0), + parallel_(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); - } - parallel_ = true; + int old(dryRun_); + dryRun_ = level; + return old; + } + + //- 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_; - } - - //- Change 'verbose', return old value - int verbose(const int level) noexcept - { - int old(verbose_); - verbose_ = level; - return old; + if (!UPstream::init(argc, argv, needsThread_)) + { + Info<< "Failed to start parallel run" << endl; + UPstream::exit(1); + } + parallel_ = true; } }; diff --git a/src/Pstream/mpi/UPstream.C b/src/Pstream/mpi/UPstream.C index 1b982ca32a..0f22ca74c3 100644 --- a/src/Pstream/mpi/UPstream.C +++ b/src/Pstream/mpi/UPstream.C @@ -282,13 +282,17 @@ 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 << " world:" << world << endl;