BUG: masterUncollatedFileOperation checking of file-size
- used Foam:fileSize check to decide on scheduled/nonBlocking but this
was being done on all ranks and subsequently broadcast.
Now avoid unnecessary filesystem access on non-master ranks.
- a Pstream::master with a Pstream::parRun guard in case Pstream has
not yet been initialised, as will be the case for low-level messages
during startup.
- propagate relativeName handling into IOstreams
- simplifies local toggling.
- centralize fileModification static variables into IOobject.
They were previously scattered between IOobject and regIOobject
- This reflects the pre-existing coding situation where const_cast was
used throughout to effect the same.
STYLE: fix private/protected access
- CodedField, codedMixedFvPatchField
- libs() singleton method for global library handling
- explicit handling of empty filename for dlLibraryTable open/close.
Largely worked before, but now be more explicit about its behaviour.
- add (key, dict) constructor and open() methods.
More similarity to dimensionedType, Enum etc, and there is no
ambiguity with the templated open().
- construct or open from initializer_list of names
- optional verbosity when opening with auxiliary table,
avoid duplicate messages or spurious messages for these.
- basename and fullname methods (migrated from dynamicCode).
- centralise low-level load/unload hooks
- adjust close to also dlclose() aliased library names.
- for codedFunctionObject and CodedSource the main code snippets
were not included in the SHA1 calculation, which meant that many
changes would not be noticed and no new library would be compiled.
As a workaround, a dummy 'code' entry could be used solely for the
purposes of generating a SHA1, but this is easily forgotten.
We now allow tracking of the dynamicCodeContext for the coded
objects and append to the SHA1 hasher with specific entries.
This should solve the previous misbehaviour.
We additionally add information about the ordering of the code
sections. Suppose we have a coded function object (all code
segments are optional) with the following:
codeExecute "";
codeWrite #{ Info<< "Called\n"; #};
which we subsequently change to this:
codeExecute #{ Info<< "Called\n"; #};
codeWrite "";
If the code strings are simply concatenated together, the SHA1 hashes
will be identical. We thus 'salt' with their semantic locations,
choosing tags that are unlikely to occur within the code strings
themselves.
- simplify the coded templates with constexpr for the SHA1sum
information.
- Correct the CodedSource to use 'codeConstrain' instead of
'codeSetValue' for consistency with the underlying functions.
- add additional control via a Foam::infoDetailLevel flag, which is
supported by a 'DetailLevel' macro. Eg,
DetailLevel << "some information" << nl
- When infoDetailLevel is zero, the stdout for all Foam::system() calls
are also redirected to stderr to prevent child output from
appearing on the parent.
- close stdin before exec in system call.
Original commit message:
------------------------
Parallel IO: New collated file format
When an OpenFOAM simulation runs in parallel, the data for decomposed fields and
mesh(es) has historically been stored in multiple files within separate
directories for each processor. Processor directories are named 'processorN',
where N is the processor number.
This commit introduces an alternative "collated" file format where the data for
each decomposed field (and mesh) is collated into a single file, which is
written and read on the master processor. The files are stored in a single
directory named 'processors'.
The new format produces significantly fewer files - one per field, instead of N
per field. For large parallel cases, this avoids the restriction on the number
of open files imposed by the operating system limits.
The file writing can be threaded allowing the simulation to continue running
while the data is being written to file. NFS (Network File System) is not
needed when using the the collated format and additionally, there is an option
to run without NFS with the original uncollated approach, known as
"masterUncollated".
The controls for the file handling are in the OptimisationSwitches of
etc/controlDict:
OptimisationSwitches
{
...
//- Parallel IO file handler
// uncollated (default), collated or masterUncollated
fileHandler uncollated;
//- collated: thread buffer size for queued file writes.
// If set to 0 or not sufficient for the file size threading is not used.
// Default: 2e9
maxThreadFileBufferSize 2e9;
//- masterUncollated: non-blocking buffer size.
// If the file exceeds this buffer size scheduled transfer is used.
// Default: 2e9
maxMasterFileBufferSize 2e9;
}
When using the collated file handling, memory is allocated for the data in the
thread. maxThreadFileBufferSize sets the maximum size of memory in bytes that
is allocated. If the data exceeds this size, the write does not use threading.
When using the masterUncollated file handling, non-blocking MPI communication
requires a sufficiently large memory buffer on the master node.
maxMasterFileBufferSize sets the maximum size in bytes of the buffer. If the
data exceeds this size, the system uses scheduled communication.
The installation defaults for the fileHandler choice, maxThreadFileBufferSize
and maxMasterFileBufferSize (set in etc/controlDict) can be over-ridden within
the case controlDict file, like other parameters. Additionally the fileHandler
can be set by:
- the "-fileHandler" command line argument;
- a FOAM_FILEHANDLER environment variable.
A foamFormatConvert utility allows users to convert files between the collated
and uncollated formats, e.g.
mpirun -np 2 foamFormatConvert -parallel -fileHandler uncollated
An example case demonstrating the file handling methods is provided in:
$FOAM_TUTORIALS/IO/fileHandling
The work was undertaken by Mattijs Janssens, in collaboration with Henry Weller.
- The logic for switching input-mode was previously completely
encapsulated within the #inputMode directive, but without any
programming equivalent. Furthermore, the encapsulation in inputMode
made the logic less clear in other places.
Exposing the inputMode as an enum with direct access from entry
simplifies things a fair bit.
- eliminate one level of else/if nesting in entryIO.C for clearer logic
- for dictionary function entries, simply use
addNamedToMemberFunctionSelectionTable() and avoid defining a type()
as a static. For most function entries the information is only used
to get a name for the selection table lookup anyhow.
- use allocator class to wrap the stream pointers instead of passing
them into ISstream, OSstream and using a dynamic cast to delete
then. This is especially important if we will have a bidirectional
stream (can't delete twice!).
STYLE:
- file stream constructors with std::string (C++11)
- for rewind, explicit about in|out direction. This is not currently
important, but avoids surprises with any future bidirectional access.
- combined string streams in StringStream.H header.
Similar to <sstream> include that has both input and output string
streams.
Problems remain with codedFixedValueFvPatchScalarField:
- readIfModified() notices change on system/codeDict, but the
codeProperties::setUnmodified() means that only a single entry will
get processed
- it appears that while dlclose() may (or may not) be actually closing
the library, there are probably still references about. This means
that a subsequent reloading still points to the original functions
and the lookup is not updated correctly.