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-2023 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  UPstreamTemplates.C
37 
38 \*---------------------------------------------------------------------------*/
39 
40 #ifndef Foam_UPstream_H
41 #define Foam_UPstream_H
42 
43 #include "wordList.H"
44 #include "labelList.H"
45 #include "DynamicList.H"
46 #include "HashTable.H"
47 #include "Map.H"
48 #include "Enum.H"
49 #include "ListOps.H"
50 
51 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
52 
53 namespace Foam
54 {
55 
56 //- Implementation details for UPstream/Pstream/MPI etc.
57 namespace PstreamDetail {}
58 
59 /*---------------------------------------------------------------------------*\
60  Class UPstream Declaration
61 \*---------------------------------------------------------------------------*/
62 
63 class UPstream
64 {
65 public:
66 
67  //- Int ranges are used for MPI ranks (processes)
68  typedef IntRange<int> rangeType;
69 
70  //- Communications types
71  enum class commsTypes : char
72  {
73  blocking,
74  scheduled,
76  };
77 
78  //- Enumerated names for the communication types
79  static const Enum<commsTypes> commsTypeNames;
80 
81  //- Different MPI-send modes (ignored for commsTypes::blocking)
82  enum class sendModes : char
83  {
84  normal,
85  sync
86  };
87 
88 
89  // Public Classes
90 
91  //- Wrapper for MPI_Request
92  class Request; // Forward Declaration
93 
94  //- Structure for communicating between processors
95  class commsStruct
96  {
97  // Private Data
98 
99  //- The procID of the processor \em directly above
100  label above_;
101 
102  //- The procIDs of processors \em directly below
103  labelList below_;
105  //- The procIDs of all processors below myProcNo,
106  //- not just directly below
107  labelList allBelow_;
108 
109  //- The procIDs of all processors not below myProcNo
110  // (inverse of allBelow_ without myProcNo)
111  labelList allNotBelow_;
112 
113 
114  public:
115 
116  // Constructors
117 
118  //- Default construct with above == -1
119  commsStruct() noexcept : above_(-1) {}
120 
121  //- Move construct from components
123  (
124  const label above,
125  labelList&& below,
128  );
129 
130  //- Copy construct from below, allBelow components
132  (
133  const label numProcs,
134  const label myProcID,
135  const label above,
136  const labelUList& below,
137  const labelUList& allBelow
138  );
140 
141  // Member Functions
142 
143  //- Print un-directed graph in graphviz dot format
144  static void printGraph
145  (
146  Ostream& os,
147  const UList<UPstream::commsStruct>& comms,
148  const label proci = 0 // starting node
149  );
150 
151 
152  // Access
153 
154  //- The number of processors addressed by the structure
155  label nProcs() const;
156 
157  //- The procID of the processor \em directly above
158  label above() const noexcept { return above_; }
159 
160  //- The procIDs of the processors \em directly below
161  const labelList& below() const noexcept { return below_; }
162 
163  //- The procIDs of all processors below
164  //- (so not just directly below)
165  const labelList& allBelow() const noexcept { return allBelow_; }
166 
167  //- The procIDs of all processors not below myProcNo.
168  //- The inverse set of allBelow without myProcNo.
169  const labelList& allNotBelow() const noexcept
170  {
171  return allNotBelow_;
172  }
173 
174 
175  // Edit
176 
177  //- Reset to default constructed state
178  void reset();
179 
180  //- Reset with automatic linear/tree selection
181  void reset(const label procID, const label numProcs);
182 
183 
184  // Member / Friend Operators
185 
186  bool operator==(const commsStruct&) const;
187  bool operator!=(const commsStruct&) const;
189  friend Ostream& operator<<(Ostream&, const commsStruct&);
190  };
191 
192 
193 private:
194 
195  // Private Data
196 
197  //- Communications type of this stream
198  commsTypes commsType_;
200 
201  // Private Static Data
202 
203  //- By default this is not a parallel run
204  static bool parRun_;
206  //- Have support for threads?
207  static bool haveThreads_;
208 
209  //- Standard transfer message type
210  static int msgType_;
211 
212  //- Names of all worlds
213  static wordList allWorlds_;
214 
215  //- Per processor the world index (into allWorlds_)
216  static labelList worldIDs_;
217 
218  //- Intra-host communicator
219  static label intraHostComm_;
220 
221  //- Inter-host communicator (between host leaders)
222  static label interHostComm_;
223 
224 
225  // Communicator specific data
226 
227  //- My processor number
228  static DynamicList<int> myProcNo_;
229 
230  //- List of process IDs
231  static DynamicList<List<int>> procIDs_;
232 
233  //- Parent communicator
234  static DynamicList<label> parentComm_;
235 
236  //- Free communicators
237  static DynamicList<label> freeComms_;
238 
239  //- Linear communication schedule
240  static DynamicList<List<commsStruct>> linearCommunication_;
241 
242  //- Multi level communication schedule
243  static DynamicList<List<commsStruct>> treeCommunication_;
244 
245 
246  // Private Member Functions
247 
248  //- Set data for parallel running
249  static void setParRun(const label nProcs, const bool haveThreads);
250 
251  //- Initialise entries for new communicator. Return the index
252  static label getAvailableCommIndex(const label parentIndex);
253 
254  //- Allocate MPI components of communicator with given index
255  static void allocateCommunicatorComponents
256  (
257  const label parentIndex,
258  const label index
259  );
260 
261  //- Free MPI components of communicator.
262  // Does not touch the first two communicators (SELF, WORLD)
263  static void freeCommunicatorComponents(const label index);
264 
265  //- Allocate inter-host, intra-host communicators
266  //- with comm-world as parent
267  static bool allocateHostCommunicatorPairs();
268 
269 
270 public:
271 
272  //- Declare name of the class and its debug switch
273  ClassName("UPstream");
274 
275 
276  // Static Data
277 
278  //- Should compact transfer be used in which floats replace doubles
279  //- reducing the bandwidth requirement at the expense of some loss
280  //- in accuracy
281  static bool floatTransfer;
282 
283  //- Number of processors to change from linear to tree communication
284  static int nProcsSimpleSum;
285 
286  //- Number of processors to change to nonBlocking consensual
287  //- exchange (NBX). Ignored for zero or negative values.
288  static int nProcsNonblockingExchange;
289 
290  //- Number of polling cycles in processor updates
291  static int nPollProcInterfaces;
292 
293  //- Default commsType
295 
296  //- Optional maximum message size (bytes)
297  static int maxCommsSize;
298 
299  //- Tuning parameters for non-blocking exchange (NBX)
300  static int tuning_NBX_;
301 
302  //- MPI buffer-size (bytes)
303  static const int mpiBufferSize;
304 
305 
306  // Standard Communicators
307 
308  //- Communicator for all ranks.
309  //- May differ from commGlobal() if local worlds are in use
310  static label worldComm;
311 
312  //- Debugging: warn for use of any communicator differing from warnComm
313  static label warnComm;
314 
315  //- Communicator for all ranks, irrespective of any local worlds
316  static constexpr label commGlobal() noexcept { return 0; }
317 
318  //- Communicator within the current rank only
319  static constexpr label commSelf() noexcept { return 1; }
320 
321  //- Communicator for all ranks (respecting any local worlds)
322  static label commWorld() noexcept { return worldComm; }
323 
324  //- Set world communicator. Negative values are a no-op.
325  // \returns old world communicator index
326  static label commWorld(const label communicator) noexcept
327  {
328  label old(worldComm);
329  if (communicator >= 0) worldComm = communicator;
330  return old;
331  }
332 
333  //- Alter communicator debugging setting.
334  //- Warns for use of any communicator differing from specified.
335  // \returns the previous warn index
336  static label commWarn(const label communicator) noexcept
337  {
338  label old(warnComm);
339  warnComm = communicator;
340  return old;
341  }
342 
343  //- Number of currently defined communicators
344  static label nComms() noexcept { return parentComm_.size(); }
345 
346  //- Debugging: print the communication tree
347  static void printCommTree(const label communicator);
348 
349 
350  // Host Communicators
351 
352  //- Demand-driven: Intra-host communicator (respects any local worlds)
353  static label commIntraHost();
354 
355  //- Demand-driven: Inter-host communicator (respects any local worlds)
356  static label commInterHost();
357 
358  //- Test for presence of any intra or inter host communicators
359  static bool hasHostComms();
360 
361  //- Remove any existing intra and inter host communicators
362  static void clearHostComms();
363 
365  // Constructors
366 
367  //- Construct for given communication type
368  explicit UPstream(const commsTypes commsType) noexcept
369  :
370  commsType_(commsType)
371  {}
372 
373 
374  // Member Functions
376  //- Allocate new communicator with contiguous sub-ranks
377  //- on the parent communicator.
378  static label allocateCommunicator
379  (
381  const label parent,
382 
384  const labelRange& subRanks,
387  const bool withComponents = true
388  );
389 
390  //- Allocate new communicator with sub-ranks on the parent communicator
391  static label allocateCommunicator
392  (
394  const label parent,
397  const labelUList& subRanks,
398 
400  const bool withComponents = true
401  );
402 
403  //- Free a previously allocated communicator.
404  // Ignores placeholder (negative) communicators.
405  static void freeCommunicator
406  (
407  const label communicator,
408  const bool withComponents = true
409  );
410 
411  //- Allocate an inter-host communicator
412  static label allocateInterHostCommunicator
413  (
414  const label parentCommunicator = worldComm
415  );
416 
417  //- Allocate an intra-host communicator
418  static label allocateIntraHostCommunicator
419  (
420  const label parentCommunicator = worldComm
421  );
422 
423 
424  //- Wrapper class for allocating/freeing communicators. Always invokes
425  //- allocateCommunicatorComponents() and freeCommunicatorComponents()
426  class communicator
427  {
428  label comm_;
430  public:
431 
432  //- No copy construct
433  communicator(const communicator&) = delete;
434 
435  //- No copy assignment
436  void operator=(const communicator&) = delete;
437 
438  //- Default construct (a placeholder communicator)
439  communicator() noexcept : comm_(-1) {}
440 
441  //- Move construct, takes ownership
442  communicator(communicator&& c) : comm_(c.comm_) { c.comm_ = -1; }
443 
444  //- Allocate communicator for contiguous sub-ranks on given parent
446  (
448  const label parentComm,
451  const labelRange& subRanks
452  )
453  :
454  comm_(UPstream::allocateCommunicator(parentComm, subRanks))
455  {}
456 
457  //- Allocate communicator for sub-ranks on given parent
459  (
461  const label parentComm,
462 
464  const labelUList& subRanks
465  )
466  :
467  comm_(UPstream::allocateCommunicator(parentComm, subRanks))
468  {}
469 
470  //- Free allocated communicator
472 
473  //- True if communicator is non-negative (ie, was allocated)
474  bool good() const noexcept { return (comm_ >= 0); }
475 
476  //- The communicator label
477  label comm() const noexcept { return comm_; }
478 
479  //- Release ownership of the communicator, return old value.
480  // Leave further management to the caller
481  label release() noexcept { label c(comm_); comm_ = -1; return c; }
482 
483  //- Free allocated communicator
484  void reset() { UPstream::freeCommunicator(comm_); comm_ = -1; }
485 
486  //- Allocate with contiguous sub-ranks of parent communicator
487  void reset(label parent, const labelRange& subRanks)
488  {
490  comm_ = UPstream::allocateCommunicator(parent, subRanks);
491  }
492 
493  //- Allocate with sub-ranks of parent communicator
494  void reset(label parent, const labelUList& subRanks)
495  {
497  comm_ = UPstream::allocateCommunicator(parent, subRanks);
498  }
499 
500  //- Take ownership, free allocated communicator
501  // \caution do not call as self-assignment
502  void reset(communicator&& c)
503  {
504  if (comm_ != c.comm_) UPstream::freeCommunicator(comm_);
505  comm_ = c.comm_;
506  c.comm_ = -1;
507  }
508 
509  //- Move assignment, takes ownership
510  // \caution do not call as self-assignment
511  void operator=(communicator&& c) { reset(std::move(c)); }
512 
513  //- Cast to label - the same as comm()
514  operator label() const noexcept { return comm_; }
515  };
516 
517 
518  //- Return physical processor number (i.e. processor number in
519  //- worldComm) given communicator and processor
520  static int baseProcNo(label comm, int procID);
521 
522  //- Return processor number in communicator (given physical processor
523  //- number) (= reverse of baseProcNo)
524  static label procNo(const label comm, const int baseProcID);
525 
526  //- Return processor number in communicator (given processor number
527  //- and communicator)
528  static label procNo
529  (
530  const label comm,
531  const label currentComm,
532  const int currentProcID
533  );
534 
535  //- Add the valid option this type of communications library
536  //- adds/requires on the command line
537  static void addValidParOptions(HashTable<string>& validParOptions);
538 
539  //- Initialisation function called from main
540  // Spawns sub-processes and initialises inter-communication
541  static bool init(int& argc, char**& argv, const bool needsThread);
542 
543  //- Special purpose initialisation function.
544  // Performs a basic MPI_Init without any other setup.
545  // Only used for applications that need MPI communication when
546  // OpenFOAM is running in a non-parallel mode.
547  // \note Behaves as a no-op if MPI has already been initialized.
548  // Fatal if MPI has already been finalized.
549  static bool initNull();
550 
551  //- Impose a synchronisation barrier (optionally non-blocking)
552  static void barrier
553  (
554  const label communicator,
555  UPstream::Request* req = nullptr
556  );
557 
558  //- Probe for an incoming message.
559  //
560  // \param commsType Blocking or not
561  // \param fromProcNo The source rank (negative == ANY_SOURCE)
562  // \param tag The source message tag
563  // \param communicator The communicator index
564  //
565  // \returns source rank and message size (bytes)
566  // and (-1, 0) on failure
567  static std::pair<int,int> probeMessage
568  (
570  const int fromProcNo,
571  const int tag = UPstream::msgType(),
572  const label communicator = worldComm
573  );
574 
575 
576  // Requests (non-blocking comms).
577  // Pending requests are usually handled as an internal (global) list,
578  // since this simplifies the overall tracking and provides a convenient
579  // wrapping to avoid exposing MPI-specific types, but can also handle
580  // with a wrapped UPstream::Request as well.
581 
582  //- Number of outstanding requests (on the internal list of requests)
583  static label nRequests() noexcept;
584 
585  //- Truncate outstanding requests to given length, which is
586  //- expected to be in the range [0 to nRequests()].
587  // A no-op for out-of-range values.
588  static void resetRequests(const label n);
589 
590  //- Transfer the (wrapped) MPI request to the internal global list.
591  // A no-op for non-parallel. No special treatment for null requests.
592  static void addRequest(UPstream::Request& req);
593 
594  //- Non-blocking comms: cancel and free outstanding request.
595  //- Corresponds to MPI_Cancel() + MPI_Request_free()
596  // A no-op if parRun() == false
597  // if there are no pending requests,
598  // or if the index is out-of-range (0 to nRequests)
599  static void cancelRequest(const label i);
600 
601  //- Non-blocking comms: cancel and free outstanding request.
602  //- Corresponds to MPI_Cancel() + MPI_Request_free()
603  // A no-op if parRun() == false
604  static void cancelRequest(UPstream::Request& req);
605 
606  //- Non-blocking comms: cancel and free outstanding requests.
607  //- Corresponds to MPI_Cancel() + MPI_Request_free()
608  // A no-op if parRun() == false or list is empty
609  static void cancelRequests(UList<UPstream::Request>& requests);
610 
611  //- Non-blocking comms: cancel/free outstanding requests
612  //- (from position onwards) and remove from internal list of requests.
613  //- Corresponds to MPI_Cancel() + MPI_Request_free()
614  // A no-op if parRun() == false,
615  // if the position is out-of-range [0 to nRequests()],
616  // or the internal list of requests is empty.
617  //
618  // \param pos starting position within the internal list of requests
619  // \param len length of slice to remove (negative = until the end)
620  static void removeRequests(const label pos, label len = -1);
621 
622  //- Non-blocking comms: free outstanding request.
623  //- Corresponds to MPI_Request_free()
624  // A no-op if parRun() == false
625  static void freeRequest(UPstream::Request& req);
626 
627  //- Non-blocking comms: free outstanding requests.
628  //- Corresponds to MPI_Request_free()
629  // A no-op if parRun() == false or list is empty
630  static void freeRequests(UList<UPstream::Request>& requests);
631 
632  //- Wait until all requests (from position onwards) have finished.
633  //- Corresponds to MPI_Waitall()
634  // A no-op if parRun() == false,
635  // if the position is out-of-range [0 to nRequests()],
636  // or the internal list of requests is empty.
637  //
638  // If checking a trailing portion of the list, it will also trim
639  // the list of outstanding requests as a side-effect.
640  // This is a feature (not a bug) to conveniently manange the list.
641  //
642  // \param pos starting position within the internal list of requests
643  // \param len length of slice to check (negative = until the end)
644  static void waitRequests(const label pos, label len = -1);
645 
646  //- Wait until all requests have finished.
647  //- Corresponds to MPI_Waitall()
648  // A no-op if parRun() == false, or the list is empty.
649  static void waitRequests(UList<UPstream::Request>& requests);
650 
651  //- Wait until any request (from position onwards) has finished.
652  //- Corresponds to MPI_Waitany()
653  // A no-op and returns false if parRun() == false,
654  // if the position is out-of-range [0 to nRequests()],
655  // or the internal list of requests is empty.
656  //
657  // \returns true if any pending request completed.
658  // \returns false if all requests have already been handled.
659  //
660  // \param pos starting position within the internal list of requests
661  // \param len length of slice to check (negative = until the end)
662  static bool waitAnyRequest(const label pos, label len = -1);
663 
664  //- Wait until some requests (from position onwards) have finished.
665  //- Corresponds to MPI_Waitsome()
666  // A no-op and returns false if parRun() == false,
667  // if the position is out-of-range [0 to nRequests],
668  // or the internal list of requests is empty.
669  //
670  // \returns true if some pending requests completed.
671  // \returns false if all requests have already been handled
672  //
673  // \param pos starting position within the internal list of requests
674  // \param len length of slice to check (negative = until the end)
675  // \param[out] indices the completed request indices relative to the
676  // starting position. This is an optional parameter that can be
677  // used to recover the indices or simply to avoid reallocations
678  // when calling within a loop.
679  static bool waitSomeRequests
680  (
681  const label pos,
682  label len = -1,
683  DynamicList<int>* indices = nullptr
684  );
685 
686  //- Wait until some requests have finished.
687  //- Corresponds to MPI_Waitsome()
688  // A no-op and returns false if parRun() == false,
689  // the list is empty,
690  // or if all the requests have already been handled.
691  //
692  // \param requests the requests
693  // \param[out] indices the completed request indices relative to the
694  // starting position. This is an optional parameter that can be
695  // used to recover the indices or simply to avoid reallocations
696  // when calling within a loop.
697  static bool waitSomeRequests
698  (
699  UList<UPstream::Request>& requests,
700  DynamicList<int>* indices = nullptr
701  );
702 
703  //- Wait until any request has finished and return its index.
704  //- Corresponds to MPI_Waitany()
705  // Returns -1 if parRun() == false, or the list is empty,
706  // or if all the requests have already been handled
707  static label waitAnyRequest(UList<UPstream::Request>& requests);
708 
709  //- Wait until request i has finished.
710  //- Corresponds to MPI_Wait()
711  // A no-op if parRun() == false,
712  // if there are no pending requests,
713  // or if the index is out-of-range (0 to nRequests)
714  static void waitRequest(const label i);
715 
716  //- Wait until specified request has finished.
717  //- Corresponds to MPI_Wait()
718  // A no-op if parRun() == false or for a null-request
719  static void waitRequest(UPstream::Request& req);
720 
721  //- Non-blocking comms: has request i finished?
722  //- Corresponds to MPI_Test()
723  // A no-op and returns true if parRun() == false,
724  // if there are no pending requests,
725  // or if the index is out-of-range (0 to nRequests)
726  static bool finishedRequest(const label i);
727 
728  //- Non-blocking comms: has request finished?
729  //- Corresponds to MPI_Test()
730  // A no-op and returns true if parRun() == false
731  // or for a null-request
732  static bool finishedRequest(UPstream::Request& req);
733 
734  //- Non-blocking comms: have all requests (from position onwards)
735  //- finished?
736  //- Corresponds to MPI_Testall()
737  // A no-op and returns true if parRun() == false,
738  // if there are no pending requests,
739  // or if the index is out-of-range (0 to nRequests)
740  // or the addressed range is empty etc.
741  //
742  // \param pos starting position within the internal list of requests
743  // \param len length of slice to check (negative = until the end)
744  static bool finishedRequests(const label pos, label len = -1);
745 
746  //- Non-blocking comms: have all requests finished?
747  //- Corresponds to MPI_Testall()
748  // A no-op and returns true if parRun() == false or list is empty
749  static bool finishedRequests(UList<UPstream::Request>& requests);
750 
751  //- Non-blocking comms: have both requests finished?
752  //- Corresponds to pair of MPI_Test()
753  // A no-op and returns true if parRun() == false,
754  // if there are no pending requests,
755  // or if the indices are out-of-range (0 to nRequests)
756  // Each finished request parameter is set to -1 (ie, done).
757  static bool finishedRequestPair(label& req0, label& req1);
758 
759  //- Non-blocking comms: wait for both requests to finish.
760  //- Corresponds to pair of MPI_Wait()
761  // A no-op if parRun() == false,
762  // if there are no pending requests,
763  // or if the indices are out-of-range (0 to nRequests)
764  // Each finished request parameter is set to -1 (ie, done).
765  static void waitRequestPair(label& req0, label& req1);
766 
767 
768  // General
769 
770  //- Set as parallel run on/off.
771  // \return the previous value
772  static bool parRun(const bool on) noexcept
773  {
774  bool old(parRun_);
775  parRun_ = on;
776  return old;
777  }
778 
779  //- Test if this a parallel run
780  // Modify access is deprecated
781  static bool& parRun() noexcept { return parRun_; }
782 
783  //- Have support for threads
784  static bool haveThreads() noexcept { return haveThreads_; }
785 
786  //- Relative rank for the master process - is always 0.
787  static constexpr int masterNo() noexcept { return 0; }
788 
789  //- Number of ranks in parallel run (for given communicator).
790  //- It is 1 for serial run
791  static label nProcs(const label communicator = worldComm)
792  {
793  return procIDs_[communicator].size();
794  }
795 
796  //- Rank of this process in the communicator (starting from masterNo()).
797  //- Can be negative if the process is not a rank in the communicator
798  static int myProcNo(const label communicator = worldComm)
799  {
800  return myProcNo_[communicator];
801  }
802 
803  //- True if process corresponds to the master rank in the communicator
804  static bool master(const label communicator = worldComm)
805  {
806  return myProcNo_[communicator] == masterNo();
807  }
808 
809  //- True if process corresponds to any rank (master or sub-rank)
810  //- in the given communicator
811  static bool is_rank(const label communicator = worldComm)
812  {
813  return myProcNo_[communicator] >= 0;
814  }
815 
816  //- True if process corresponds to a sub-rank in the given communicator
817  static bool is_subrank(const label communicator = worldComm)
818  {
819  return myProcNo_[communicator] > masterNo();
820  }
821 
822  //- True if parallel algorithm or exchange is required.
823  // This is when parRun() == true, the process corresponds to a rank
824  // in the communicator and there is more than one rank in the
825  // communicator
826  static bool is_parallel(const label communicator = worldComm)
827  {
828  return
829  (
830  parRun_ && is_rank(communicator) && nProcs(communicator) > 1
831  );
832  }
833 
834  //- The parent communicator
835  static label parent(const label communicator)
836  {
837  return parentComm_(communicator);
838  }
839 
840  //- The list of ranks within a given communicator
841  static List<int>& procID(const label communicator)
842  {
843  return procIDs_[communicator];
844  }
845 
846 
847  // Worlds
848 
849  //- All worlds
850  static const wordList& allWorlds() noexcept
851  {
852  return allWorlds_;
853  }
854 
855  //- The indices into allWorlds for all processes
856  static const labelList& worldIDs() noexcept
857  {
858  return worldIDs_;
859  }
860 
861  //- My worldID
862  static label myWorldID()
863  {
864  return worldIDs_[myProcNo(UPstream::commGlobal())];
865  }
866 
867  //- My world
868  static const word& myWorld()
869  {
870  return allWorlds_[worldIDs_[myProcNo(UPstream::commGlobal())]];
871  }
872 
873 
874  // Rank addressing
875 
876  //- Range of process indices for all processes
877  static rangeType allProcs(const label communicator = worldComm)
878  {
879  // Proc 0 -> nProcs (int value)
880  return rangeType(static_cast<int>(nProcs(communicator)));
881  }
882 
883  //- Range of process indices for sub-processes
884  static rangeType subProcs(const label communicator = worldComm)
885  {
886  // Proc 1 -> nProcs (int value)
887  return rangeType(1, static_cast<int>(nProcs(communicator)-1));
888  }
889 
890  //- Communication schedule for linear all-to-master (proc 0)
891  static const List<commsStruct>&
893  (
894  const label communicator = worldComm
895  );
896 
897  //- Communication schedule for tree all-to-master (proc 0)
898  static const List<commsStruct>& treeCommunication
899  (
900  const label communicator = worldComm
901  );
902 
903  //- Communication schedule for linear/tree all-to-master (proc 0).
904  //- Chooses based on the value of UPstream::nProcsSimpleSum
905  static const List<commsStruct>& whichCommunication
906  (
907  const label communicator = worldComm
908  )
909  {
910  return
911  (
912  nProcs(communicator) < nProcsSimpleSum
913  ? linearCommunication(communicator)
914  : treeCommunication(communicator)
915  );
916  }
917 
918 
919  //- Message tag of standard messages
920  static int& msgType() noexcept
921  {
922  return msgType_;
923  }
924 
925  //- Set the message tag for standard messages
926  // \return the previous value
927  static int msgType(int val) noexcept
928  {
929  int old(msgType_);
930  msgType_ = val;
931  return old;
932  }
933 
934  //- Increment the message tag for standard messages
935  // \return the previous value
936  static int incrMsgType(int val = 1) noexcept
937  {
938  int old(msgType_);
939  msgType_ += val;
940  return old;
941  }
942 
943  //- Get the communications type of the stream
945  {
946  return commsType_;
947  }
948 
949  //- Set the communications type of the stream
950  // \return the previous value
952  {
953  commsTypes old(commsType_);
954  commsType_ = ct;
955  return old;
956  }
957 
958 
959  //- Shutdown (finalize) MPI as required.
960  // Uses MPI_Abort instead of MPI_Finalize if errNo is non-zero
961  static void shutdown(int errNo = 0);
962 
963  //- Call MPI_Abort with no other checks or cleanup
964  static void abort();
965 
966  //- Shutdown (finalize) MPI as required and exit program with errNo.
967  static void exit(int errNo = 1);
968 
969 
970  #undef Pstream_CommonRoutines
971  #define Pstream_CommonRoutines(Native) \
972  \
973  \
974  \
975  static void allToAll \
976  ( \
977  \
978  const UList<Native>& sendData, \
979  \
980  UList<Native>& recvData, \
981  const label communicator = worldComm \
982  ); \
983  \
984  \
985  \
986  \
987  \
988  \
989  \
990  \
991  \
992  static void allToAllConsensus \
993  ( \
994  \
995  const UList<Native>& sendData, \
996  \
997  UList<Native>& recvData, \
998  \
999  const int tag, \
1000  const label communicator = worldComm \
1001  ); \
1002  \
1003  \
1004  \
1005  \
1006  \
1007  \
1008  static void allToAllConsensus \
1009  ( \
1010  \
1011  const Map<Native>& sendData, \
1012  \
1013  Map<Native>& recvData, \
1014  \
1015  const int tag, \
1016  const label communicator = worldComm \
1017  ); \
1018  \
1019  \
1020  \
1021  static Map<Native> allToAllConsensus \
1022  ( \
1023  \
1024  const Map<Native>& sendData, \
1025  \
1026  const int tag, \
1027  const label communicator = worldComm \
1028  ) \
1029  { \
1030  Map<Native> recvData; \
1031  allToAllConsensus(sendData, recvData, tag, communicator); \
1032  return recvData; \
1033  }
1034 
1035  Pstream_CommonRoutines(int32_t);
1036  Pstream_CommonRoutines(int64_t);
1038  #undef Pstream_CommonRoutines
1039 
1040 
1041  // Low-level gather/scatter routines
1042 
1043  #undef Pstream_CommonRoutines
1044  #define Pstream_CommonRoutines(Native) \
1045  \
1046  \
1047  static void mpiGather \
1048  ( \
1049  \
1050  const Native* sendData, \
1051  \
1052  Native* recvData, \
1053  \
1054  int count, \
1055  const label communicator = worldComm \
1056  ); \
1057  \
1058  \
1059  static void mpiScatter \
1060  ( \
1061  \
1062  const Native* sendData, \
1063  \
1064  Native* recvData, \
1065  \
1066  int count, \
1067  const label communicator = worldComm \
1068  ); \
1069  \
1070  \
1071  \
1072  static void mpiAllGather \
1073  ( \
1074  \
1075  Native* allData, \
1076  \
1077  int count, \
1078  const label communicator = worldComm \
1079  ); \
1080  \
1081  \
1082  static void gather \
1083  ( \
1084  const Native* sendData, \
1085  int sendCount, \
1086  Native* recvData, \
1087  const UList<int>& recvCounts, \
1088  const UList<int>& recvOffsets, \
1089  const label communicator = worldComm \
1090  ); \
1091  \
1092  \
1093  static void scatter \
1094  ( \
1095  const Native* sendData, \
1096  const UList<int>& sendCounts, \
1097  const UList<int>& sendOffsets, \
1098  Native* recvData, \
1099  int recvCount, \
1100  const label communicator = worldComm \
1101  );
1102 
1103  Pstream_CommonRoutines(char);
1104  Pstream_CommonRoutines(int32_t);
1105  Pstream_CommonRoutines(int64_t);
1106  Pstream_CommonRoutines(uint32_t);
1107  Pstream_CommonRoutines(uint64_t);
1108  Pstream_CommonRoutines(float);
1109  Pstream_CommonRoutines(double);
1110 
1111  #undef Pstream_CommonRoutines
1112 
1113 
1114  // Gather single, contiguous value(s)
1115 
1116  //- Allgather individual values into list locations.
1117  // The returned list has size nProcs, identical on all ranks.
1118  template<class T>
1119  static List<T> allGatherValues
1120  (
1121  const T& localValue,
1122  const label communicator = worldComm
1123  );
1124 
1125  //- Gather individual values into list locations.
1126  // On master list length == nProcs, otherwise zero length.
1127  // \n
1128  // For \b non-parallel :
1129  // the returned list length is 1 with localValue.
1130  template<class T>
1131  static List<T> listGatherValues
1132  (
1133  const T& localValue,
1134  const label communicator = worldComm
1135  );
1136 
1137  //- Scatter individual values from list locations.
1138  // On master input list length == nProcs, ignored on other procs.
1139  // \n
1140  // For \b non-parallel :
1141  // returns the first list element (or zero).
1142  template<class T>
1143  static T listScatterValues
1144  (
1145  const UList<T>& allValues,
1146  const label communicator = worldComm
1147  );
1148 
1150  // Broadcast Functions
1151 
1152  //- Broadcast buffer contents to all processes in given communicator.
1153  //- The sizes must match on all processes.
1154  // For \b non-parallel : do nothing.
1155  // \return True on success
1156  static bool broadcast
1157  (
1158  char* buf,
1159  const std::streamsize bufSize,
1160  const label communicator,
1161  const int rootProcNo = masterNo()
1162  );
1163 
1164 
1165  // Logical reductions
1166 
1167  //- Logical (and) reduction (MPI_AllReduce)
1168  // For \b non-parallel : do nothing
1169  static void reduceAnd
1170  (
1171  bool& value,
1172  const label communicator = worldComm
1173  );
1174 
1175  //- Logical (or) reduction (MPI_AllReduce)
1176  // For \b non-parallel : do nothing
1177  static void reduceOr
1178  (
1179  bool& value,
1180  const label communicator = worldComm
1181  );
1182 
1183 
1184  // Housekeeping
1186  //- Wait for all requests to finish.
1187  // \deprecated(2023-01) Probably not what you want.
1188  // Should normally be restricted to a particular starting request.
1189  FOAM_DEPRECATED_FOR(2023-01, "waitRequests(int) method")
1190  static void waitRequests() { waitRequests(0); }
1191 
1192  //- Process index of first sub-process
1193  // \deprecated(2020-09) use subProcs() method instead
1194  static constexpr int firstSlave() noexcept
1195  {
1196  return 1;
1197  }
1198 
1199  //- Process index of last sub-process
1200  // \deprecated(2020-09) use subProcs() method instead
1201  static int lastSlave(const label communicator = worldComm)
1202  {
1203  return nProcs(communicator) - 1;
1204  }
1205 };
1206 
1207 
1208 /*---------------------------------------------------------------------------*\
1209  Class UPstream::Request Declaration
1210 \*---------------------------------------------------------------------------*/
1211 
1212 //- An opaque wrapper for MPI_Request with a vendor-independent
1213 //- representation independent of any \c <mpi.h> header
1214 // The MPI standard states that MPI_Request is always an opaque object.
1215 // Generally it is either an integer (eg, mpich) or a pointer (eg, openmpi).
1216 class UPstream::Request
1217 {
1218 public:
1219 
1220  // Public Types
1221 
1222  //- Storage for MPI_Request (as integer or pointer)
1223  typedef std::intptr_t value_type;
1224 
1225 
1226 private:
1227 
1228  // Private Data
1230  //- The MPI_Request (as wrapped value)
1231  value_type value_;
1232 
1233 public:
1234 
1235  // Generated Methods
1236 
1237  //- Copy construct
1238  Request(const Request&) noexcept = default;
1240  //- Move construct
1241  Request(Request&&) noexcept = default;
1242 
1243  //- Copy assignment
1244  Request& operator=(const Request&) noexcept = default;
1245 
1246  //- Move assignment
1247  Request& operator=(Request&&) noexcept = default;
1248 
1249 
1250  // Member Operators
1252  //- Test for equality
1253  bool operator==(const Request& rhs) const noexcept
1254  {
1255  return (value_ == rhs.value_);
1256  }
1257 
1258  //- Test for inequality
1259  bool operator!=(const Request& rhs) const noexcept
1260  {
1261  return (value_ != rhs.value_);
1262  }
1263 
1264 
1265  // Constructors
1266 
1267  //- Default construct as MPI_REQUEST_NULL
1268  Request() noexcept;
1269 
1270  //- Construct from MPI_Request (as pointer type)
1271  explicit Request(const void* p) noexcept
1272  :
1273  value_(reinterpret_cast<value_type>(p))
1274  {}
1275 
1276  //- Construct from MPI_Request (as integer type)
1277  explicit Request(value_type val) noexcept
1278  :
1279  value_(val)
1280  {}
1281 
1282 
1283  // Member Functions
1284 
1285  //- Return raw value
1286  value_type value() const noexcept { return value_; }
1287 
1288  //- Return as pointer value
1289  const void* pointer() const noexcept
1290  {
1291  return reinterpret_cast<const void*>(value_);
1292  }
1293 
1294  //- True if not equal to MPI_REQUEST_NULL
1295  bool good() const noexcept;
1296 
1297  //- Reset to default constructed value (MPI_REQUEST_NULL)
1298  void reset() noexcept;
1299 
1300  //- Same as calling UPstream::cancelRequest()
1301  void cancel() { UPstream::cancelRequest(*this); }
1302 
1303  //- Same as calling UPstream::freeRequest()
1304  void free() { UPstream::freeRequest(*this); }
1305 
1306  //- Same as calling UPstream::finishedRequest()
1307  bool finished() { return UPstream::finishedRequest(*this); }
1308 
1309  //- Same as calling UPstream::waitRequest()
1310  void wait() { UPstream::waitRequest(*this); }
1311 };
1312 
1313 
1314 // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
1315 
1316 Ostream& operator<<(Ostream&, const UPstream::commsStruct&);
1317 
1318 
1319 // * * * * * * * * * * * * Template Specialisations * * * * * * * * * * * * //
1320 
1321 // Template specialisation for access of commsStruct
1322 template<>
1323 UPstream::commsStruct&
1324 UList<UPstream::commsStruct>::operator[](const label procID);
1325 
1326 template<>
1327 const UPstream::commsStruct&
1328 UList<UPstream::commsStruct>::operator[](const label procID) const;
1329 
1330 
1331 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1332 
1333 } // End namespace Foam
1334 
1335 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1336 
1337 #ifdef NoRepository
1338  #include "UPstreamTemplates.C"
1339 #endif
1340 
1341 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1342 
1343 #endif
1344 
1345 // ************************************************************************* //
static bool floatTransfer
Should compact transfer be used in which floats replace doubles reducing the bandwidth requirement at...
Definition: UPstream.H:364
const labelList & below() const noexcept
The procIDs of the processors directly below.
Definition: UPstream.H:193
static const word & myWorld()
My world.
Definition: UPstream.H:1165
commsStruct() noexcept
Default construct with above == -1.
Definition: UPstream.H:139
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
sendModes
Different MPI-send modes (ignored for commsTypes::blocking)
Definition: UPstream.H:87
"blocking" : (MPI_Bsend, MPI_Recv)
static void removeRequests(const label pos, label len=-1)
Non-blocking comms: cancel/free outstanding requests (from position onwards) and remove from internal...
static const Enum< commsTypes > commsTypeNames
Enumerated names for the communication types.
Definition: UPstream.H:82
static const labelList & worldIDs() noexcept
The indices into allWorlds for all processes.
Definition: UPstream.H:1149
~communicator()
Free allocated communicator.
Definition: UPstream.H:625
label release() noexcept
Release ownership of the communicator, return old value.
Definition: UPstream.H:642
label comm() const noexcept
The communicator label.
Definition: UPstream.H:635
void reset() noexcept
Reset to default constructed value (MPI_REQUEST_NULL)
static int incrMsgType(int val=1) noexcept
Increment the message tag for standard messages.
Definition: UPstream.H:1251
static void clearHostComms()
Remove any existing intra and inter host communicators.
Definition: UPstream.C:716
commsTypes
Communications types.
Definition: UPstream.H:72
static void freeCommunicator(const label communicator, const bool withComponents=true)
Free a previously allocated communicator.
Definition: UPstream.C:565
static label nRequests() noexcept
Number of outstanding requests (on the internal list of requests)
An interval of (signed) integers defined by a start and a size.
Definition: IntRange.H:59
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
Definition: UPstream.H:1176
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:52
IntRange< int > rangeType
Int ranges are used for MPI ranks (processes)
Definition: UPstream.H:67
static int maxCommsSize
Optional maximum message size (bytes)
Definition: UPstream.H:390
static constexpr int firstSlave() noexcept
Process index of first sub-process.
Definition: UPstream.H:1545
static int nProcsSimpleSum
Number of processors to change from linear to tree communication.
Definition: UPstream.H:369
void wait()
Same as calling UPstream::waitRequest()
Definition: UPstream.H:1705
communicator() noexcept
Default construct (a placeholder communicator)
Definition: UPstream.H:585
static List< T > listGatherValues(const T &localValue, const label communicator=worldComm)
Gather individual values into list locations.
static bool initNull()
Special purpose initialisation function.
Definition: UPstream.C:30
static bool & parRun() noexcept
Test if this a parallel run.
Definition: UPstream.H:1049
static void cancelRequest(const label i)
Non-blocking comms: cancel and free outstanding request. Corresponds to MPI_Cancel() + MPI_Request_fr...
static bool finishedRequest(const label i)
Non-blocking comms: has request i finished? Corresponds to MPI_Test()
static label procNo(const label comm, const int baseProcID)
Return processor number in communicator (given physical processor number) (= reverse of baseProcNo) ...
Definition: UPstream.C:617
static List< T > allGatherValues(const T &localValue, const label communicator=worldComm)
Allgather individual values into list locations.
static void reduceOr(bool &value, const label communicator=worldComm)
Logical (or) reduction (MPI_AllReduce)
static const List< commsStruct > & whichCommunication(const label communicator=worldComm)
Communication schedule for linear/tree all-to-master (proc 0). Chooses based on the value of UPstream...
Definition: UPstream.H:1213
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1229
static constexpr label commSelf() noexcept
Communicator within the current rank only.
Definition: UPstream.H:424
static void printGraph(Ostream &os, const UList< UPstream::commsStruct > &comms, const label proci=0)
Print un-directed graph in graphviz dot format.
static void freeRequest(UPstream::Request &req)
Non-blocking comms: free outstanding request. Corresponds to MPI_Request_free()
static label commIntraHost()
Demand-driven: Intra-host communicator (respects any local worlds)
Definition: UPstream.C:682
void reset()
Reset to default constructed state.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition: UPstream.H:409
static void freeRequests(UList< UPstream::Request > &requests)
Non-blocking comms: free outstanding requests. Corresponds to MPI_Request_free()
label above() const noexcept
The procID of the processor directly above.
Definition: UPstream.H:188
bool good() const noexcept
True if not equal to MPI_REQUEST_NULL.
static void waitRequests()
Wait for all requests to finish.
Definition: UPstream.H:1538
static bool hasHostComms()
Test for presence of any intra or inter host communicators.
Definition: UPstream.C:710
static int tuning_NBX_
Tuning parameters for non-blocking exchange (NBX)
Definition: UPstream.H:395
static void shutdown(int errNo=0)
Shutdown (finalize) MPI as required.
Definition: UPstream.C:51
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
ClassName("UPstream")
Declare name of the class and its debug switch.
static label allocateInterHostCommunicator(const label parentCommunicator=worldComm)
Allocate an inter-host communicator.
Definition: UPstream.C:401
void reset()
Free allocated communicator.
Definition: UPstream.H:647
Various functions to operate on Lists.
class FOAM_DEPRECATED_FOR(2017-05, "Foam::Enum") NamedEnum
Definition: NamedEnum.H:65
T & operator[](const label i)
Return element of UList.
Definition: UListI.H:361
static bool finishedRequestPair(label &req0, label &req1)
Non-blocking comms: have both requests finished? Corresponds to pair of MPI_Test() ...
static int nProcsNonblockingExchange
Number of processors to change to nonBlocking consensual exchange (NBX). Ignored for zero or negative...
Definition: UPstream.H:375
static label commWarn(const label communicator) noexcept
Alter communicator debugging setting. Warns for use of any communicator differing from specified...
Definition: UPstream.H:449
dimensionedScalar pos(const dimensionedScalar &ds)
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:1065
bool operator!=(const Request &rhs) const noexcept
Test for inequality.
Definition: UPstream.H:1632
static int nPollProcInterfaces
Number of polling cycles in processor updates.
Definition: UPstream.H:380
static label parent(const label communicator)
The parent communicator.
Definition: UPstream.H:1122
static void exit(int errNo=1)
Shutdown (finalize) MPI as required and exit program with errNo.
Definition: UPstream.C:55
const void * pointer() const noexcept
Return as pointer value.
Definition: UPstream.H:1672
static void reduceAnd(bool &value, const label communicator=worldComm)
Logical (and) reduction (MPI_AllReduce)
static bool is_rank(const label communicator=worldComm)
True if process corresponds to any rank (master or sub-rank) in the given communicator.
Definition: UPstream.H:1091
"scheduled" : (MPI_Send, MPI_Recv)
static const List< commsStruct > & treeCommunication(const label communicator=worldComm)
Communication schedule for tree all-to-master (proc 0)
Definition: UPstream.C:659
static bool init(int &argc, char **&argv, const bool needsThread)
Initialisation function called from main.
Definition: UPstream.C:40
An opaque wrapper for MPI_Request with a vendor-independent representation independent of any <mpi...
Definition: UPstream.H:1573
label nProcs() const
The number of processors addressed by the structure.
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
Definition: UPstream.H:1059
(MPI_Send, MPI_Isend)
void free()
Same as calling UPstream::freeRequest()
Definition: UPstream.H:1695
static bool is_parallel(const label communicator=worldComm)
True if parallel algorithm or exchange is required.
Definition: UPstream.H:1111
static label allocateIntraHostCommunicator(const label parentCommunicator=worldComm)
Allocate an intra-host communicator.
Definition: UPstream.C:424
static label warnComm
Debugging: warn for use of any communicator differing from warnComm.
Definition: UPstream.H:414
Structure for communicating between processors.
Definition: UPstream.H:104
const labelList & allBelow() const noexcept
The procIDs of all processors below (so not just directly below)
Definition: UPstream.H:199
value_type value() const noexcept
Return raw value.
Definition: UPstream.H:1667
static label commInterHost()
Demand-driven: Inter-host communicator (respects any local worlds)
Definition: UPstream.C:696
static bool waitAnyRequest(const label pos, label len=-1)
Wait until any request (from position onwards) has finished. Corresponds to MPI_Waitany() ...
commsTypes commsType() const noexcept
Get the communications type of the stream.
Definition: UPstream.H:1261
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
const direction noexcept
Definition: Scalar.H:258
(MPI_Ssend, MPI_Issend)
bool operator==(const commsStruct &) const
static void resetRequests(const label n)
Truncate outstanding requests to given length, which is expected to be in the range [0 to nRequests()...
UPstream(const commsTypes commsType) noexcept
Construct for given communication type.
Definition: UPstream.H:495
static bool is_subrank(const label communicator=worldComm)
True if process corresponds to a sub-rank in the given communicator.
Definition: UPstream.H:1099
OBJstream os(runTime.globalPath()/outputName)
bool operator!=(const commsStruct &) const
static const List< commsStruct > & linearCommunication(const label communicator=worldComm)
Communication schedule for linear all-to-master (proc 0)
Definition: UPstream.C:646
static void printCommTree(const label communicator)
Debugging: print the communication tree.
Definition: UPstream.C:671
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
static void waitRequestPair(label &req0, label &req1)
Non-blocking comms: wait for both requests to finish. Corresponds to pair of MPI_Wait() ...
static void addRequest(UPstream::Request &req)
Transfer the (wrapped) MPI request to the internal global list.
bool good() const noexcept
True if communicator is non-negative (ie, was allocated)
Definition: UPstream.H:630
void cancel()
Same as calling UPstream::cancelRequest()
Definition: UPstream.H:1690
static label commWorld() noexcept
Communicator for all ranks (respecting any local worlds)
Definition: UPstream.H:429
Wrapper class for allocating/freeing communicators. Always invokes allocateCommunicatorComponents() a...
Definition: UPstream.H:566
const labelList & allNotBelow() const noexcept
The procIDs of all processors not below myProcNo. The inverse set of allBelow without myProcNo...
Definition: UPstream.H:205
static void abort()
Call MPI_Abort with no other checks or cleanup.
Definition: UPstream.C:62
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:77
List< word > wordList
List of word.
Definition: fileName.H:59
Request() noexcept
Default construct as MPI_REQUEST_NULL.
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:385
static void cancelRequests(UList< UPstream::Request > &requests)
Non-blocking comms: cancel and free outstanding requests. Corresponds to MPI_Cancel() + MPI_Request_f...
static int lastSlave(const label communicator=worldComm)
Process index of last sub-process.
Definition: UPstream.H:1555
static List< int > & procID(const label communicator)
The list of ranks within a given communicator.
Definition: UPstream.H:1130
static label nComms() noexcept
Number of currently defined communicators.
Definition: UPstream.H:459
std::intptr_t value_type
Storage for MPI_Request (as integer or pointer)
Definition: UPstream.H:1582
static bool broadcast(char *buf, const std::streamsize bufSize, const label communicator, const int rootProcNo=masterNo())
Broadcast buffer contents to all processes in given communicator. The sizes must match on all process...
static std::pair< int, int > probeMessage(const UPstream::commsTypes commsType, const int fromProcNo, const int tag=UPstream::msgType(), const label communicator=worldComm)
Probe for an incoming message.
Definition: UPstream.C:89
const dimensionedScalar c
Speed of light in a vacuum.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
"nonBlocking" : (MPI_Isend, MPI_Irecv)
label n
void operator=(const communicator &)=delete
No copy assignment.
static bool haveThreads() noexcept
Have support for threads.
Definition: UPstream.H:1054
friend Ostream & operator<<(Ostream &, const commsStruct &)
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
Definition: UPstream.H:1185
List< label > labelList
A List of labels.
Definition: List.H:62
volScalarField & p
static const int mpiBufferSize
MPI buffer-size (bytes)
Definition: UPstream.H:400
static const wordList & allWorlds() noexcept
All worlds.
Definition: UPstream.H:1141
bool finished()
Same as calling UPstream::finishedRequest()
Definition: UPstream.H:1700
static T listScatterValues(const UList< T > &allValues, const label communicator=worldComm)
Scatter individual values from list locations.
#define Pstream_CommonRoutines(Native)
Definition: UPstream.H:1371
static void waitRequest(const label i)
Wait until request i has finished. Corresponds to MPI_Wait()
Inter-processor communications stream.
Definition: UPstream.H:60
static int baseProcNo(label comm, int procID)
Return physical processor number (i.e. processor number in worldComm) given communicator and processo...
Definition: UPstream.C:604
static void addValidParOptions(HashTable< string > &validParOptions)
Add the valid option this type of communications library adds/requires on the command line...
Definition: UPstream.C:26
static label allocateCommunicator(const label parent, const labelRange &subRanks, const bool withComponents=true)
Allocate new communicator with contiguous sub-ranks on the parent communicator.
Definition: UPstream.C:258
Namespace for OpenFOAM.
static label myWorldID()
My worldID.
Definition: UPstream.H:1157
static bool waitSomeRequests(const label pos, label len=-1, DynamicList< int > *indices=nullptr)
Wait until some requests (from position onwards) have finished. Corresponds to MPI_Waitsome() ...
static void barrier(const label communicator, UPstream::Request *req=nullptr)
Impose a synchronisation barrier (optionally non-blocking)
Definition: UPstream.C:83
static bool finishedRequests(const label pos, label len=-1)
Non-blocking comms: have all requests (from position onwards) finished? Corresponds to MPI_Testall() ...
static constexpr label commGlobal() noexcept
Communicator for all ranks, irrespective of any local worlds.
Definition: UPstream.H:419