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