Loading...
Searching...
No Matches
fileOperationNew.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2022-2023 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26\*---------------------------------------------------------------------------*/
27
28#include "fileOperation.H"
29#include "dummyFileOperation.H"
31
32// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
33
34Foam::refPtr<Foam::fileOperation> Foam::fileOperation::dummyHandlerPtr_;
35
37
38
39// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
40
42{
43 if (!dummyHandlerPtr_)
44 {
45 // verbose = false
46 dummyHandlerPtr_.reset(new fileOperations::dummyFileOperation(false));
47 }
48
49 return dummyHandlerPtr_;
50}
51
52
54{
56 {
57 word handlerType(Foam::getEnv("FOAM_FILEHANDLER"));
58
59 if (handlerType.empty())
60 {
61 handlerType = defaultFileHandler;
62 }
63
65 }
66
68}
69
70
73{
74 return refPtr<fileOperation>(std::move(fileHandlerPtr_));
75}
76
77
80{
81 // - do nothing if newHandler is empty. Does not delete current
82 // - do nothing if newHandler is identical to current handler
83
84 // Change ownership as atomic operations
85
86 // If newHandler and current handler are actually identical, we
87 // have a bit problem somewhere else since this means that the pointer
88 // is managed is done in two places!
89 // Should flag as a FatalError (in the future), but there may still be
90 // some place where we would like to fake shared pointers?
91
92 // TBD: add a flush() operation on the old handler first,
93 // instead of waiting for it to be run on destruction?
94
96
97 if
98 (
99 newHandler.get() != nullptr
100 && newHandler.get() != fileOperation::fileHandlerPtr_.get()
101 )
102 {
103 old.swap(newHandler);
106
107 return old;
108}
109
110
112Foam::fileOperation::fileHandler(autoPtr<fileOperation>&& newHandler)
113{
114 // Same logic as refPtr version
115
116 refPtr<fileOperation> old;
117
118 if
119 (
120 newHandler.get() != nullptr
121 && newHandler.get() != fileOperation::fileHandlerPtr_.get()
122 )
123 {
124 old.reset(newHandler.release());
127
128 return old;
129}
130
131
140{
142 (
143 new fileOperations::uncollatedFileOperation(false) // verbose = false
144 );
145}
146
147
148// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
149
152(
153 const word& handlerType,
154 bool verbose
155)
156{
157 if (handlerType.empty())
158 {
160 {
162 << "Default file-handler name is undefined" << nl
163 << abort(FatalError);
164 }
165
166 // Forward to self
168 }
169
171 << "Constructing fileHandler: " << handlerType << endl;
172
173 auto* ctorPtr = wordConstructorTable(handlerType);
174
175 if (!ctorPtr)
176 {
178 (
179 "fileHandler",
180 handlerType,
181 *wordConstructorTablePtr_
182 ) << abort(FatalError);
184
185 return autoPtr<fileOperation>(ctorPtr(verbose));
186}
187
188
191(
192 const word& handlerType,
193 const Tuple2<label, labelList>& commAndIORanks,
194 const bool distributedRoots,
195 bool verbose
196)
197{
198 if (handlerType.empty())
199 {
201 {
203 << "defaultFileHandler name is undefined" << nl
204 << abort(FatalError);
205 }
206
207 // Forward to self
208 return fileOperation::New
209 (
211 commAndIORanks,
212 distributedRoots,
213 verbose
214 );
215 }
216
218 << "Constructing fileHandler: " << handlerType << endl;
219
220 auto* ctorPtr = commConstructorTable(handlerType);
221
222 if (!ctorPtr)
223 {
225 (
226 "fileHandler",
227 handlerType,
228 *commConstructorTablePtr_
229 ) << abort(FatalError);
230 }
231
233 (
234 ctorPtr(commAndIORanks, distributedRoots, verbose)
235 );
236}
237
238
239
240// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
242namespace Foam
243{
244
245// From boolUList/bitSet to list of labels,
246// always include rank 0 and constrain by numProcs
247template<class BoolListType>
248static labelList getSelectedProcs(const BoolListType& useProc)
249{
250 labelList ranks;
251
252 if
253 (
256 )
257 {
259
260 for (const int proci : UPstream::allProcs(UPstream::worldComm))
261 {
262 // Always include the master rank
263 if (!proci || useProc.test(proci))
264 {
265 subProcs.push_back(proci);
266 }
267 }
268
269 ranks.transfer(subProcs);
270 }
271
272 return ranks;
273}
274
275} // End namespace Foam
276
277
278// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
279
281Foam::fileOperation::New_impl
282(
283 const fileOperation& origHandler,
284 const labelUList& subProcs, // in worldComm
285 bool verbose
286)
287{
288 autoPtr<fileOperation> newHandler;
289
290 // NB: input must include master!
291
292 const label myProci = UPstream::myProcNo(UPstream::worldComm);
293 const label numProcs = UPstream::nProcs(UPstream::worldComm);
294
295 if (subProcs.contains(myProci))
296 {
297 // Retaining the original IO ranks if possible
298
299 // Retain the original IO ranks that coincide with the new subset.
300 // This may still need more attention...
301
302 const labelUList& origIOranks = origHandler.ioRanks();
303 DynamicList<label> subIORanks(origIOranks.size());
304
305 for (const label proci : subProcs)
306 {
307 if (origIOranks.contains(proci))
308 {
309 subIORanks.push_back(proci);
310 }
311 }
312
313 // Default starting point
314 Tuple2<label, labelList> commAndIORanks
315 (
317 subIORanks
318 );
319
320 // TBD: special handling for uncollated
321 // if (origHandler.comm() == UPstream::commSelf())
322 // {
323 // commAndIORanks.first() = UPstream::commSelf();
324 // }
325
326 const bool hasIOranks = (commAndIORanks.second().size() > 1);
327
328 if
329 (
331 && (hasIOranks || (subProcs.size() != numProcs))
332 )
333 {
334 // Without any IO range, restrict to overall proc range
335 // since we don't necessarily trust the input...
336 labelRange siblingRange(numProcs);
337
338 if (hasIOranks)
339 {
340 // Multiple masters: ranks included in my IO range
341 siblingRange = fileOperation::subRanks(commAndIORanks.second());
342 }
343
344 // Restrict to siblings within the IO range or proc range
345 labelList siblings;
346 if (siblingRange.size())
347 {
348 auto& dynSiblings = subIORanks;
349 dynSiblings.clear();
350
351 for (const label proci : subProcs)
352 {
353 if (siblingRange.contains(proci))
354 {
355 dynSiblings.push_back(proci);
356 }
357 }
358
359 siblings.transfer(dynSiblings);
360 }
361
362 // Warning: MS-MPI currently uses MPI_Comm_create() instead of
363 // MPI_Comm_create_group() so it will block there!
364
365 commAndIORanks.first() = UPstream::newCommunicator
366 (
368 siblings
369 );
370 }
371
372
373 // Allocate new handler with same type and similar IO ranks
374 // but with different sub-ranks (and communicator)
375
376
377 // Temporarily override world comm to get through the initialisation
378 // (e.g. fileOperation::printRanks() which uses worldComm)
379 const label oldWorldComm = UPstream::commWorld(commAndIORanks.first());
380
381 newHandler = fileOperation::New
382 (
383 origHandler.type(),
384 commAndIORanks,
385 origHandler.distributed(),
386 verbose
387 );
388
389 UPstream::commWorld(oldWorldComm);
390
391 if (newHandler)
392 {
393 // Make sure that the output format uses the correct number of
394 // 'active' ranks (instead of that of the origHandler)
395 newHandler->nProcs(subProcs.size());
396 newHandler->storeComm();
397 }
399
400 return newHandler;
401}
402
403
406(
407 const fileOperation& origHandler,
408 const boolUList& useProc, // in worldComm
409 bool verbose
410)
411{
412 const labelList subProcs = getSelectedProcs(useProc);
413
414 return New_impl(origHandler, subProcs, verbose);
415}
416
417
420(
421 const fileOperation& origHandler,
422 const bitSet& useProc, // in worldComm
423 bool verbose
424)
425{
426 const labelList subProcs = getSelectedProcs(useProc);
427
428 return New_impl(origHandler, subProcs, verbose);
429}
430
431
432// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
433
435Foam::fileHandler(autoPtr<fileOperation>&& newHandler)
436{
437 refPtr<fileOperation> oldHandler
438 (
439 fileOperation::fileHandler(std::move(newHandler))
440 );
441
442 autoPtr<fileOperation> old;
443
444 // Can return as autoPtr if handler was also a pointer (not a reference)
445 if (oldHandler.is_pointer())
446 {
447 old.reset(oldHandler.release());
448 }
449
450 return old;
451}
452
453
454// ************************************************************************* //
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
void push_back(const T &val)
Copy append an element to the end of this list.
void transfer(List< T > &list)
Transfer the contents of the argument List into this list and annul the argument list.
Definition List.C:347
A 2-tuple for storing two objects of dissimilar types. The container is similar in purpose to std::pa...
Definition Tuple2.H:51
static label commWorld() noexcept
Communicator for all ranks (respecting any local worlds).
Definition UPstream.H:1101
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
Definition UPstream.H:1706
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
Definition UPstream.H:1669
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition UPstream.H:1714
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
Definition UPstream.H:1697
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition UPstream.H:1069
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
Definition UPstream.H:1857
static label newCommunicator(const label parent, const labelRange &subRanks, const bool withComponents=true)
Create new communicator with sub-ranks on the parent communicator.
Definition UPstream.C:272
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
Definition autoPtr.H:65
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
Definition autoPtrI.H:37
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
Definition bitSet.H:61
An encapsulation of filesystem-related operations.
static const fileOperation & fileHandler()
Return the current file handler. Will create the default file handler if necessary.
static refPtr< fileOperation > fileHandlerPtr_
The currently active file handler. Avoid accessing directly.
static labelRange subRanks(const labelUList &mainIOranks)
Get (contiguous) range/bounds of ranks addressed within the given main io-ranks.
static word defaultFileHandler
Name of the default fileHandler.
static refPtr< fileOperation > null()
Reference to a dummy file handler.
static autoPtr< fileOperation > NewUncollated()
The commonly used uncollatedFileOperation.
fileOperation(const label comm, const labelUList &ioRanks=labelUList::null(), const bool distributedRoots=false)
Construct from communicator, optionally with specified io-ranks and/or distributed roots.
static autoPtr< fileOperation > New(const word &handlerType, bool verbose=false)
Select fileHandler-type. Uses defaultFileHandler if the handlerType is empty.
Dummy fileOperation, to be used as a placeholder for interfaces taking a reference to a fileOperation...
fileOperation that assumes file operations are local.
A range or interval of labels defined by a start and a size.
Definition labelRange.H:66
A class for managing references or pointers (no reference counting).
Definition refPtr.H:54
T * get() noexcept
Return pointer without nullptr checking.
Definition refPtr.H:249
void swap(refPtr< T > &other) noexcept
Swaps the managed object with other.
Definition refPtrI.H:430
T * release() noexcept
Release ownership and return the pointer. A no-op for reference objects (returns nullptr).
Definition refPtrI.H:266
void reset(T *p=nullptr) noexcept
Delete managed pointer and set to new given pointer.
Definition refPtrI.H:314
A class for handling words, derived from Foam::string.
Definition word.H:66
#define FatalErrorInLookup(lookupTag, lookupName, lookupTable)
Report an error message using Foam::FatalError.
Definition error.H:607
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition error.H:600
#define DebugInFunction
Report an information message using Foam::Info.
Namespace for OpenFOAM.
string getEnv(const std::string &envName)
Get environment value for given envName.
Definition POSIX.C:341
List< label > labelList
A List of labels.
Definition List.H:62
refPtr< fileOperation > fileHandler(std::nullptr_t)
Delete current file handler - forwards to fileOperation::handler().
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition Ostream.H:519
errorManip< error > abort(error &err)
Definition errorManip.H:139
UList< bool > boolUList
A UList of bools.
Definition UList.H:73
static labelList getSelectedProcs(const BoolListType &useProc)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
UList< label > labelUList
A UList of labels.
Definition UList.H:75
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50