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::buffered, "buffered" }, // "buffered"
54  { commsTypes::scheduled, "scheduled" },
55  { commsTypes::nonBlocking, "nonBlocking" }, // "immediate"
56  // compatibility names
57  { commsTypes::buffered, "blocking" },
58 });
59 
60 
61 // * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
62 
63 namespace Foam
64 {
65 
66 // Determine host grouping.
67 // Uses SHA1 of hostname instead of MPI_Comm_split or MPI_Comm_split_type
68 // for two reasons:
69 // - Comm_split returns an MPI_COMM_NULL on non-participating process
70 // which does not easily fit into the OpenFOAM framework
71 //
72 // - use the SHA1 of hostname allows a single MPI_Gather, determination of
73 // the inter-host vs intra-host (on the master) followed by a single
74 // broadcast of integers.
75 //
76 // Returns: the unique host indices with the leading hosts encoded
77 // with negative values
78 static List<int> getHostGroupIds(const label parentCommunicator)
79 {
80  const label numProcs = UPstream::nProcs(parentCommunicator);
81 
82  List<SHA1Digest> digests;
83  if (UPstream::master(parentCommunicator))
84  {
85  digests.resize(numProcs);
86  }
87 
88  // Could also add lowercase etc, but since hostName()
89  // will be consistent within the same node, there is no need.
90  SHA1Digest myDigest(SHA1(hostName()).digest());
91 
92  // The fixed-length digest allows use of MPI_Gather
94  (
95  myDigest.cdata_bytes(), // Send
96  digests.data_bytes(), // Recv
97  SHA1Digest::max_size(), // Num send/recv data per rank
98  parentCommunicator
99  );
100 
101  List<int> hostIDs(numProcs);
102 
103  // Compact numbering of hosts.
104  if (UPstream::master(parentCommunicator))
105  {
106  DynamicList<SHA1Digest> uniqDigests;
107 
108  forAll(digests, proci)
109  {
110  const SHA1Digest& dig = digests[proci];
111 
112  hostIDs[proci] = uniqDigests.find(dig);
113 
114  if (hostIDs[proci] < 0)
115  {
116  // First appearance of host. Encode as leader
117  hostIDs[proci] = -(uniqDigests.size() + 1);
118  uniqDigests.push_back(dig);
119  }
120  }
121  }
122 
124  (
125  hostIDs.data_bytes(),
126  hostIDs.size_bytes(),
127  parentCommunicator,
129  );
130 
131  return hostIDs;
132 }
133 
134 } // End namespace Foam
135 
136 
137 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
138 
139 void Foam::UPstream::setParRun(const label nProcs, const bool haveThreads)
140 {
141  parRun_ = (nProcs > 0);
142  haveThreads_ = haveThreads;
143 
144  label comm = -1;
145  labelRange singleProc(1);
146 
147  // Redo communicators that were created during static initialisation.
148  // When parRun == true, redo with MPI components
149  // When parRun == false, just redo in case of future changes
150 
151  if (!parRun_)
152  {
153  // These are already correct from the static initialisation,
154  // but just in case of future changes
155 
156  // Using (world, self) ordering
159 
160  // 0: COMM_WORLD : commWorld() / commGlobal()
161  comm = allocateCommunicator(-1, singleProc, false);
162  if (comm != UPstream::commGlobal())
163  {
164  // Failed sanity check
166  << "problem : comm:" << comm
167  << " expected comm-global:" << UPstream::commGlobal()
169  }
170 
171  // 1: COMM_SELF
172  comm = allocateCommunicator(-2, singleProc, false);
173  if (comm != UPstream::commSelf())
174  {
175  // Failed sanity check
177  << "problem : comm:" << comm
178  << " expected comm-self:" << UPstream::commSelf()
180  }
181 
182  Pout.prefix().clear();
183  Perr.prefix().clear();
184  }
185  else
186  {
187  // Redo communicators that were created during static initialisation
188  // but this time with MPI components
189 
190  // Using (world, self) ordering
193 
194  // 0: COMM_WORLD : commWorld() / commGlobal()
195  comm = allocateCommunicator(-1, labelRange(nProcs), true);
196  if (comm != UPstream::commGlobal())
197  {
198  // Failed sanity check
200  << "problem : comm:" << comm
201  << " expected comm-global:" << UPstream::commGlobal()
203  }
204 
205  // 1: COMM_SELF
206  // - Processor number wrt world communicator
207  singleProc.start() = UPstream::myProcNo(UPstream::commGlobal());
208  comm = allocateCommunicator(-2, singleProc, true);
209  if (comm != UPstream::commSelf())
210  {
211  // Failed sanity check
213  << "problem : comm:" << comm
214  << " expected comm-self:" << UPstream::commSelf()
216  }
217 
218  Pout.prefix() = '[' + Foam::name(myProcNo(commGlobal())) + "] ";
219  Perr.prefix() = Pout.prefix();
220  }
221 
222  if (debug)
223  {
224  Perr<< "UPstream::setParRun :"
225  << " nProcs:" << nProcs
226  << " haveThreads:" << haveThreads
227  << endl;
228  }
229 }
230 
231 
232 Foam::label Foam::UPstream::getAvailableCommIndex(const label parentIndex)
233 {
234  label index;
235  if (!freeComms_.empty())
236  {
237  // LIFO pop
238  index = freeComms_.back();
239  freeComms_.pop_back();
240 
241  // Reset existing
242  myProcNo_[index] = -1;
243  parentComm_[index] = parentIndex;
244 
245  procIDs_[index].clear();
246  linearCommunication_[index].clear();
247  treeCommunication_[index].clear();
248  }
249  else
250  {
251  // Extend storage
252  index = parentComm_.size();
253 
254  myProcNo_.push_back(-1);
255  parentComm_.push_back(parentIndex);
256 
257  procIDs_.emplace_back();
258  linearCommunication_.emplace_back();
259  treeCommunication_.emplace_back();
260  }
261 
262  return index;
263 }
264 
265 
267 (
268  const label parentIndex,
269  const labelRange& subRanks,
270  const bool withComponents
271 )
272 {
273  const label index = getAvailableCommIndex(parentIndex);
274 
275  if (debug)
276  {
277  Perr<< "Allocating communicator " << index << nl
278  << " parent : " << parentIndex << nl
279  << " procs : " << subRanks << nl
280  << endl;
281  }
282 
283  // Initially treat as master,
284  // overwritten by allocateCommunicatorComponents
285  myProcNo_[index] = UPstream::masterNo();
286 
287  // The selected sub-ranks.
288  // - transcribe from label to int
289  // - already in incremental order
290  auto& procIds = procIDs_[index];
291  procIds.resize_nocopy(subRanks.size());
292 
293  label numSubRanks = 0;
294  for (const label subRanki : subRanks)
295  {
296  procIds[numSubRanks] = subRanki;
297  ++numSubRanks;
298  }
299 
300  // Sizing and filling are demand-driven
301  linearCommunication_[index].clear();
302  treeCommunication_[index].clear();
303 
304  if (withComponents && parRun())
305  {
306  allocateCommunicatorComponents(parentIndex, index);
307 
308  // Could 'remember' locations of uninvolved ranks
321  }
322 
323  return index;
324 }
325 
326 
328 (
329  const label parentIndex,
330  const labelUList& subRanks,
331  const bool withComponents
332 )
333 {
334  const label index = getAvailableCommIndex(parentIndex);
335 
336  if (debug)
337  {
338  Perr<< "Allocating communicator " << index << nl
339  << " parent : " << parentIndex << nl
340  << " procs : " << flatOutput(subRanks) << nl
341  << endl;
342  }
343 
344  // Initially treat as master,
345  // overwritten by allocateCommunicatorComponents
346  myProcNo_[index] = UPstream::masterNo();
347 
348  // The selected sub-ranks.
349  // - transcribe from label to int. Treat negative values as 'ignore'
350  // - enforce incremental order (so index is rank in next communicator)
351 
352  auto& procIds = procIDs_[index];
353  procIds.resize_nocopy(subRanks.size());
354 
355  label numSubRanks = 0;
356  bool monotonicOrder = true;
357  for (const label subRanki : subRanks)
358  {
359  if (subRanki < 0)
360  {
361  continue;
362  }
363  if (monotonicOrder && numSubRanks)
364  {
365  monotonicOrder = (procIds[numSubRanks-1] < subRanki);
366  }
367 
368  procIds[numSubRanks] = subRanki;
369  ++numSubRanks;
370  }
371 
372  if (!monotonicOrder)
373  {
374  auto last = procIds.begin() + numSubRanks;
375  std::sort(procIds.begin(), last);
376  last = std::unique(procIds.begin(), last);
377  numSubRanks = label(last - procIds.begin());
378  }
379 
380  procIds.resize(numSubRanks);
381 
382  // Sizing and filling are demand-driven
383  linearCommunication_[index].clear();
384  treeCommunication_[index].clear();
385 
386  if (withComponents && parRun())
387  {
388  allocateCommunicatorComponents(parentIndex, index);
389 
390  // Could 'remember' locations of uninvolved ranks
403  }
404 
405  return index;
406 }
407 
408 
410 (
411  const label parentCommunicator
412 )
413 {
414  List<int> hostIDs = getHostGroupIds(parentCommunicator);
415 
416  DynamicList<label> subRanks(hostIDs.size());
417 
418  // From master to host-leader. Ranks between hosts.
419  forAll(hostIDs, proci)
420  {
421  // Is host leader?
422  if (hostIDs[proci] < 0)
423  {
424  subRanks.push_back(proci);
425  }
426  }
427 
428  return allocateCommunicator(parentCommunicator, subRanks);
429 }
430 
431 
433 (
434  const label parentCommunicator
435 )
436 {
437  List<int> hostIDs = getHostGroupIds(parentCommunicator);
438 
439  DynamicList<label> subRanks(hostIDs.size());
440 
441  // Intra-host ranks. Ranks within a host
442  int myHostId = hostIDs[UPstream::myProcNo(parentCommunicator)];
443  if (myHostId < 0) myHostId = -(myHostId + 1); // Flip to generic id
444 
445  forAll(hostIDs, proci)
446  {
447  int id = hostIDs[proci];
448  if (id < 0) id = -(id + 1); // Flip to generic id
449 
450  if (id == myHostId)
451  {
452  subRanks.push_back(proci);
453  }
454  }
455 
456  return allocateCommunicator(parentCommunicator, subRanks);
457 }
458 
459 
460 bool Foam::UPstream::allocateHostCommunicatorPairs()
461 {
462  // Use the world communicator (not global communicator)
463  const label parentCommunicator = worldComm;
464 
465  // Skip if non-parallel
466  if (!parRun())
467  {
468  return false;
469  }
470 
471  if (interHostComm_ >= 0 || intraHostComm_ >= 0)
472  {
473  // Failed sanity check
475  << "Host communicator(s) already created!" << endl
477  return false;
478  }
479 
480  interHostComm_ = getAvailableCommIndex(parentCommunicator);
481  intraHostComm_ = getAvailableCommIndex(parentCommunicator);
482 
483  // Sorted order, purely cosmetic
484  if (intraHostComm_ < interHostComm_)
485  {
486  std::swap(intraHostComm_, interHostComm_);
487  }
488 
489  // Overwritten later
490  myProcNo_[intraHostComm_] = UPstream::masterNo();
491  myProcNo_[interHostComm_] = UPstream::masterNo();
492 
493  if (debug)
494  {
495  Perr<< "Allocating host communicators "
496  << interHostComm_ << ", " << intraHostComm_ << nl
497  << " parent : " << parentCommunicator << nl
498  << endl;
499  }
500 
501  List<int> hostIDs = getHostGroupIds(parentCommunicator);
502 
503  DynamicList<int> subRanks(hostIDs.size());
504 
505  // From master to host-leader. Ranks between hosts.
506  {
507  subRanks.clear();
508  forAll(hostIDs, proci)
509  {
510  // Is host leader?
511  if (hostIDs[proci] < 0)
512  {
513  subRanks.push_back(proci);
514 
515  // Flip to generic host id
516  hostIDs[proci] = -(hostIDs[proci] + 1);
517  }
518  }
519 
520  const label index = interHostComm_;
521 
522  // Direct copy (subRanks is also int)
523  procIDs_[index] = subRanks;
524 
525  // Implicitly: withComponents = true
526  if (parRun()) // Already checked...
527  {
528  allocateCommunicatorComponents(parentCommunicator, index);
529  }
530 
531  // Sizing and filling are demand-driven
532  linearCommunication_[index].clear();
533  treeCommunication_[index].clear();
534  }
535 
536  // Intra-host ranks. Ranks within a host
537  {
538  int myHostId = hostIDs[UPstream::myProcNo(parentCommunicator)];
539  if (myHostId < 0) myHostId = -(myHostId + 1); // Flip to generic id
540 
541  subRanks.clear();
542  forAll(hostIDs, proci)
543  {
544  int id = hostIDs[proci];
545  if (id < 0) id = -(id + 1); // Flip to generic id
546 
547  if (id == myHostId)
548  {
549  subRanks.push_back(proci);
550  }
551  }
552 
553  const label index = intraHostComm_;
554 
555  // Direct copy (subRanks is also int)
556  procIDs_[index] = subRanks;
557 
558  // Implicitly: withComponents = true
559  if (parRun()) // Already checked...
560  {
561  allocateCommunicatorComponents(parentCommunicator, index);
562  }
563 
564  // Sizing and filling are demand-driven
565  linearCommunication_[index].clear();
566  treeCommunication_[index].clear();
567  }
568 
569  return true;
570 }
571 
572 
574 (
575  const label communicator,
576  const bool withComponents
577 )
578 {
579  // Filter out any placeholders
580  if (communicator < 0)
581  {
582  return;
583  }
584 
585  // Update demand-driven communicators
586  if (interHostComm_ == communicator) interHostComm_ = -1;
587  if (intraHostComm_ == communicator) intraHostComm_ = -1;
588 
589  if (debug)
590  {
591  Perr<< "Communicators : Freeing communicator " << communicator
592  << " parent: " << parentComm_[communicator]
593  << " myProcNo: " << myProcNo_[communicator]
594  << endl;
595  }
596 
597  if (withComponents && parRun())
598  {
599  freeCommunicatorComponents(communicator);
600  }
601 
602  myProcNo_[communicator] = -1;
603  parentComm_[communicator] = -1;
604  //procIDs_[communicator].clear();
605  linearCommunication_[communicator].clear();
606  treeCommunication_[communicator].clear();
607 
608  // LIFO push
609  freeComms_.push_back(communicator);
610 }
611 
612 
613 int Foam::UPstream::baseProcNo(label comm, int procID)
614 {
615  while (UPstream::parent(comm) >= 0 && procID >= 0)
616  {
617  const auto& parentRanks = UPstream::procID(comm);
618  procID = parentRanks[procID];
619  comm = parent(comm);
620  }
621 
622  return procID;
623 }
624 
625 
626 Foam::label Foam::UPstream::procNo(const label comm, const int baseProcID)
627 {
628  const auto& parentRanks = UPstream::procID(comm);
629  label parentComm = UPstream::parent(comm);
630 
631  int procID = baseProcID;
632 
633  if (parentComm >= 0)
634  {
635  procID = UPstream::procNo(parentComm, baseProcID);
636  }
637 
638  return parentRanks.find(procID);
639 }
640 
641 
642 Foam::label Foam::UPstream::procNo
643 (
644  const label comm,
645  const label currentComm,
646  const int currentProcID
647 )
648 {
649  label physProcID = UPstream::baseProcNo(currentComm, currentProcID);
650  return UPstream::procNo(comm, physProcID);
651 }
652 
653 
655 Foam::UPstream::linearCommunication(const label communicator)
656 {
657  if (linearCommunication_[communicator].empty())
658  {
659  linearCommunication_[communicator] =
660  List<commsStruct>(UPstream::nProcs(communicator));
661  }
662 
663  return linearCommunication_[communicator];
664 }
665 
666 
668 Foam::UPstream::treeCommunication(const label communicator)
669 {
670  if (treeCommunication_[communicator].empty())
671  {
672  treeCommunication_[communicator] =
674  }
675 
676  return treeCommunication_[communicator];
677 }
678 
679 
680 void Foam::UPstream::printCommTree(const label communicator)
681 {
682  const auto& comms = UPstream::whichCommunication(communicator);
683 
685  {
686  commsStruct::printGraph(Info(), comms);
687  }
688 }
689 
690 
691 Foam::label Foam::UPstream::commIntraHost()
692 {
693  if (!parRun())
694  {
695  return worldComm; // Don't know anything better to return
696  }
697  if (intraHostComm_ < 0)
698  {
699  allocateHostCommunicatorPairs();
700  }
701  return intraHostComm_;
702 }
703 
704 
705 Foam::label Foam::UPstream::commInterHost()
706 {
707  if (!parRun())
708  {
709  return worldComm; // Don't know anything better to return
710  }
711  if (interHostComm_ < 0)
712  {
713  allocateHostCommunicatorPairs();
714  }
715  return interHostComm_;
716 }
717 
720 {
721  return (intraHostComm_ >= 0 || interHostComm_ >= 0);
722 }
723 
724 
726 {
727  // Always with Pstream
728  freeCommunicator(intraHostComm_, true);
729  freeCommunicator(interHostComm_, true);
730 }
731 
732 
733 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
734 
735 bool Foam::UPstream::parRun_(false);
736 
737 bool Foam::UPstream::haveThreads_(false);
738 
739 int Foam::UPstream::msgType_(1);
740 
741 
742 Foam::wordList Foam::UPstream::allWorlds_(Foam::one{}, "");
743 Foam::labelList Foam::UPstream::worldIDs_(Foam::one{}, 0);
744 
745 
746 Foam::DynamicList<int> Foam::UPstream::myProcNo_(16);
747 Foam::DynamicList<Foam::List<int>> Foam::UPstream::procIDs_(16);
748 
749 Foam::DynamicList<Foam::label> Foam::UPstream::parentComm_(16);
750 Foam::DynamicList<Foam::label> Foam::UPstream::freeComms_;
751 
753 Foam::UPstream::linearCommunication_(16);
754 
756 Foam::UPstream::treeCommunication_(16);
757 
758 
759 Foam::label Foam::UPstream::intraHostComm_(-1);
760 Foam::label Foam::UPstream::interHostComm_(-1);
762 Foam::label Foam::UPstream::worldComm(0);
763 Foam::label Foam::UPstream::warnComm(-1);
764 
765 
766 // Predefine world and self communicator slots.
767 // These are overwritten in parallel mode (by UPstream::setParRun())
768 const Foam::label nPredefinedComm = []()
769 {
770  // 0: COMM_WORLD : commWorld() / commGlobal()
772 
773  // 1: COMM_SELF
775 
776  return Foam::UPstream::nComms();
777 }();
778 
779 
781 (
782  Foam::debug::optimisationSwitch("floatTransfer", 0)
783 );
785 (
786  "floatTransfer",
787  bool,
789 );
790 
792 (
793  Foam::debug::optimisationSwitch("nProcsSimpleSum", 0)
794 );
796 (
797  "nProcsSimpleSum",
798  int,
800 );
801 
803 (
804  Foam::debug::optimisationSwitch("nbx.min", 0)
805 );
807 (
808  "nbx.min",
809  int,
811 );
812 
814 (
815  Foam::debug::optimisationSwitch("nbx.tuning", 0)
816 );
818 (
819  "nbx.tuning",
820  int,
822 );
823 
824 
826 (
827  Foam::debug::optimisationSwitch("nPollProcInterfaces", 0)
828 );
830 (
831  "nPollProcInterfaces",
832  int,
834 );
835 
836 
838 (
839  commsTypeNames.get
840  (
841  "commsType",
843  )
844 );
845 
846 
848 namespace Foam
849 {
850  //- Registered reader for UPstream::defaultCommsType
851  class addcommsTypeToOpt
852  :
854  {
855  public:
856 
857  addcommsTypeToOpt(const char* name)
858  :
859  ::Foam::simpleRegIOobject(Foam::debug::addOptimisationObject, name)
860  {}
861 
862  virtual ~addcommsTypeToOpt() = default;
863 
864  virtual void readData(Foam::Istream& is)
865  {
868  }
869 
870  virtual void writeData(Foam::Ostream& os) const
871  {
873  }
874  };
875 
876  addcommsTypeToOpt addcommsTypeToOpt_("commsType");
877 }
879 
881 (
882  Foam::debug::optimisationSwitch("maxCommsSize", 0)
883 );
885 (
886  "maxCommsSize",
887  int,
889 );
890 
891 
893 (
894  Foam::debug::optimisationSwitch("mpiBufferSize", 0)
895 );
896 
897 
898 // ************************************************************************* //
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:376
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:89
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:718
static void writeData(Ostream &os, const Type &val)
void resize(const label len)
Adjust allocated size of list.
Definition: ListI.H:153
commsTypes
Communications types.
Definition: UPstream.H:77
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:608
static void freeCommunicator(const label communicator, const bool withComponents=true)
Free a previously allocated communicator.
Definition: UPstream.C:567
static List< int > getHostGroupIds(const label parentCommunicator)
Definition: UPstream.C:71
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:402
static int nProcsSimpleSum
Number of processors to change from linear to tree communication.
Definition: UPstream.H:381
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:619
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 constexpr label commSelf() noexcept
Communicator within the current rank only.
Definition: UPstream.H:436
static label commIntraHost()
Demand-driven: Intra-host communicator (respects any local worlds)
Definition: UPstream.C:684
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
char * data_bytes() noexcept
Return pointer to the underlying array serving as data storage,.
Definition: UListI.H:279
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:712
static int tuning_NBX_
Tuning parameters for non-blocking exchange (NBX)
Definition: UPstream.H:407
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:403
#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:387
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: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
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:661
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:1071
const string & prefix() const noexcept
Return the stream prefix.
static label allocateIntraHostCommunicator(const label parentCommunicator=worldComm)
Allocate an intra-host communicator.
Definition: UPstream.C:426
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:426
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:698
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:648
defineTypeNameAndDebug(combustionModel, 0)
static void printCommTree(const label communicator)
Debugging: print the communication tree.
Definition: UPstream.C:673
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:578
const Foam::label nPredefinedComm
Definition: UPstream.C:761
static commsTypes defaultCommsType
Default commsType.
Definition: UPstream.H:397
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: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...
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
Definition: UPstream.H:1094
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:1066
static const int mpiBufferSize
MPI buffer-size (bytes)
Definition: UPstream.H:412
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:606
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.
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:431