UPstream.H
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) 2011-2017 OpenFOAM Foundation
9  Copyright (C) 2015-2016 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Class
28  Foam::UPstream
29 
30 Description
31  Inter-processor communications stream
32 
33 SourceFiles
34  UPstream.C
35  UPstreamCommsStruct.C
36  gatherScatter.C
37  combineGatherScatter.C
38  gatherScatterList.C
39 
40 \*---------------------------------------------------------------------------*/
41 
42 #ifndef UPstream_H
43 #define UPstream_H
44 
45 #include "labelList.H"
46 #include "DynamicList.H"
47 #include "HashTable.H"
48 #include "string.H"
49 #include "Enum.H"
50 #include "ListOps.H"
51 #include "LIFOStack.H"
52 
53 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
54 
55 namespace Foam
56 {
57 
58 /*---------------------------------------------------------------------------*\
59  Class UPstream Declaration
60 \*---------------------------------------------------------------------------*/
61 
62 class UPstream
63 {
64 public:
65 
66  //- Types of communications
67  enum class commsTypes
68  {
69  blocking,
70  scheduled,
72  };
73 
74  //- Names of the communication types
75  static const Enum<commsTypes> commsTypeNames;
76 
77 
78  // Public classes
79 
80  //- Structure for communicating between processors
81  class commsStruct
82  {
83  // Private data
84 
85  //- procID of above processor
86  label above_;
87 
88  //- procIDs of processors directly below me
89  labelList below_;
90 
91  //- procIDs of all processors below (so not just directly below)
92  labelList allBelow_;
93 
94  //- procIDs of all processors not below.
95  // (inverse set of allBelow_ and minus myProcNo)
96  labelList allNotBelow_;
97 
98 
99  public:
100 
101  // Constructors
102 
103  //- Construct null
104  commsStruct();
105 
106  //- Construct from components
108  (
109  const label above,
110  const labelList& below,
111  const labelList& allBelow,
112  const labelList& allNotBelow
113  );
114 
115  //- Construct from components; construct allNotBelow_
117  (
118  const label nProcs,
119  const label myProcID,
120  const label above,
121  const labelList& below,
122  const labelList& allBelow
123  );
124 
125 
126  // Member Functions
127 
128  // Access
129 
130  label above() const
131  {
132  return above_;
133  }
134 
135  const labelList& below() const
136  {
137  return below_;
138  }
139 
140  const labelList& allBelow() const
141  {
142  return allBelow_;
143  }
144 
145  const labelList& allNotBelow() const
146  {
147  return allNotBelow_;
148  }
149 
150 
151  // Member operators
152 
153  bool operator==(const commsStruct&) const;
154 
155  bool operator!=(const commsStruct&) const;
156 
157 
158  // Ostream Operator
159 
160  friend Ostream& operator<<(Ostream&, const commsStruct&);
161  };
162 
163 
164  //- combineReduce operator for lists. Used for counting.
165  struct listEq
166  {
167  template<class T>
168  void operator()(T& x, const T& y) const
169  {
170  forAll(y, i)
171  {
172  if (y[i].size())
173  {
174  x[i] = y[i];
175  }
176  }
177  }
178  };
179 
180 
181 private:
182 
183  // Private data
184 
185  //- By default this is not a parallel run
186  static bool parRun_;
187 
188  //- Have support for threads?
189  static bool haveThreads_;
190 
191  //- Standard transfer message type
192  static int msgType_;
193 
194  // Communicator specific data
195 
196  //- Free communicators
197  static LIFOStack<label> freeComms_;
198 
199  //- My processor number
200  static DynamicList<int> myProcNo_;
201 
202  //- List of process IDs
203  static DynamicList<List<int>> procIDs_;
204 
205  //- Parent communicator
206  static DynamicList<label> parentCommunicator_;
207 
208  //- Linear communication schedule
209  static DynamicList<List<commsStruct>> linearCommunication_;
210 
211  //- Multi level communication schedule
212  static DynamicList<List<commsStruct>> treeCommunication_;
213 
214 
215  // Private Member Functions
216 
217  //- Set data for parallel running
218  static void setParRun(const label nProcs, const bool haveThreads);
219 
220  //- Calculate linear communication schedule
221  static List<commsStruct> calcLinearComm(const label nProcs);
222 
223  //- Calculate tree communication schedule
224  static List<commsStruct> calcTreeComm(const label nProcs);
225 
226  //- Helper function for tree communication schedule determination
227  // Collects all processorIDs below a processor
228  static void collectReceives
229  (
230  const label procID,
231  const List<DynamicList<label>>& receives,
232  DynamicList<label>& allReceives
233  );
234 
235  //- Allocate a communicator with index
236  static void allocatePstreamCommunicator
237  (
238  const label parentIndex,
239  const label index
240  );
241 
242  //- Free a communicator
243  static void freePstreamCommunicator
244  (
245  const label index
246  );
247 
248 
249 protected:
250 
251  // Protected data
252 
253  //- Communications type of this stream
255 
256 public:
257 
258  // Declare name of the class and its debug switch
259  ClassName("UPstream");
260 
261 
262  // Static data
263 
264  //- Should compact transfer be used in which floats replace doubles
265  //- reducing the bandwidth requirement at the expense of some loss
266  //- in accuracy
267  static bool floatTransfer;
268 
269  //- Number of processors at which the sum algorithm changes from linear
270  //- to tree
271  static int nProcsSimpleSum;
272 
273  //- Default commsType
275 
276  //- Number of polling cycles in processor updates
277  static int nPollProcInterfaces;
278 
279  //- Optional maximum message size (bytes)
280  static int maxCommsSize;
281 
282  //- MPI buffer-size (bytes)
283  static const int mpiBufferSize;
284 
285  //- Default communicator (all processors)
286  static label worldComm;
287 
288  //- Debugging: warn for use of any communicator differing from warnComm
289  static label warnComm;
290 
291 
292  // Constructors
293 
294  //- Construct given optional buffer size
296  :
298  {}
299 
300 
301  // Member functions
302 
303  //- Allocate a new communicator
305  (
306  const label parent,
307  const labelList& subRanks,
308  const bool doPstream = true
309  );
310 
311  //- Free a previously allocated communicator
312  static void freeCommunicator
313  (
314  const label communicator,
315  const bool doPstream = true
316  );
317 
318  //- Free all communicators
319  static void freeCommunicators(const bool doPstream);
320 
321  //- Helper class for allocating/freeing communicators
322  class communicator
323  {
324  label comm_;
325 
326  //- No copy construct
327  communicator(const communicator&) = delete;
328 
329  //- No copy assignment
330  void operator=(const communicator&) = delete;
331 
332  public:
333 
335  (
336  const label parent,
337  const labelList& subRanks,
338  const bool doPstream
339  )
340  :
341  comm_(allocateCommunicator(parent, subRanks, doPstream))
342  {}
343 
344  ~communicator()
345  {
346  freeCommunicator(comm_);
347  }
348 
349  operator label() const
350  {
351  return comm_;
352  }
353  };
354 
355  //- Return physical processor number (i.e. processor number in
356  //- worldComm) given communicator and procssor
357  static int baseProcNo(const label myComm, const int procID);
358 
359  //- Return processor number in communicator (given physical processor
360  //- number) (= reverse of baseProcNo)
361  static label procNo(const label comm, const int baseProcID);
362 
363  //- Return processor number in communicator (given processor number
364  //- and communicator)
365  static label procNo
366  (
367  const label myComm,
368  const label currentComm,
369  const int currentProcID
370  );
371 
372  //- Add the valid option this type of communications library
373  //- adds/requires on the command line
374  static void addValidParOptions(HashTable<string>& validParOptions);
375 
376  //- Initialisation function called from main
377  // Spawns slave processes and initialises inter-communication
378  static bool init(int& argc, char**& argv, const bool needsThread);
379 
380  //- Special purpose initialisation function.
381  // Performs a basic MPI_Init without any other setup.
382  // Only used for applications that need MPI communication when
383  // OpenFOAM is running in a non-parallel mode.
384  // \note Behaves as a no-op if MPI has already been initialized.
385  // Fatal if MPI has already been finalized.
386  static bool initNull();
387 
388  // Non-blocking comms
389 
390  //- Get number of outstanding requests
391  static label nRequests();
392 
393  //- Truncate number of outstanding requests
394  static void resetRequests(const label sz);
395 
396  //- Wait until all requests (from start onwards) have finished.
397  static void waitRequests(const label start = 0);
398 
399  //- Wait until request i has finished.
400  static void waitRequest(const label i);
401 
402  //- Non-blocking comms: has request i finished?
403  static bool finishedRequest(const label i);
404 
405  static int allocateTag(const char*);
406 
407  static int allocateTag(const word&);
408 
409  static void freeTag(const char*, const int tag);
410 
411  static void freeTag(const word&, const int tag);
412 
413 
414  //- Is this a parallel run?
415  static bool& parRun()
416  {
417  return parRun_;
418  }
419 
420  //- Have support for threads
421  static bool haveThreads()
422  {
423  return haveThreads_;
424  }
425 
426  //- Number of processes in parallel run
427  static label nProcs(const label communicator = 0)
428  {
429  return procIDs_[communicator].size();
430  }
431 
432  //- Process index of the master
433  static constexpr int masterNo() noexcept
434  {
435  return 0;
436  }
437 
438  //- Am I the master process
439  static bool master(const label communicator = 0)
440  {
441  return myProcNo_[communicator] == masterNo();
442  }
443 
444  //- Number of this process (starting from masterNo() = 0)
445  static int myProcNo(const label communicator = 0)
446  {
447  return myProcNo_[communicator];
448  }
449 
450  static label parent(const label communicator)
451  {
452  return parentCommunicator_(communicator);
453  }
454 
455  //- Process ID of given process index
457  {
458  return procIDs_[communicator];
459  }
460 
461  //- Process index of first slave
462  static constexpr int firstSlave() noexcept
463  {
464  return 1;
465  }
466 
467  //- Process index of last slave
468  static int lastSlave(const label communicator = 0)
469  {
470  return nProcs(communicator) - 1;
471  }
472 
473  //- Communication schedule for linear all-to-master (proc 0)
475  (
476  const label communicator = 0
477  )
478  {
479  return linearCommunication_[communicator];
480  }
481 
482  //- Communication schedule for tree all-to-master (proc 0)
484  (
485  const label communicator = 0
486  )
487  {
488  return treeCommunication_[communicator];
489  }
490 
491  //- Message tag of standard messages
492  static int& msgType()
493  {
494  return msgType_;
495  }
496 
497 
498  //- Get the communications type of the stream
499  commsTypes commsType() const
500  {
501  return commsType_;
502  }
503 
504  //- Set the communications type of the stream
506  {
507  commsTypes oldCommsType = commsType_;
508  commsType_ = ct;
509  return oldCommsType;
510  }
511 
512 
513  //- Exit program
514  static void exit(int errnum = 1);
515 
516  //- Abort program
517  static void abort();
518 
519  //- Exchange label with all processors (in the communicator).
520  // sendData[proci] is the label to send to proci.
521  // After return recvData contains the data from the other processors.
522  static void allToAll
523  (
524  const labelUList& sendData,
525  labelUList& recvData,
526  const label communicator = 0
527  );
528 
529  //- Exchange data with all processors (in the communicator)
530  // sendSizes, sendOffsets give (per processor) the slice of
531  // sendData to send, similarly recvSizes, recvOffsets give the slice
532  // of recvData to receive
533  static void allToAll
534  (
535  const char* sendData,
536  const UList<int>& sendSizes,
537  const UList<int>& sendOffsets,
538 
539  char* recvData,
540  const UList<int>& recvSizes,
541  const UList<int>& recvOffsets,
542 
543  const label communicator = 0
544  );
545 
546  //- Receive data from all processors on the master
547  static void gather
548  (
549  const char* sendData,
550  int sendSize,
551 
552  char* recvData,
553  const UList<int>& recvSizes,
554  const UList<int>& recvOffsets,
555  const label communicator = 0
556  );
557 
558  //- Send data to all processors from the root of the communicator
559  static void scatter
560  (
561  const char* sendData,
562  const UList<int>& sendSizes,
563  const UList<int>& sendOffsets,
564 
565  char* recvData,
566  int recvSize,
567  const label communicator = 0
568  );
569 };
570 
571 
572 Ostream& operator<<(Ostream&, const UPstream::commsStruct&);
573 
574 // Template specialisation for access of commsStruct
575 template<>
576 UPstream::commsStruct&
578 
579 template<>
580 const UPstream::commsStruct&
582 
583 
584 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
585 
586 } // End namespace Foam
587 
588 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
589 
590 #endif
591 
592 // ************************************************************************* //
Foam::UPstream::allocateTag
static int allocateTag(const char *)
Definition: UPstream.C:997
Foam::UPstream::warnComm
static label warnComm
Debugging: warn for use of any communicator differing from warnComm.
Definition: UPstream.H:288
Foam::UPstream::commsTypes::blocking
Foam::UPstream::resetRequests
static void resetRequests(const label sz)
Truncate number of outstanding requests.
Definition: UPstream.C:158
Foam::UPstream::commsTypes::nonBlocking
Foam::Enum< commsTypes >
Foam::UPstream::masterNo
static constexpr int masterNo() noexcept
Process index of the master.
Definition: UPstream.H:432
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:62
HashTable.H
Foam::UPstream::communicator::~communicator
~communicator()
Definition: UPstream.H:343
Foam::UPstream::commsStruct::commsStruct
commsStruct()
Construct null.
Definition: UPstreamCommsStruct.C:33
Foam::UPstream::baseProcNo
static int baseProcNo(const label myComm, const int procID)
Definition: UPstream.C:205
Foam::UPstream::haveThreads
static bool haveThreads()
Have support for threads.
Definition: UPstream.H:420
Foam::DynamicList< int >
Foam::UPstream::exit
static void exit(int errnum=1)
Exit program.
Definition: UPstream.C:59
Foam::UPstream::nProcs
static label nProcs(const label communicator=0)
Number of processes in parallel run.
Definition: UPstream.H:426
Foam::UPstream::parRun
static bool & parRun()
Is this a parallel run?
Definition: UPstream.H:414
Foam::UPstream::listEq
combineReduce operator for lists. Used for counting.
Definition: UPstream.H:164
Foam::UPstream::commsStruct::operator<<
friend Ostream & operator<<(Ostream &, const commsStruct &)
Foam::UPstream::waitRequests
static void waitRequests(const label start=0)
Wait until all requests (from start onwards) have finished.
Definition: UPstream.C:162
string.H
Foam::UPstream::abort
static void abort()
Abort program.
Definition: UPstream.C:66
Foam::UPstream::defaultCommsType
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:273
Foam::UPstream::allToAll
static void allToAll(const labelUList &sendData, labelUList &recvData, const label communicator=0)
Exchange label with all processors (in the communicator).
Definition: UPstream.C:100
Foam::UPstream::gather
static void gather(const char *sendData, int sendSize, char *recvData, const UList< int > &recvSizes, const UList< int > &recvOffsets, const label communicator=0)
Receive data from all processors on the master.
Definition: UPstream.C:111
Foam::UPstream::UPstream
UPstream(const commsTypes commsType)
Construct given optional buffer size.
Definition: UPstream.H:294
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:290
Foam::UPstream::commsStruct::operator==
bool operator==(const commsStruct &) const
Definition: UPstreamCommsStruct.C:95
Foam::UPstream::commsStruct::allBelow
const labelList & allBelow() const
Definition: UPstream.H:139
Foam::UPstream::mpiBufferSize
static const int mpiBufferSize
MPI buffer-size (bytes)
Definition: UPstream.H:282
Foam::UPstream::allocateCommunicator
static label allocateCommunicator(const label parent, const labelList &subRanks, const bool doPstream=true)
Allocate a new communicator.
Definition: UPstream.C:100
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:62
Foam::UPstream
Inter-processor communications stream.
Definition: UPstream.H:61
labelList.H
Foam::UPstream::lastSlave
static int lastSlave(const label communicator=0)
Process index of last slave.
Definition: UPstream.H:467
Foam::UPstream::floatTransfer
static bool floatTransfer
Definition: UPstream.H:266
Foam::T
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
Definition: FieldFieldFunctions.C:58
Foam::UPstream::waitRequest
static void waitRequest(const label i)
Wait until request i has finished.
Definition: UPstream.C:166
Foam::UPstream::commsType
commsTypes commsType() const
Get the communications type of the stream.
Definition: UPstream.H:498
Foam::UPstream::addValidParOptions
static void addValidParOptions(HashTable< string > &validParOptions)
Definition: UPstream.C:34
Foam::UPstream::procID
static List< int > & procID(label communicator)
Process ID of given process index.
Definition: UPstream.H:455
Foam::UPstream::freeCommunicator
static void freeCommunicator(const label communicator, const bool doPstream=true)
Free a previously allocated communicator.
Definition: UPstream.C:166
Foam::UPstream::commsTypeNames
static const Enum< commsTypes > commsTypeNames
Names of the communication types.
Definition: UPstream.H:74
Foam::UPstream::commsTypes::scheduled
Foam::UPstream::scatter
static void scatter(const char *sendData, const UList< int > &sendSizes, const UList< int > &sendOffsets, char *recvData, int recvSize, const label communicator=0)
Send data to all processors from the root of the communicator.
Definition: UPstream.C:126
Foam::UPstream::commsStruct::allNotBelow
const labelList & allNotBelow() const
Definition: UPstream.H:144
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::UPstream::commsStruct::above
label above() const
Definition: UPstream.H:129
Foam::UPstream::commsStruct
Structure for communicating between processors.
Definition: UPstream.H:80
Foam::UPstream::myProcNo
static int myProcNo(const label communicator=0)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:444
Foam::UPstream::master
static bool master(const label communicator=0)
Am I the master process.
Definition: UPstream.H:438
Foam::UPstream::nProcsSimpleSum
static int nProcsSimpleSum
Definition: UPstream.H:270
Foam::UPstream::firstSlave
static constexpr int firstSlave() noexcept
Process index of first slave.
Definition: UPstream.H:461
Foam::HashTable
A HashTable similar to std::unordered_map.
Definition: HashTable.H:105
Foam::UPstream::msgType
static int & msgType()
Message tag of standard messages.
Definition: UPstream.H:491
Foam::UPstream::commsTypes
commsTypes
Types of communications.
Definition: UPstream.H:66
Foam::UPstream::nRequests
static label nRequests()
Get number of outstanding requests.
Definition: UPstream.C:152
Foam::UPstream::listEq::operator()
void operator()(T &x, const T &y) const
Definition: UPstream.H:167
Foam::UPstream::commsType_
commsTypes commsType_
Communications type of this stream.
Definition: UPstream.H:253
Foam::UPstream::initNull
static bool initNull()
Special purpose initialisation function.
Definition: UPstream.C:38
Foam::UPstream::maxCommsSize
static int maxCommsSize
Optional maximum message size (bytes)
Definition: UPstream.H:279
Foam::UPstream::worldComm
static label worldComm
Default communicator (all processors)
Definition: UPstream.H:285
Foam::List< label >
Foam::UList::operator[]
T & operator[](const label i)
Return element of UList.
Definition: UListI.H:246
Foam::start
label ListType::const_reference const label start
Definition: ListOps.H:408
Foam::UPstream::procNo
static label procNo(const label comm, const int baseProcID)
Definition: UPstream.C:221
Foam::UList< label >
Foam::UPstream::ClassName
ClassName("UPstream")
Foam::UPstream::commsType
commsTypes commsType(const commsTypes ct)
Set the communications type of the stream.
Definition: UPstream.H:504
Foam::UPstream::finishedRequest
static bool finishedRequest(const label i)
Non-blocking comms: has request i finished?
Definition: UPstream.C:170
x
x
Definition: LISASMDCalcMethod2.H:52
Foam::UPstream::freeCommunicators
static void freeCommunicators(const bool doPstream)
Free all communicators.
Definition: UPstream.C:193
DynamicList.H
ListOps.H
Various functions to operate on Lists.
Foam::Ostream
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
Definition: Ostream.H:56
Foam::UPstream::parent
static label parent(const label communicator)
Definition: UPstream.H:449
Foam::UPstream::communicator
Helper class for allocating/freeing communicators.
Definition: UPstream.H:321
Foam::UPstream::linearCommunication
static const List< commsStruct > & linearCommunication(const label communicator=0)
Communication schedule for linear all-to-master (proc 0)
Definition: UPstream.H:474
Foam::LIFOStack< label >
Foam::UPstream::init
static bool init(int &argc, char **&argv, const bool needsThread)
Initialisation function called from main.
Definition: UPstream.C:48
Foam::UPstream::commsStruct::operator!=
bool operator!=(const commsStruct &) const
Definition: UPstreamCommsStruct.C:107
LIFOStack.H
Foam::operator<<
Ostream & operator<<(Ostream &, const boundaryPatch &)
Definition: boundaryPatch.C:102
Foam::UPstream::nPollProcInterfaces
static int nPollProcInterfaces
Number of polling cycles in processor updates.
Definition: UPstream.H:276
Foam::UPstream::commsStruct::below
const labelList & below() const
Definition: UPstream.H:134
Foam::UPstream::treeCommunication
static const List< commsStruct > & treeCommunication(const label communicator=0)
Communication schedule for tree all-to-master (proc 0)
Definition: UPstream.H:483
y
scalar y
Definition: LISASMDCalcMethod1.H:14
Enum.H
Foam::UPstream::freeTag
static void freeTag(const char *, const int tag)
Definition: UPstream.C:1055