From 8959b8e00a23a952057773aedebd6f30352b7d14 Mon Sep 17 00:00:00 2001 From: Henry Weller Date: Wed, 21 Mar 2018 12:42:22 +0000 Subject: [PATCH] ENH: Improvements to the fileHandler and collated IO Improvements to existing functionality -------------------------------------- - MPI is initialised without thread support if it is not needed e.g. uncollated - Use native c++11 threading; avoids problem with static destruction order. - etc/cellModels now only read if needed. - etc/controlDict can now be read from the environment variable FOAM_CONTROLDICT - Uniform files (e.g. '0/uniform/time') are now read only once on the master only (with the masterUncollated or collated file handlers) - collated format writes to 'processorsNNN' instead of 'processors'. The file format is unchanged. - Thread buffer and file buffer size are no longer limited to 2Gb. The global controlDict file contains parameters for file handling. Under some circumstances, e.g. running in parallel on a system without NFS, the user may need to set some parameters, e.g. fileHandler, before the global controlDict file is read from file. To support this, OpenFOAM now allows the global controlDict to be read as a string set to the FOAM_CONTROLDICT environment variable. The FOAM_CONTROLDICT environment variable can be set to the content the global controlDict file, e.g. from a sh/bash shell: export FOAM_CONTROLDICT=$(foamDictionary $FOAM_ETC/controlDict) FOAM_CONTROLDICT can then be passed to mpirun using the -x option, e.g.: mpirun -np 2 -x FOAM_CONTROLDICT simpleFoam -parallel Note that while this avoids the need for NFS to read the OpenFOAM configuration the executable still needs to load shared libraries which must either be copied locally or available via NFS or equivalent. New: Multiple IO ranks ---------------------- The masterUncollated and collated fileHandlers can now use multiple ranks for writing e.g.: mpirun -np 6 simpleFoam -parallel -ioRanks '(0 3)' In this example ranks 0 ('processor0') and 3 ('processor3') now handle all the I/O. Rank 0 handles 0,1,2 and rank 3 handles 3,4,5. The set of IO ranks should always include 0 as first element and be sorted in increasing order. The collated fileHandler uses the directory naming processorsNNN_XXX-YYY where NNN is the total number of processors and XXX and YYY are first and last processor in the rank, e.g. in above example the directories would be processors6_0-2 processors6_3-5 and each of the collated files in these contains data of the local ranks only. The same naming also applies when e.g. running decomposePar: decomposePar -fileHandler collated -ioRanks '(0 3)' New: Distributed data --------------------- The individual root directories can be placed on different hosts with different paths if necessary. In the current framework it is necessary to specify the root per slave process but this has been simplified with the option of specifying the root per host with the -hostRoots command line option: mpirun -np 6 simpleFoam -parallel -ioRanks '(0 3)' \ -hostRoots '("machineA" "/tmp/" "machineB" "/tmp")' The hostRoots option is followed by a list of machine name + root directory, the machine name can contain regular expressions. New: hostCollated ----------------- The new hostCollated fileHandler automatically sets the 'ioRanks' according to the host name with the lowest rank e.g. to run simpleFoam on 6 processors with ranks 0-2 on machineA and ranks 3-5 on machineB with the machines specified in the hostfile: mpirun -np 6 --hostfile hostfile simpleFoam -parallel -fileHandler hostCollated This is equivalent to mpirun -np 6 --hostfile hostfile simpleFoam -parallel -fileHandler collated -ioRanks '(0 3)' This example will write directories: processors6_0-2/ processors6_3-5/ A typical example would use distributed data e.g. no two nodes, machineA and machineB, each with three processes: decomposePar -fileHandler collated -case cavity # Copy case (constant/*, system/*, processors6/) to master: rsync -a cavity machineA:/tmp/ # Create root on slave: ssh machineB mkdir -p /tmp/cavity # Run mpirun --hostfile hostfile icoFoam \ -case /tmp/cavity -parallel -fileHandler hostCollated \ -hostRoots '("machineA" "/tmp" "machineB" "/tmp")' Contributed by Mattijs Janssens --- .../decomposePar/decomposePar.C | 49 +- .../reconstructPar/reconstructPar.C | 3 + .../graphics/PVReaders/vtkPVFoam/vtkPVFoam.C | 26 +- src/OSspecific/POSIX/POSIX.C | 146 +- src/OpenFOAM/Make/files | 3 +- .../decomposedBlockData/decomposedBlockData.C | 143 +- .../decomposedBlockData/decomposedBlockData.H | 18 +- src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H | 6 +- src/OpenFOAM/db/Time/Time.C | 30 + src/OpenFOAM/db/Time/Time.H | 3 - src/OpenFOAM/db/Time/findInstance.C | 236 --- src/OpenFOAM/db/regIOobject/regIOobjectRead.C | 5 +- src/OpenFOAM/global/argList/argList.C | 190 +- src/OpenFOAM/global/argList/parRun.H | 6 +- src/OpenFOAM/global/debug/debug.C | 36 +- .../collatedFileOperation/OFstreamCollator.C | 372 ++-- .../collatedFileOperation/OFstreamCollator.H | 45 +- .../collatedFileOperation.C | 339 ++- .../collatedFileOperation.H | 81 +- .../hostCollatedFileOperation.C | 176 ++ .../hostCollatedFileOperation.H | 134 ++ .../fileOperation/fileOperation.C | 866 ++++++-- .../fileOperation/fileOperation.H | 152 +- .../fileOperationInitialise.C | 88 + .../fileOperationInitialise.H | 102 + .../unthreadedInitialise.H | 84 + .../masterUncollatedFileOperation.C | 1816 ++++++++++++----- .../masterUncollatedFileOperation.H | 155 +- .../masterUncollatedFileOperationTemplates.C | 58 +- .../uncollatedFileOperation.C | 66 +- src/OpenFOAM/include/OSspecific.H | 27 - src/OpenFOAM/memory/tmp/tmpNrc.H | 5 +- src/Pstream/dummy/UPstream.C | 4 +- src/Pstream/mpi/UPstream.C | 13 +- tutorials/IO/fileHandler/Allclean | 8 +- tutorials/IO/fileHandler/Allrun | 74 +- tutorials/IO/fileHandler/system/controlDict | 7 +- 37 files changed, 4093 insertions(+), 1479 deletions(-) delete mode 100644 src/OpenFOAM/db/Time/findInstance.C create mode 100644 src/OpenFOAM/global/fileOperations/collatedFileOperation/hostCollatedFileOperation.C create mode 100644 src/OpenFOAM/global/fileOperations/collatedFileOperation/hostCollatedFileOperation.H create mode 100644 src/OpenFOAM/global/fileOperations/fileOperationInitialise/fileOperationInitialise.C create mode 100644 src/OpenFOAM/global/fileOperations/fileOperationInitialise/fileOperationInitialise.H create mode 100644 src/OpenFOAM/global/fileOperations/fileOperationInitialise/unthreadedInitialise.H diff --git a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C index fa0dd946bd..b14da4cca1 100644 --- a/applications/utilities/parallelProcessing/decomposePar/decomposePar.C +++ b/applications/utilities/parallelProcessing/decomposePar/decomposePar.C @@ -356,6 +356,9 @@ int main(int argc, char *argv[]) ) ); + // Give file handler a chance to determine the output directory + const_cast(fileHandler()).setNProcs(nDomains); + if (decomposeFieldsOnly) { // Sanity check on previously decomposed case @@ -395,22 +398,42 @@ int main(int argc, char *argv[]) Info<< "Removing " << nProcs << " existing processor directories" << endl; - fileHandler().rmDir + // Remove existing processors directory + fileNameList dirs ( - runTime.path()/word("processors"), - true // silent (may not have been collated) - ); - - // remove existing processor dirs - // reverse order to avoid gaps if someone interrupts the process - for (label proci = nProcs-1; proci >= 0; --proci) - { - fileName procDir + fileHandler().readDir ( - runTime.path()/(word("processor") + name(proci)) - ); + runTime.path(), + fileName::Type::DIRECTORY + ) + ); + forAllReverse(dirs, diri) + { + const fileName& d = dirs[diri]; - fileHandler().rmDir(procDir); + // Starts with 'processors' + if (d.find("processors") == 0) + { + if (fileHandler().exists(d)) + { + fileHandler().rmDir(d); + } + } + + // Starts with 'processor' + if (d.find("processor") == 0) + { + // Check that integer after processor + fileName num(d.substr(9)); + label proci = -1; + if (Foam::read(num.c_str(), proci)) + { + if (fileHandler().exists(d)) + { + fileHandler().rmDir(d); + } + } + } } procDirsProblem = false; diff --git a/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C b/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C index c8ab33cfa2..d807c19223 100644 --- a/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C +++ b/applications/utilities/parallelProcessing/reconstructPar/reconstructPar.C @@ -216,6 +216,9 @@ int main(int argc, char *argv[]) << exit(FatalError); } + // Warn fileHandler of number of processors + const_cast(fileHandler()).setNProcs(nProcs); + // Create the processor databases PtrList