From 06147dabe7ec06c777f7ab59ef80ef94abde58d4 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Wed, 17 May 2023 11:24:44 +0200 Subject: [PATCH] ENH: more flexible handling of FOAM_IORANKS - accept plain lists (space or comma separated) as well as the traditional OpenFOAM lists. This simplifies argument handling with job scripts. For example, simpleFoam -ioRanks 0,4,8 ... vs simpleFoam -ioRanks '(0 4 8)' ... It is also possible to select the IO ranks on a per-host basis: simpleFoam -ioRanks host ... - expose rank/subrank handling as static fileOperation methods --- .../test/fileHandler-ranks1/Make/files | 3 + .../test/fileHandler-ranks1/Make/options | 2 + applications/test/fileHandler-ranks1/README | 20 ++ .../Test-fileHandler-ranks1.C | 249 ++++++++++++++ src/OpenFOAM/Make/files | 1 + .../collatedFileOperation.C | 10 +- .../collatedFileOperation.H | 2 +- .../hostCollatedFileOperation.C | 56 +-- .../hostCollatedFileOperation.H | 18 +- .../fileOperation/fileOperation.C | 14 - .../fileOperation/fileOperation.H | 61 +++- .../fileOperation/fileOperationRanks.C | 319 ++++++++++++++++++ .../masterUncollatedFileOperation.C | 37 +- tutorials/IO/fileHandler/Allrun | 8 +- 14 files changed, 680 insertions(+), 120 deletions(-) create mode 100644 applications/test/fileHandler-ranks1/Make/files create mode 100644 applications/test/fileHandler-ranks1/Make/options create mode 100644 applications/test/fileHandler-ranks1/README create mode 100644 applications/test/fileHandler-ranks1/Test-fileHandler-ranks1.C create mode 100644 src/OpenFOAM/global/fileOperations/fileOperation/fileOperationRanks.C diff --git a/applications/test/fileHandler-ranks1/Make/files b/applications/test/fileHandler-ranks1/Make/files new file mode 100644 index 0000000000..7ad7a3eb9a --- /dev/null +++ b/applications/test/fileHandler-ranks1/Make/files @@ -0,0 +1,3 @@ +Test-fileHandler-ranks1.C + +EXE = $(FOAM_USER_APPBIN)/Test-fileHandler-ranks1 diff --git a/applications/test/fileHandler-ranks1/Make/options b/applications/test/fileHandler-ranks1/Make/options new file mode 100644 index 0000000000..18e6fe47af --- /dev/null +++ b/applications/test/fileHandler-ranks1/Make/options @@ -0,0 +1,2 @@ +/* EXE_INC = */ +/* EXE_LIBS = */ diff --git a/applications/test/fileHandler-ranks1/README b/applications/test/fileHandler-ranks1/README new file mode 100644 index 0000000000..657fad446a --- /dev/null +++ b/applications/test/fileHandler-ranks1/README @@ -0,0 +1,20 @@ +Test that -ioRanks selections perform as expected and that sub-rank +selection is also doing the correct thing. + +For example, + +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks host +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks '(0 3 14)' +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks 14,15,2,0,10,15,0,0,0, +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks '0,3,10' +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks '0,3,11' +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks '0,3,14' +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks '0,3,15' +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks '0,3,12,115' +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks '0,3,10,12,115' +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks host -pick '1,2,3,4' +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -pick '2,4,6,8' +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks '0,3' -pick '2,4,6,8' +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks '0,4' -pick '2,4,6,8' +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks '0,6' -pick '2,4,6,8' +mpirun -np 10 --oversubscribe Test-fileHandler-ranks1 -parallel -ioRanks '0,6' -pick '2,4,6,8' diff --git a/applications/test/fileHandler-ranks1/Test-fileHandler-ranks1.C b/applications/test/fileHandler-ranks1/Test-fileHandler-ranks1.C new file mode 100644 index 0000000000..253553e7d6 --- /dev/null +++ b/applications/test/fileHandler-ranks1/Test-fileHandler-ranks1.C @@ -0,0 +1,249 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2023 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see . + +Application + Test-fileHandler-ranks1 + +Description + Test IO ranks and ranks selection + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "fileName.H" +#include "fileOperation.H" +#include "IOstreams.H" +#include "ITstream.H" +#include "OSspecific.H" +#include "Pstream.H" +#include "SHA1.H" +#include "stringOps.H" + +using namespace Foam; + +// Parse space, comma, semicolon separated list of integers, floats etc... +template +static List splitStringToList(const std::string& str) +{ + const SubStrings items = stringOps::splitAny(str, " ,;"); + + DynamicList values(items.size()); + + for (const auto& item : items) + { + const std::string s(item.str()); + + PrimitiveType val; + + if (Foam::read(s, val)) + { + values.push_back(val); + } + else + { + // Report errors? Could get noisy... + } + } + + return List(std::move(values)); +} + + +//- Construct by parsing string for scalar ranges +// The individual items are space, comma or semicolon delimited. +static labelList parseIOranks +( + const Foam::string& str, + label numProcs = -1 +) +{ + bool byHostName = false; + + labelList ranks; + + // Info<< "parsing: " << str << endl; + + if (!str.empty()) + { + if (str.contains('(')) + { + // Looks like a list - tokenise it + + ITstream is(str); + if (!is.empty()) + { + is >> ranks; + } + } + else if (str == "host") + { + // Select by host + byHostName = true; + } + else + { + // Manual parse + ranks = splitStringToList