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