UPstream.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 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 Note
28  Included by global/globals.C
29 
30 \*---------------------------------------------------------------------------*/
31 
32 #include "UPstream.H"
33 #include "debug.H"
34 #include "registerSwitch.H"
35 #include "dictionary.H"
36 #include "SHA1.H"
37 #include "OSspecific.H" // for hostName()
38 #include "IOstreams.H"
39 
40 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
41 
42 namespace Foam
43 {
44  defineTypeNameAndDebug(UPstream, 0);
45 }
46 
47 const Foam::Enum
48 <
50 >
52 ({
53  { commsTypes::blocking, "blocking" },
54  { commsTypes::scheduled, "scheduled" },
55  { commsTypes::nonBlocking, "nonBlocking" },
56 });
57 
58 
59 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
60 
61 namespace Foam
62 {
63 
64 // Determine host grouping.
65 // Uses SHA1 of hostname instead of MPI_Comm_split or MPI_Comm_split_type
66 // for two reasons:
67 // - Comm_split returns an MPI_COMM_NULL on non-participating process
68 // which does not easily fit into the OpenFOAM framework
69 //
70 // - use the SHA1 of hostname allows a single MPI_Gather, determination of
71 // the inter-host vs intra-host (on the master) followed by a single
72 // broadcast of integers.
73 //
74 // Returns: the unique host indices with the leading hosts encoded
75 // with negative values
76 static List<int> getHostGroupIds(const label parentCommunicator)
77 {
78  const label numProcs = UPstream::nProcs(parentCommunicator);
79 
80  List<SHA1Digest> digests;
81  if (UPstream::master(parentCommunicator))
82  {
83  digests.resize(numProcs);
84  }
85 
86  // Could also add lowercase etc, but since hostName()
87  // will be consistent within the same node, there is no need.
88  SHA1Digest myDigest(SHA1(hostName()).digest());
89 
90  // The fixed-length digest allows use of MPI_Gather
92  (
93  myDigest.cdata_bytes(), // Send
94  digests.data_bytes(), // Recv
95  SHA1Digest::max_size(), // Num send/recv data per rank
96  parentCommunicator
97  );
98 
99  List<int> hostIDs(numProcs);
100 
101  // Compact numbering of hosts.
102  if (UPstream::master(parentCommunicator))
103  {
104  DynamicList<SHA1Digest> uniqDigests;
105 
106  forAll(digests, proci)
107  {
108  const SHA1Digest& dig = digests[proci];
109 
110  hostIDs[proci] = uniqDigests.find(dig);
111 
112  if (hostIDs[proci] < 0)
113  {
114  // First appearance of host. Encode as leader
115  hostIDs[proci] = -(uniqDigests.size() + 1);
116  uniqDigests.push_back(dig);
117  }
118  }
119  }
120 
122  (
123  hostIDs.data_bytes(),
124  hostIDs.size_bytes(),
125  parentCommunicator,
127  );
128 
129  return hostIDs;
130 }
131 
132 } // End namespace Foam
133 
134 
135 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
136 
137 void Foam::UPstream::setParRun(const label nProcs, const bool haveThreads)
138 {
139  parRun_ = (nProcs > 0);
140  haveThreads_ = haveThreads;
141 
142  label comm = -1;
143  labelRange singleProc(1);
144 
145  // Redo communicators that were created during static initialisation.
146  // When parRun == true, redo with MPI components
147  // When parRun == false, just redo in case of future changes
148 
149  if (!parRun_)
150  {
151  // These are already correct from the static initialisation,
152  // but just in case of future changes
153 
154  // Using (world, self) ordering
157 
158  // 0: COMM_WORLD : commWorld() / commGlobal()
159  comm = allocateCommunicator(-1, singleProc, false);
160  if (comm != UPstream::commGlobal())
161  {
162  // Failed sanity check
164  << "problem : comm:" << comm
165  << " expected comm-global:" << UPstream::commGlobal()
167  }
168 
169  // 1: COMM_SELF
170  comm = allocateCommunicator(-2, singleProc, false);
171  if (comm != UPstream::commSelf())
172  {
173  // Failed sanity check
175  << "problem : comm:" << comm
176  << " expected comm-self:" << UPstream::commSelf()
178  }
179 
180  Pout.prefix().clear();
181  Perr.prefix().clear();
182  }
183  else
184  {
185  // Redo communicators that were created during static initialisation
186  // but this time with MPI components
187 
188  // Using (world, self) ordering
191 
192  // 0: COMM_WORLD : commWorld() / commGlobal()
193  comm = allocateCommunicator(-1, labelRange(nProcs), true);
194  if (comm != UPstream::commGlobal())
195  {
196  // Failed sanity check
198  << "problem : comm:" << comm
199  << " expected comm-global:" << UPstream::commGlobal()
201  }
202 
203  // 1: COMM_SELF
204  // - Processor number wrt world communicator
205  singleProc.start() = UPstream::myProcNo(UPstream::commGlobal());
206  comm = allocateCommunicator(-2, singleProc, true);
207  if (comm != UPstream::commSelf())
208  {
209  // Failed sanity check
211  << "problem : comm:" << comm
212  << " expected comm-self:" << UPstream::commSelf()
214  }
215 
216  Pout.prefix() = '[' + Foam::name(myProcNo(commGlobal())) + "] ";
217  Perr.prefix() = Pout.prefix();
218  }
219 
220  if (debug)
221  {
222  Pout<< "UPstream::setParRun :"
223  << " nProcs:" << nProcs
224  << " haveThreads:" << haveThreads
225  << endl;
226  }
227 }
228 
229 
230 Foam::label Foam::UPstream::getAvailableCommIndex(const label parentIndex)
231 {
232  label index;
233  if (!freeComms_.empty())
234  {
235  // LIFO pop
236  index = freeComms_.back();
237  freeComms_.pop_back();
238 
239  // Reset existing
240  myProcNo_[index] = -1;
241  parentComm_[index] = parentIndex;
242 
243  procIDs_[index].clear();
244  linearCommunication_[index].clear();
245  treeCommunication_[index].clear();
246  }
247  else
248  {
249  // Extend storage
250  index = parentComm_.size();
251 
252  myProcNo_.push_back(-1);
253  parentComm_.push_back(parentIndex);
254 
255  procIDs_.emplace_back();
256  linearCommunication_.emplace_back();
257  treeCommunication_.emplace_back();
258  }
259 
260  return index;
261 }
262 
263 
265 (
266  const label parentIndex,
267  const labelRange& subRanks,
268  const bool withComponents
269 )
270 {
271  const label index = getAvailableCommIndex(parentIndex);
272 
273  if (debug)
274  {
275  Pout<< "Allocating communicator " << index << nl
276  << " parent : " << parentIndex << nl
277  << " procs : " << subRanks << nl
278  << endl;
279  }
280 
281  // Initially treat as master,
282  // overwritten by allocateCommunicatorComponents
283  myProcNo_[index] = UPstream::masterNo();
284 
285  // The selected sub-ranks.
286  // - transcribe from label to int
287  // - already in incremental order
288  auto& procIds = procIDs_[index];
289  procIds.resize_nocopy(subRanks.size());
290 
291  label numSubRanks = 0;
292  for (const label subRanki : subRanks)
293  {
294  procIds[numSubRanks] = subRanki;
295  ++numSubRanks;
296  }
297 
298  // Sizing and filling are demand-driven
299  linearCommunication_[index].clear();
300  treeCommunication_[index].clear();
301 
302  if (withComponents && parRun())
303  {
304  allocateCommunicatorComponents(parentIndex, index);
305 
306  // Could 'remember' locations of uninvolved ranks
319  }
320 
321  return index;
322 }
323 
324 
326 (
327  const label parentIndex,
328  const labelUList& subRanks,
329  const bool withComponents
330 )
331 {
332  const label index = getAvailableCommIndex(parentIndex);
333 
334  if (debug)
335  {
336  Pout<< "Allocating communicator " << index << nl
337  << " parent : " << parentIndex << nl
338  << " procs : " << flatOutput(subRanks) << nl
339  << endl;
340  }
341 
342  // Initially treat as master,
343  // overwritten by allocateCommunicatorComponents
344  myProcNo_[index] = UPstream::masterNo();
345 
346  // The selected sub-ranks.
347  // - transcribe from label to int. Treat negative values as 'ignore'
348  // - enforce incremental order (so index is rank in next communicator)
349 
350  auto& procIds = procIDs_[index];
351  procIds.resize_nocopy(subRanks.size());
352 
353  label numSubRanks = 0;
354  bool monotonicOrder = true;
355  for (const label subRanki : subRanks)
356  {
357  if (subRanki < 0)
358  {
359  continue;
360  }
361  if (monotonicOrder && numSubRanks)
362  {
363  monotonicOrder = (procIds[numSubRanks-1] < subRanki);
364  }
365 
366  procIds[numSubRanks] = subRanki;
367  ++numSubRanks;
368  }
369 
370  if (!monotonicOrder)
371  {
372  auto last = procIds.begin() + numSubRanks;
373  std::sort(procIds.begin(), last);
374  last = std::unique(procIds.begin(), last);
375  numSubRanks = label(last - procIds.begin());
376  }
377 
378  procIds.resize(numSubRanks);
379 
380  // Sizing and filling are demand-driven
381  linearCommunication_[index].clear();
382  treeCommunication_[index].clear();
383 
384  if (withComponents && parRun())
385  {
386  allocateCommunicatorComponents(parentIndex, index);
387 
388  // Could 'remember' locations of uninvolved ranks
401  }
402 
403  return index;
404 }
405 
406 
408 (
409  const label parentCommunicator
410 )
411 {
412  List<int> hostIDs = getHostGroupIds(parentCommunicator);
413 
414  DynamicList<label> subRanks(hostIDs.size());
415 
416  // From master to host-leader. Ranks between hosts.
417  forAll(hostIDs, proci)
418  {
419  // Is host leader?
420  if (hostIDs[proci] < 0)
421  {
422  subRanks.push_back(proci);
423  }
424  }
425 
426  return allocateCommunicator(parentCommunicator, subRanks);
427 }
428 
429 
431 (
432  const label parentCommunicator
433 )
434 {
435  List<int> hostIDs = getHostGroupIds(parentCommunicator);
436 
437  DynamicList<label> subRanks(hostIDs.size());
438 
439  // Intra-host ranks. Ranks within a host
440  int myHostId = hostIDs[UPstream::myProcNo(parentCommunicator)];
441  if (myHostId < 0) myHostId = -(myHostId + 1); // Flip to generic id
442 
443  forAll(hostIDs, proci)
444  {
445  int id = hostIDs[proci];
446  if (id < 0) id = -(id + 1); // Flip to generic id
447 
448  if (id == myHostId)
449  {
450  subRanks.push_back(proci);
451  }
452  }
453 
454  return allocateCommunicator(parentCommunicator, subRanks);
455 }
456 
457 
458 bool Foam::UPstream::allocateHostCommunicatorPairs()
459 {
460  // Use the world communicator (not global communicator)
461  const label parentCommunicator = worldComm;
462 
463  // Skip if non-parallel
464  if (!parRun())
465  {
466  return false;
467  }
468 
469  if (interHostComm_ >= 0 || intraHostComm_ >= 0)
470  {
471  // Failed sanity check
473  << "Host communicator(s) already created!" << endl
475  return false;
476  }
477 
478  interHostComm_ = getAvailableCommIndex(parentCommunicator);
479  intraHostComm_ = getAvailableCommIndex(parentCommunicator);
480 
481  // Sorted order, purely cosmetic
482  if (intraHostComm_ < interHostComm_)
483  {
484  std::swap(intraHostComm_, interHostComm_);
485  }
486 
487  // Overwritten later
488  myProcNo_[intraHostComm_] = UPstream::masterNo();
489  myProcNo_[interHostComm_] = UPstream::masterNo();
490 
491  if (debug)
492  {
493  Pout<< "Allocating host communicators "
494  << interHostComm_ << ", " << intraHostComm_ << nl
495  << " parent : " << parentCommunicator << nl
496  << endl;
497  }
498 
499  List<int> hostIDs = getHostGroupIds(parentCommunicator);
500 
501  DynamicList<int> subRanks(hostIDs.size());
502 
503  // From master to host-leader. Ranks between hosts.
504  {
505  subRanks.clear();
506  forAll(hostIDs, proci)
507  {
508  // Is host leader?
509  if (hostIDs[proci] < 0)
510  {
511  subRanks.push_back(proci);
512 
513  // Flip to generic host id
514  hostIDs[proci] = -(hostIDs[proci] + 1);
515  }
516  }
517 
518  const label index = interHostComm_;
519 
520  // Direct copy (subRanks is also int)
521  procIDs_[index] = subRanks;
522 
523  // Implicitly: withComponents = true
524  if (parRun()) // Already checked...
525  {
526  allocateCommunicatorComponents(parentCommunicator, index);
527  }
528 
529  // Sizing and filling are demand-driven
530  linearCommunication_[index].clear();
531  treeCommunication_[index].clear();
532  }
533 
534  // Intra-host ranks. Ranks within a host
535  {
536  int myHostId = hostIDs[UPstream::myProcNo(parentCommunicator)];
537  if (myHostId < 0) myHostId = -(myHostId + 1); // Flip to generic id
538 
539  subRanks.clear();
540  forAll(hostIDs, proci)
541  {
542  int id = hostIDs[proci];
543  if (id < 0) id = -(id + 1); // Flip to generic id
544 
545  if (id == myHostId)
546  {
547  subRanks.push_back(proci);
548  }
549  }
550 
551  const label index = intraHostComm_;
552 
553  // Direct copy (subRanks is also int)
554  procIDs_[index] = subRanks;
555 
556  // Implicitly: withComponents = true
557  if (parRun()) // Already checked...
558  {
559  allocateCommunicatorComponents(parentCommunicator, index);
560  }
561 
562  // Sizing and filling are demand-driven
563  linearCommunication_[index].clear();
564  treeCommunication_[index].clear();
565  }
566 
567  return true;
568 }
569 
570 
572 (
573  const label communicator,
574  const bool withComponents
575 )
576 {
577  // Filter out any placeholders
578  if (communicator < 0)
579  {
580  return;
581  }
582 
583  // Update demand-driven communicators
584  if (interHostComm_ == communicator) interHostComm_ = -1;
585  if (intraHostComm_ == communicator) intraHostComm_ = -1;
586 
587  if (debug)
588  {
589  Pout<< "Communicators : Freeing communicator " << communicator
590  << " parent: " << parentComm_[communicator]
591  << " myProcNo: " << myProcNo_[communicator]
592  << endl;
593  }
594 
595  if (withComponents && parRun())
596  {
597  freeCommunicatorComponents(communicator);
598  }
599 
600  myProcNo_[communicator] = -1;
601  parentComm_[communicator] = -1;
602  //procIDs_[communicator].clear();
603  linearCommunication_[communicator].clear();
604  treeCommunication_[communicator].clear();
605 
606  // LIFO push
607  freeComms_.push_back(communicator);
608 }
609 
610 
611 int Foam::UPstream::baseProcNo(label comm, int procID)
612 {
613  while (UPstream::parent(comm) >= 0 && procID >= 0)
614  {
615  const auto& parentRanks = UPstream::procID(comm);
616  procID = parentRanks[procID];
617  comm = parent(comm);
618  }
619 
620  return procID;
621 }
622 
623 
624 Foam::label Foam::UPstream::procNo(const label comm, const int baseProcID)
625 {
626  const auto& parentRanks = UPstream::procID(comm);
627  label parentComm = UPstream::parent(comm);
628 
629  int procID = baseProcID;
630 
631  if (parentComm >= 0)
632  {
633  procID = UPstream::procNo(parentComm, baseProcID);
634  }
635 
636  return parentRanks.find(procID);
637 }
638 
639 
640 Foam::label Foam::UPstream::procNo
641 (
642  const label comm,
643  const label currentComm,
644  const int currentProcID
645 )
646 {
647  label physProcID = UPstream::baseProcNo(currentComm, currentProcID);
648  return UPstream::procNo(comm, physProcID);
649 }
650 
651 
653 Foam::UPstream::linearCommunication(const label communicator)
654 {
655  if (linearCommunication_[communicator].empty())
656  {
657  linearCommunication_[communicator] =
658  List<commsStruct>(UPstream::nProcs(communicator));
659  }
660 
661  return linearCommunication_[communicator];
662 }
663 
664 
666 Foam::UPstream::treeCommunication(const label communicator)
667 {
668  if (treeCommunication_[communicator].empty())
669  {
670  treeCommunication_[communicator] =
672  }
673 
674  return treeCommunication_[communicator];
675 }
676 
677 
678 void Foam::UPstream::printCommTree(const label communicator)
679 {
680  const auto& comms = UPstream::whichCommunication(communicator);
681 
683  {
684  commsStruct::printGraph(Info(), comms);
685  }
686 }
687 
688 
689 Foam::label Foam::UPstream::commIntraHost()
690 {
691  if (!parRun())
692  {
693  return worldComm; // Don't know anything better to return
694  }
695  if (intraHostComm_ < 0)
696  {
697  allocateHostCommunicatorPairs();
698  }
699  return intraHostComm_;
700 }
701 
702 
703 Foam::label Foam::UPstream::commInterHost()
704 {
705  if (!parRun())
706  {
707  return worldComm; // Don't know anything better to return
708  }
709  if (interHostComm_ < 0)
710  {
711  allocateHostCommunicatorPairs();
712  }
713  return interHostComm_;
714 }
715 
718 {
719  return (intraHostComm_ >= 0 || interHostComm_ >= 0);
720 }
721 
722 
724 {
725  // Always with Pstream
726  freeCommunicator(intraHostComm_, true);
727  freeCommunicator(interHostComm_, true);
728 }
729 
730 
731 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
732 
733 bool Foam::UPstream::parRun_(false);
734 
735 bool Foam::UPstream::haveThreads_(false);
736 
737 int Foam::UPstream::msgType_(1);
738 
739 
740 Foam::wordList Foam::UPstream::allWorlds_(Foam::one{}, "");
741 Foam::labelList Foam::UPstream::worldIDs_(Foam::one{}, 0);
742 
743 
744 Foam::DynamicList<int> Foam::UPstream::myProcNo_(16);
745 Foam::DynamicList<Foam::List<int>> Foam::UPstream::procIDs_(16);
746 
747 Foam::DynamicList<Foam::label> Foam::UPstream::parentComm_(16);
748 Foam::DynamicList<Foam::label> Foam::UPstream::freeComms_;
749 
751 Foam::UPstream::linearCommunication_(16);
752 
754 Foam::UPstream::treeCommunication_(16);
755 
756 
757 Foam::label Foam::UPstream::intraHostComm_(-1);
758 Foam::label Foam::UPstream::interHostComm_(-1);
760 Foam::label Foam::UPstream::worldComm(0);
761 Foam::label Foam::UPstream::warnComm(-1);
762 
763 
764 // Predefine world and self communicator slots.
765 // These are overwritten in parallel mode (by UPstream::setParRun())
766 const Foam::label nPredefinedComm = []()
767 {
768  // 0: COMM_WORLD : commWorld() / commGlobal()
770 
771  // 1: COMM_SELF
773 
774  return Foam::UPstream::nComms();
775 }();
776 
777 
779 (
780  Foam::debug::optimisationSwitch("floatTransfer", 0)
781 );
783 (
784  "floatTransfer",
785  bool,
787 );
788 
790 (
791  Foam::debug::optimisationSwitch("nProcsSimpleSum", 0)
792 );
794 (
795  "nProcsSimpleSum",
796  int,
798 );
799 
801 (
802  Foam::debug::optimisationSwitch("nbx.min", 0)
803 );
805 (
806  "nbx.min",
807  int,
809 );
810 
812 (
813  Foam::debug::optimisationSwitch("nbx.tuning", 0)
814 );
816 (
817  "nbx.tuning",
818  int,
820 );
821 
822 
824 (
825  Foam::debug::optimisationSwitch("nPollProcInterfaces", 0)
826 );
828 (
829  "nPollProcInterfaces",
830  int,
832 );
833 
834 
836 (
837  commsTypeNames.get
838  (
839  "commsType",
841  )
842 );
843 
844 
846 namespace Foam
847 {
848  //- Registered reader for UPstream::defaultCommsType
849  class addcommsTypeToOpt
850  :
852  {
853  public:
854 
855  addcommsTypeToOpt(const char* name)
856  :
857  ::Foam::simpleRegIOobject(Foam::debug::addOptimisationObject, name)
858  {}
859 
860  virtual ~addcommsTypeToOpt() = default;
861 
862  virtual void readData(Foam::Istream& is)
863  {
866  }
867 
868  virtual void writeData(Foam::Ostream& os) const
869  {
871  }
872  };
873 
874  addcommsTypeToOpt addcommsTypeToOpt_("commsType");
875 }
877 
879 (
880  Foam::debug::optimisationSwitch("maxCommsSize", 0)
881 );
883 (
884  "maxCommsSize",
885  int,
887 );
888 
889 
891 (
892  Foam::debug::optimisationSwitch("mpiBufferSize", 0)
893 );
894 
895 
896 // ************************************************************************* //
registerOptSwitch("fa:geometryOrder", int, faMesh::geometryOrder_)
static bool floatTransfer
Should compact transfer be used in which floats replace doubles reducing the bandwidth requirement at...
Definition: UPstream.H:364
Abstract base class for registered object with I/O. Used in debug symbol registration.
prefixOSstream Perr
OSstream wrapped stderr (std::cerr) with parallel prefix.
EnumType read(Istream &is) const
Read a word from Istream and return the corresponding enumeration.
Definition: Enum.C:102
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
static const Enum< commsTypes > commsTypeNames
Enumerated names for the communication types.
Definition: UPstream.H:82
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:125
static void clearHostComms()
Remove any existing intra and inter host communicators.
Definition: UPstream.C:716
static void writeData(Ostream &os, const Type &val)
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:160
commsTypes
Communications types.
Definition: UPstream.H:72
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:598
static void freeCommunicator(const label communicator, const bool withComponents=true)
Free a previously allocated communicator.
Definition: UPstream.C:565
static List< int > getHostGroupIds(const label parentCommunicator)
Definition: UPstream.C:69
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:52
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
constexpr char nl
The newline &#39;\n&#39; character (0x0a)
Definition: Ostream.H:50
static int maxCommsSize
Optional maximum message size (bytes)
Definition: UPstream.H:390
static int nProcsSimpleSum
Number of processors to change from linear to tree communication.
Definition: UPstream.H:369
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:531
The SHA1 message digest.
Definition: SHA1Digest.H:56
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 const List< commsStruct > & whichCommunication(const label communicator=worldComm)
Communication schedule for linear/tree all-to-master (proc 0). Chooses based on the value of UPstream...
Definition: UPstream.H:1213
static constexpr label commSelf() noexcept
Communicator within the current rank only.
Definition: UPstream.H:424
static label commIntraHost()
Demand-driven: Intra-host communicator (respects any local worlds)
Definition: UPstream.C:682
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Definition: UPstream.H:1074
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Definition: UPstream.H:409
char * data_bytes() noexcept
Return pointer to the underlying array serving as data storage,.
Definition: UListI.H:286
const char * cdata_bytes() const noexcept
Raw digest char data (20 bytes) - const access. For consistency with other objects, these are not unsigned.
Definition: SHA1Digest.H:157
static bool hasHostComms()
Test for presence of any intra or inter host communicators.
Definition: UPstream.C:710
static int tuning_NBX_
Tuning parameters for non-blocking exchange (NBX)
Definition: UPstream.H:395
UList< label > labelUList
A UList of labels.
Definition: UList.H:78
static label allocateInterHostCommunicator(const label parentCommunicator=worldComm)
Allocate an inter-host communicator.
Definition: UPstream.C:401
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:421
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
static int nProcsNonblockingExchange
Number of processors to change to nonBlocking consensual exchange (NBX). Ignored for zero or negative...
Definition: UPstream.H:375
Functions used by OpenFOAM that are specific to POSIX compliant operating systems and need to be repl...
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
Definition: UPstream.H:1065
static int nPollProcInterfaces
Number of polling cycles in processor updates.
Definition: UPstream.H:380
static label parent(const label communicator)
The parent communicator.
Definition: UPstream.H:1122
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
Definition: exprTraits.C:127
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:51
static const List< commsStruct > & treeCommunication(const label communicator=worldComm)
Communication schedule for tree all-to-master (proc 0)
Definition: UPstream.C:659
void sort(UList< T > &list)
Sort the list.
Definition: UList.C:296
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
Definition: UPstream.H:1059
const string & prefix() const noexcept
Return the stream prefix.
static label allocateIntraHostCommunicator(const label parentCommunicator=worldComm)
Allocate an intra-host communicator.
Definition: UPstream.C:424
static void mpiGather(const char *sendData, char *recvData, int count, const label communicator=worldComm)
Receive identically-sized char data from all ranks.
static label warnComm
Debugging: warn for use of any communicator differing from warnComm.
Definition: UPstream.H:414
string hostName()
Return the system&#39;s host name, as per hostname(1)
Definition: POSIX.C:371
label find(const T &val) const
Find index of the first occurrence of the value.
Definition: UList.C:173
static label commInterHost()
Demand-driven: Inter-host communicator (respects any local worlds)
Definition: UPstream.C:696
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:56
int optimisationSwitch(const char *name, const int deflt=0)
Lookup optimisation switch or add default value.
Definition: debug.C:234
int debug
Static debugging option.
OBJstream os(runTime.globalPath()/outputName)
static const List< commsStruct > & linearCommunication(const label communicator=worldComm)
Communication schedule for linear all-to-master (proc 0)
Definition: UPstream.C:646
defineTypeNameAndDebug(combustionModel, 0)
static void printCommTree(const label communicator)
Debugging: print the communication tree.
Definition: UPstream.C:671
void push_back(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:555
Wrapper class for allocating/freeing communicators. Always invokes allocateCommunicatorComponents() a...
Definition: UPstream.H:566
const Foam::label nPredefinedComm
Definition: UPstream.C:759
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:385
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
Definition: error.H:64
static List< int > & procID(const label communicator)
The list of ranks within a given communicator.
Definition: UPstream.H:1130
static label nComms() noexcept
Number of currently defined communicators.
Definition: UPstream.H:459
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 bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1082
static constexpr unsigned max_size() noexcept
The dimensioned size of the digest is always 20 bytes.
Definition: SHA1Digest.H:180
messageStream Info
Information stream (stdout output on master, null elsewhere)
dictionary & optimisationSwitches()
The OptimisationSwitches sub-dictionary in the central controlDict(s).
Definition: debug.C:216
Functions to compute SHA1 message digest according to the NIST specification FIPS-180-1.
Definition: SHA1.H:56
static bool haveThreads() noexcept
Have support for threads.
Definition: UPstream.H:1054
static const int mpiBufferSize
MPI buffer-size (bytes)
Definition: UPstream.H:400
void addOptimisationObject(const char *name, simpleRegIOobject *obj)
Register optimisation switch read/write object.
Definition: debug.C:259
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
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 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.
A class representing the concept of 1 (one) that can be used to avoid manipulating objects known to b...
Definition: one.H:56
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
Definition: FlatOutput.H:225
static constexpr label commGlobal() noexcept
Communicator for all ranks, irrespective of any local worlds.
Definition: UPstream.H:419