globalIndex.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) 2018-2024 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 Class
28  Foam::globalIndex
29 
30 Description
31  Calculates a unique integer (label so might not have enough room - 2G max)
32  for processor + local index. E.g.
33 
34  globalIndex globalFaces(mesh.nFaces());
35  label globalFacei = globalFaces.toGlobal(facei);
36 
37 SourceFiles
38  globalIndex.C
39  globalIndexI.H
40  globalIndexTemplates.C
41 
42 \*---------------------------------------------------------------------------*/
43 
44 #ifndef Foam_globalIndex_H
45 #define Foam_globalIndex_H
46 
47 #include "Pstream.H"
48 #include "CompactListList.H"
49 #include "DynamicList.H"
50 
51 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
52 
53 namespace Foam
54 {
55 
56 // Forward Declarations
57 class globalIndex;
58 
59 Istream& operator>>(Istream& is, globalIndex& gi);
60 Ostream& operator<<(Ostream& os, const globalIndex& gi);
61 
62 /*---------------------------------------------------------------------------*\
63  Class globalIndex Declaration
64 \*---------------------------------------------------------------------------*/
65 
66 class globalIndex
67 {
68  // Private Data
69 
70  //- Offset (addressing) table - like CompactListList
71  labelList offsets_;
72 
73 
74  // Private Member Functions
75 
76  //- Sort and bin. validBins contains bins with non-zero size.
78  bin
79  (
80  const labelUList& offsets,
81  const labelUList& globalIds,
82  labelList& order,
83  DynamicList<label>& validBins
84  );
85 
86  // Cannot use non-blocking for non-contiguous data.
87  // template<class Type>
88  // inline static UPstream::commsTypes getCommsType
89  // (
90  // const UPstream::commsTypes preferred
91  // = UPstream::commsTypes::nonBlocking
92  // );
93 
94  //- Report overflow at specified (non-negative) index
95  static void reportOverflowAndExit
96  (
97  const label idx,
98  const label prevOffset = -1, // The last valid offset value
99  const label count = 0 // The count to add to prevOffset
100  );
101 
102 public:
103 
104  // Public Data Types
105 
106  //- Dispatch tag:
107  //- Construct with a single (local size) entry, no communication.
108  struct gatherNone{};
109 
110  //- Dispatch tag:
111  //- Construct 'one-sided' from local sizes,
112  //- using gather but no broadcast.
113  struct gatherOnly{};
114 
115  //- Dispatch tag:
116  //- Construct 'one-sided' from the non-master local sizes
117  //- using gather but no broadcast.
118  struct gatherNonLocal{};
119 
120 
121  // Static Member Functions
122 
123  //- Return a null globalIndex (reference to a nullObject).
124  //- Behaves like an empty globalIndex
125  static const globalIndex& null() noexcept
126  {
127  return NullObjectRef<globalIndex>();
128  }
129 
130 
131  // Constructors
132 
133  //- Default construct (empty)
134  globalIndex() noexcept = default;
135 
136  //- Copy construct from a list of offsets.
137  //- No communication required
138  inline explicit globalIndex(const labelUList& listOffsets);
139 
140  //- Move construct from a list of offsets.
141  //- No communication required
142  inline explicit globalIndex(labelList&& listOffsets);
143 
144  //- Construct from a list of sizes and calculate the offsets.
145  //- No communication required
146  inline globalIndex
147  (
148  const globalIndex::gatherNone,
149  const labelUList& localSizes
150  );
151 
152  //- Construct from local size, using gather/broadcast
153  //- with default/specified communicator if parallel.
154  inline explicit globalIndex
155  (
156  const label localSize,
157  const label comm = UPstream::worldComm,
158  const bool parallel = UPstream::parRun()
159  );
160 
161  //- Construct with a single (local size) entry, no communication
162  inline globalIndex
163  (
164  const globalIndex::gatherNone,
165  const label localSize,
166  const label comm = -1
167  );
168 
169  //- Construct 'one-sided' from local sizes.
170  //- Uses UPstream::listGatherValues, but no broadcast.
171  //- Will be empty on non-master processes.
172  //
173  // \note can be used when Pstream::parRun() is false.
174  inline globalIndex
175  (
176  const globalIndex::gatherOnly,
177  const label localSize,
178  const label comm = UPstream::worldComm
179  );
180 
181  //- Construct 'one-sided' from the non-master local sizes
182  //- (ie, master size is treated as 0).
183  //- Uses UPstream::listGatherValues, but no broadcast.
184  //- Will be empty on non-master processes.
185  //
186  // \note can be used when Pstream::parRun() is false.
187  inline globalIndex
188  (
190  const label localSize,
191  const label comm = UPstream::worldComm
192  );
193 
194  //- Construct from Istream.
195  //- No communication required
196  explicit globalIndex(Istream& is);
197 
198 
199  // Member Functions
200 
201  //- Check for default constructed or total-size == 0
202  inline bool empty() const noexcept;
203 
204  //- The number of items covered by the offsets
205  inline label length() const noexcept;
206 
207  //- Global sum of localSizes. Same as totalSize()
208  FOAM_DEPRECATED_STRICT(2022-10, "totalSize() - unambiguous")
209  inline label size() const;
210 
211  //- The span size covered by the offsets, zero if empty
212  inline label span() const noexcept;
213 
214  //- The total addressed size, which corresponds to the
215  //- end offset and also the sum of all localSizes.
216  inline label totalSize() const noexcept;
217 
218  //- The local sizes. Same as localSizes()
219  inline labelList sizes() const;
220 
221  //- The local starts
222  inline const labelUList localStarts() const;
223 
224  //- The local sizes
225  labelList localSizes() const;
226 
227  //- Return start/size ranges for all data
228  List<labelRange> ranges() const;
229 
230  //- Global max of localSizes
231  inline label maxSize() const;
232 
233 
234  // Access
235 
236  //- Const-access to the offsets
237  inline const labelList& offsets() const noexcept;
238 
239  //- Write-access to the offsets, for changing after construction
240  inline labelList& offsets() noexcept;
241 
242 
243  // Dimensions
244 
245  //- True if local-only content (ie, nProcs == 1).
246  //- Such content is often created with gatherNone.
247  inline bool single() const noexcept;
248 
249  //- The number of processors covered by the offsets,
250  //- same as the primary length()
251  inline label nProcs() const noexcept;
252 
253  //- Range of process indices for all addressed offsets (processes)
254  inline labelRange allProcs() const noexcept;
255 
256  //- Range of process indices for addressed sub-offsets (processes)
257  inline labelRange subProcs() const noexcept;
258 
259  //- The value corresponding to the first offset
260  inline label begin_value() const noexcept;
261 
262  //- The value corresponding to the last offset (end offset),
263  //- which is 1 beyond the end of the range.
264  inline label end_value() const noexcept;
265 
266  //- The first offset range. It is (0,0) if globalIndex is empty
267  labelRange front() const;
268 
269  //- The last offset range. It is (0,0) if globalIndex is empty
270  labelRange back() const;
271 
272 
273  // Edit
274 
275  //- Reset to be empty (no offsets)
276  inline void clear();
277 
278  //- Change the number of entries (nProcs) in the offsets table.
279  //- Extending will fill with empty local sizes.
280  void resize(const label n);
281 
282  //- Reset from local size, using gather/broadcast
283  //- with default/specified communicator if parallel.
284  void reset
285  (
286  const label localSize,
287  const label comm = UPstream::worldComm,
288  const bool parallel = UPstream::parRun()
289  );
290 
291  //- Reset offsets from a list of local sizes,
292  //- with optional check for label overflow.
293  //- No communication required
294  void reset
295  (
296  const labelUList& counts,
297  const bool checkOverflow = false
298  );
299 
300  //- Reset to a single (local size) entry, no communication
301  inline void reset
302  (
303  const globalIndex::gatherNone,
304  const label localSize,
305  const label comm = -1
306  );
307 
308  //- Reset as 'one-sided' from local sizes.
309  //- Uses UPstream::listGatherValues, but no broadcast.
310  //- Will be empty on non-master processes.
311  //
312  // \note can be used when Pstream::parRun() is false.
313  inline void reset
314  (
315  const globalIndex::gatherOnly,
316  const label localSize,
317  const label comm = UPstream::worldComm
318  );
319 
320  //- Reset as 'one-sided' from the non-master local sizes
321  //- (ie, master size is treated as 0).
322  //- Uses UPstream::listGatherValues, but no broadcast.
323  //- Will be empty on non-master processes.
324  //
325  // \note can be used when Pstream::parRun() is false.
326  inline void reset
327  (
329  const label localSize,
330  const label comm = UPstream::worldComm
331  );
332 
333  //- Reset the globalIndex. Same as copy assignment.
334  inline void reset(const globalIndex& gi);
335 
336  //- Alter local size for given processor
337  void setLocalSize(const label proci, const label len);
338 
339 
340  // Queries and renumbering
341 
342  //- True if contained within the offsets range
343  inline bool contains(const label i) const noexcept;
344 
345  //- Start of proci data
346  inline label localStart(const label proci) const;
347 
348  //- End of proci data
349  inline label localEnd(const label proci) const;
350 
351  //- Size of proci data
352  inline label localSize(const label proci) const;
353 
354  //- The max of localSizes, excluding the specified processor
355  label maxNonLocalSize(const label proci) const;
356 
357  //- Return start/size range of proci data
358  inline labelRange range(const label proci) const;
359 
360  //- Is on processor proci
361  inline bool isLocal(const label proci, const label i) const;
362 
363  //- From local to global on proci
364  inline label toGlobal(const label proci, const label i) const;
365 
366  //- From local to global on proci
367  inline labelList toGlobal
368  (
369  const label proci,
370  const labelUList& labels
371  ) const;
372 
373  //- From local to global index on proci (inplace)
374  inline void inplaceToGlobal
375  (
376  const label proci,
377  labelUList& labels
378  ) const;
379 
380 
381  //- From global to local on proci
382  inline label toLocal(const label proci, const label i) const;
383 
384  //- Find processor with specified global id.
385  //- Check proci first, followed by binary search.
386  // \return the processor number or -1 (not found)
387  inline label findProc(const label proci, const label i) const;
388 
389  //- Find processor above proci with specified global id - binary search.
390  // \return the processor above proci or -1 otherwise
391  // (including for out-of-range indices)
392  inline label findProcAbove(const label proci, const label i) const;
393 
394  //- Find processor below proci with specified global id - binary search.
395  // Binary search.
396  // \return the processor below proci or -1 otherwise
397  // (including for out-of-range indices)
398  inline label findProcBelow(const label proci, const label i) const;
399 
400  //- Which processor does global id come from?
401  //- Checks proci first (assumed to occur reasonably frequently)
402  //- followed by a binary search.
403  //- Fatal for out-of-range indices
404  inline label whichProcID(const label proci, const label i) const;
405 
406 
407  // Queries relating to myProcNo (Caution: uses UPstream::worldComm)
408 
409  //- Local start on myProcNo()
410  inline label localStart() const;
411 
412  //- Local end on myProcNo()
413  inline label localEnd() const;
414 
415  //- Local size on myProcNo()
416  inline label localSize() const;
417 
418  //- The max of localSizes, excluding current (myProcNo) rank
419  inline label maxNonLocalSize() const;
420 
421  //- Return start/size range of local (myProcNo) data
422  inline labelRange range() const;
423 
424  //- Is on local processor
425  inline bool isLocal(const label i) const;
426 
427  //- From local to global index
428  inline label toGlobal(const label i) const;
429 
430  //- From local to global index
431  inline labelList toGlobal(const labelUList& labels) const;
432 
433  //- From local to global index (inplace)
434  inline void inplaceToGlobal(labelUList& labels) const;
435 
436  //- From global to local on current processor.
437  // FatalError if not on local processor.
438  inline label toLocal(const label i) const;
439 
440  //- Which processor does global id come from?
441  // Uses myProcNo for the initial local check.
442  inline label whichProcID(const label i) const;
443 
444 
445  // Iteration
446 
447  //- Forward input iterator with const access that is used to
448  //- iterate across the globalIndex offsets() table.
449  // The de-referenced value is the range() with (start, size),
450  // but it also provides separate index, start, size information.
451  class const_iterator
452  {
453  //- The parent class for which this is an iterator
454  const globalIndex* parent_;
455 
456  //- The index into the parent
457  label index_;
458 
459  public:
460 
461  // Constructors
462 
463  //- Construct from globalIndex list at given index
464  explicit const_iterator
465  (
466  const globalIndex* globalIdx,
467  const label i = 0
468  ) noexcept;
469 
470 
471  // Member Operators
472 
473  //- The index into the arrays
474  inline label index() const noexcept;
475 
476  //- The local start
477  inline label start() const;
478 
479  //- The local size
480  inline label size() const;
481 
482  //- The local range
483  inline labelRange range() const;
484 
485  //- The local range
486  inline labelRange operator*() const;
487 
488  inline const_iterator& operator++();
489  inline const_iterator operator++(int);
490 
491  inline const_iterator& operator--();
492  inline const_iterator operator--(int);
493 
494  inline bool operator==(const const_iterator& iter) const noexcept;
495  inline bool operator!=(const const_iterator& iter) const noexcept;
496  };
497 
498 
499  //- A const_iterator set to the beginning
500  inline const_iterator cbegin() const noexcept;
501 
502  //- A const_iterator set to beyond the end
503  inline const const_iterator cend() const noexcept;
504 
505  //- A const_iterator set to the beginning
506  inline const_iterator begin() const noexcept;
507 
508  //- A const_iterator set to beyond the end
509  inline const const_iterator end() const noexcept;
510 
511  //- Return const_iterator at offset proci from begin,
512  //- clamped to [0,nProcs] range
513  inline const_iterator cbegin(const label proci) const noexcept;
514 
515  //- Return const_iterator at offset proci from begin,
516  //- clamped to [0,nProcs] range
517  inline const_iterator begin(const label proci) const noexcept;
518 
519  // FUTURE?
520  // //- Return start/size range of proci data
521  // labelRange operator[](const label proci) const
522  // {
523  // return this->range(proci);
524  // }
525 
526 
527  // Helper Functions
528 
529  //- Calculate globally-consistent local range (offset/size)
530  //- based on the local input size(s).
531  // Effectively the same as globalIndex(localSize).range()
532  // but without constructing an extra intermediate list of offsets
533  static labelRange calcRange
534  (
535  const label localSize,
536  const label comm = UPstream::worldComm,
537  const bool checkOverflow = false
538  );
539 
540  //- Calculate globally-consistent local start offset
541  //- based on the local input size(s).
542  // Effectively the same as globalIndex(localSize).localStart()
543  // but without constructing an extra intermediate list of offsets
544  static label calcOffset
545  (
546  const label localSize,
547  const label comm = UPstream::worldComm,
548  const bool checkOverflow = false
549  );
550 
551  //- Calculate offsets from a list of local sizes,
552  //- with optional check for label overflow
553  static labelList calcOffsets
554  (
555  const labelUList& counts,
556  const bool checkOverflow = false
557  );
558 
559  //- Calculate offsets from an indirect list of local sizes,
560  //- with optional check for label overflow
561  template<class Addr>
562  static labelList calcOffsets
563  (
564  const IndirectListBase<label, Addr>& counts,
565  const bool checkOverflow = false
566  );
567 
568  //- Calculate offsets from list of lists,
569  //- with optional check for label overflow
570  template<class SubListType>
572  (
573  const List<SubListType>& lists,
574  const bool checkOverflow = false
575  );
576 
577  //- Calculate ranges (offset/size) from a list of local sizes,
578  //- with optional check for label overflow
579  static List<labelRange> calcRanges
580  (
581  const labelUList& counts,
582  const bool checkOverflow = false
583  );
584 
585  //- Collect single values in processor order on master (== procIDs[0]).
586  // Handles contiguous/non-contiguous data.
587  template<class ProcIDsContainer, class Type>
588  static void gatherValues
589  (
590  const label comm,
591  const ProcIDsContainer& procIDs,
592  const Type& localValue,
593  List<Type>& allValues,
594  const int tag = UPstream::msgType(),
595  const UPstream::commsTypes = UPstream::commsTypes::nonBlocking
596  );
597 
598  //- Collect data in processor order on master (== procIDs[0]).
599  // Handles contiguous/non-contiguous data, skips empty fields.
600  template<class ProcIDsContainer, class Type>
601  static void gather
602  (
603  const labelUList& offsets,
604  const label comm,
605  const ProcIDsContainer& procIDs,
606  const UList<Type>& fld,
607  List<Type>& allFld,
608  const int tag = UPstream::msgType(),
609  const UPstream::commsTypes = UPstream::commsTypes::nonBlocking
610  );
611 
612  //- Collect indirect data in processor order on master
613  // Handles contiguous/non-contiguous data, skips empty fields.
614  template<class ProcIDsContainer, class Type, class Addr>
615  static void gather
616  (
617  const labelUList& offsets,
618  const label comm,
619  const ProcIDsContainer& procIDs,
620  const IndirectListBase<Type, Addr>& fld,
621  List<Type>& allFld,
622  const int tag = UPstream::msgType(),
623  const UPstream::commsTypes = UPstream::commsTypes::nonBlocking
624  );
625 
626 
627  // Misc low-level gather routines
628 
629  //- Inplace collect in processor order on master (== procIDs[0]).
630  // Note: adjust naming?
631  template<class ProcIDsContainer, class Type>
632  static void gather
633  (
634  const labelUList& offsets,
635  const label comm,
636  const ProcIDsContainer& procIDs,
637  List<Type>& fld,
638  const int tag = UPstream::msgType(),
639  const UPstream::commsTypes ct = UPstream::commsTypes::nonBlocking
640  )
641  {
642  List<Type> allData;
643  gather(offsets, comm, procIDs, fld, allData, tag, ct);
644 
645  const int masterProci = procIDs.size() ? procIDs[0] : 0;
646  if (UPstream::myProcNo(comm) == masterProci)
647  {
648  fld.transfer(allData);
649  }
650  }
651 
652  //- Collect data in processor order on master (== procIDs[0]).
653  // \note the globalIndex offsets needed on master only.
654  template<class ProcIDsContainer, class Type>
655  void gather
656  (
657  const label comm,
658  const ProcIDsContainer& procIDs,
659  const UList<Type>& fld,
660  List<Type>& allFld,
661  const int tag = UPstream::msgType(),
663  ) const
664  {
665  gather(offsets_, comm, procIDs, fld, allFld, tag, ct);
666  }
667 
668  //- Inplace collect in processor order on master (== procIDs[0]).
669  // \note the globalIndex offsets needed on master only.
670  // Note: adjust naming?
671  template<class ProcIDsContainer, class Type>
672  void gather
673  (
674  const label comm,
675  const ProcIDsContainer& procIDs,
676  List<Type>& fld,
677  const int tag = UPstream::msgType(),
679  ) const
680  {
681  gather(offsets_, comm, procIDs, fld, tag, ct);
682  }
683 
684 
685  // Gather
686 
687  //- Collect data in processor order on master
688  //- (in serial: performs a simple copy).
689  // Communication with default/specified communicator, message tag.
690  template<class Type>
691  void gather
692  (
693  const UList<Type>& sendData,
694  List<Type>& allData,
695  const int tag = UPstream::msgType(),
697  const label comm = UPstream::worldComm
698  ) const;
699 
700  //- Collect data indirectly in processor order on master
701  //- (in serial: performs a simple copy).
702  // Communication with default/specified communicator, message tag.
703  template<class Type, class Addr>
704  void gather
705  (
706  const IndirectListBase<Type, Addr>& sendData,
707  List<Type>& allData,
708  const int tag = UPstream::msgType(),
710  const label comm = UPstream::worldComm
711  ) const;
712 
713  //- Collect data in processor order on master
714  //- (in serial: performs a simple copy).
715  // Communication with default/specified communicator, message tag.
716  //
717  // \return output (master), zero-sized on non-master
718  template<class Type, class OutputContainer = List<Type>>
719  OutputContainer gather
720  (
721  const UList<Type>& sendData,
722  const int tag = UPstream::msgType(),
724  const label comm = UPstream::worldComm
725  ) const;
726 
727  //- Collect data indirectly in processor order on master.
728  // Communication with default/specified communicator, message tag.
729  //
730  // \return output (master), zero-sized on non-master
731  template<class Type, class Addr, class OutputContainer = List<Type>>
732  OutputContainer gather
733  (
734  const IndirectListBase<Type, Addr>& sendData,
735  const int tag = UPstream::msgType(),
737  const label comm = UPstream::worldComm
738  ) const;
739 
740  //- Inplace collect data in processor order on master
741  //- (in serial: a no-op).
742  // Communication with default/specified communicator, message tag.
743  // After the gather, the field is zero-sized on non-master.
744  template<class Type>
745  void gatherInplace
746  (
748  List<Type>& fld,
749  const int tag = UPstream::msgType(),
751  const label comm = UPstream::worldComm
752  ) const;
753 
754  //- Use MPI_Gatherv call for contiguous data when possible
755  //- (in serial: performs a simple copy).
756  // Communication with default/specified communicator.
757  // \attention The nProcs for globalIndex and communicator
758  // must match!!
759  template<class Type, class OutputContainer = List<Type>>
760  void mpiGather
761  (
762  const UList<Type>& sendData,
764  OutputContainer& allData,
765  const label comm = UPstream::worldComm,
766 
767  // For fallback routines:
769  const int tag = UPstream::msgType()
770  ) const;
771 
772  //- Use MPI_Gatherv call for contiguous data when possible
773  //- (in serial: performs a simple copy).
774  // Communication with default/specified communicator.
775  // \attention The nProcs for globalIndex and communicator
776  // must match!!
777  //
778  // \return output (master), zero-sized on non-master
779  template<class Type, class OutputContainer = List<Type>>
780  OutputContainer mpiGather
781  (
782  const UList<Type>& sendData,
783  const label comm = UPstream::worldComm,
784 
785  // For fallback routines:
787  const int tag = UPstream::msgType()
788  ) const;
789 
790  //- Use MPI_Gatherv call to inplace collect contiguous data
791  //- when possible.
792  //- (in serial: a no-op).
793  // Communication with default/specified communicator.
794  // \attention The nProcs for globalIndex and communicator
795  // must match!!
796  //
797  // After the gather, the field is zero-sized on non-master.
798  template<class Type>
799  void mpiGatherInplace
800  (
802  List<Type>& fld,
803  const label comm = UPstream::worldComm,
804 
805  // For fallback routines:
807  const int tag = UPstream::msgType()
808  ) const;
809 
810 
811  // Gather Operations
812 
813  //- Use MPI_Gatherv call to collect contiguous data when possible
814  //- (in serial: performs a simple copy).
815  // Communication with default/specified communicator.
816  //
817  // The allData is output (master), zero-sized on non-master
818  template<class Type, class OutputContainer = List<Type>>
819  static void mpiGatherOp
820  (
821  const UList<Type>& sendData,
822  OutputContainer& allData,
823  const label comm = UPstream::worldComm,
824 
825  // For fallback routines:
827  const int tag = UPstream::msgType()
828  );
829 
830  //- Use MPI_Gatherv call to collect contiguous data when possible
831  //- (in serial: performs a simple copy).
832  // Communication with default/specified communicator.
833  //
834  // \return output (master), zero-sized on non-master
835  template<class Type, class OutputContainer = List<Type>>
836  static OutputContainer mpiGatherOp
837  (
838  const UList<Type>& sendData,
839  const label comm = UPstream::worldComm,
840 
841  // For fallback routines:
843  const int tag = UPstream::msgType()
844  );
845 
846  //- Use MPI_Gatherv call to inplace collect contiguous data
847  //- when possible.
848  //- (in serial: a no-op).
849  // Communication with default/specified communicator.
850  //
851  // After the gather, the field is zero-sized on non-master.
852  template<class Type>
853  static void mpiGatherInplaceOp
854  (
856  List<Type>& fld,
857  const label comm = UPstream::worldComm,
858 
859  // For fallback routines:
861  const int tag = UPstream::msgType()
862  );
863 
864  //- Collect data in processor order on master
865  //- (in serial: performs a simple copy).
866  // Communication with default/specified communicator, message tag.
867  template<class Type>
868  static void gatherOp
869  (
870  const UList<Type>& sendData,
872  List<Type>& allData,
873  const int tag = UPstream::msgType(),
875  const label comm = UPstream::worldComm
876  );
877 
878  //- Collect data in processor order on master
879  //- (in serial: performs a simple copy).
880  // Communication with default/specified communicator, message tag.
881  template<class Type, class Addr>
882  static void gatherOp
883  (
884  const IndirectListBase<Type, Addr>& sendData,
886  List<Type>& allData,
887  const int tag = UPstream::msgType(),
889  const label comm = UPstream::worldComm
890  );
891 
892  //- Collect and return data in processor order on master
893  //- (in serial: performs a simple copy).
894  // Communication with default/specified communicator, message tag.
895  //
896  // \return output (master), zero-sized on non-master
897  template<class Type, class OutputContainer = List<Type>>
898  static OutputContainer gatherOp
899  (
900  const UList<Type>& sendData,
901  const int tag = UPstream::msgType(),
903  const label comm = UPstream::worldComm
904  );
905 
906  //- Collect and return data in processor order on master
907  //- (in serial: performs a simple copy).
908  // Communication with default/specified communicator, message tag.
909  //
910  // \return output (master), zero-sized on non-master
911  template<class Type, class Addr, class OutputContainer = List<Type>>
912  static OutputContainer gatherOp
913  (
914  const IndirectListBase<Type, Addr>& sendData,
915  const int tag = UPstream::msgType(),
917  const label comm = UPstream::worldComm
918  );
919 
920  //- Inplace collect data in processor order on master
921  //- (in serial: a no-op).
922  // Communication with default/specified communicator, message tag.
923  //
924  // After the gather, the field is zero-sized on non-master.
925  template<class Type>
926  static void gatherInplaceOp
927  (
929  List<Type>& fld,
930  const int tag = UPstream::msgType(),
932  const label comm = UPstream::worldComm
933  );
934 
935 
936  // Scatter
937 
938  //- Distribute data in processor order.
939  // Requires fld to be correctly sized!
940  // Communication with default/specified communicator, message tag.
941  template<class ProcIDsContainer, class Type>
942  static void scatter
943  (
944  const labelUList& offsets,
945  const label comm,
946  const ProcIDsContainer& procIDs,
947  const UList<Type>& allFld,
948  UList<Type>& fld,
949  const int tag = UPstream::msgType(),
951  );
952 
953  //- Distribute data in processor order.
954  // Requires fld to be correctly sized!
955  // Communication with default/specified communicator, message tag.
956  // \note the globalIndex offsets needed on master only.
957  template<class ProcIDsContainer, class Type>
958  void scatter
959  (
960  const label comm,
961  const ProcIDsContainer& procIDs,
962  const UList<Type>& allFld,
963  UList<Type>& fld,
964  const int tag = UPstream::msgType(),
965  const UPstream::commsTypes ct =
967  ) const
968  {
969  scatter(offsets_, comm, procIDs, allFld, fld, tag, ct);
970  }
971 
972  //- Distribute data in processor order.
973  // Requires fld to be correctly sized!
974  // Communication with default/specified communicator, message tag.
975  // \note the globalIndex offsets needed on master only.
976  template<class Type>
977  void scatter
978  (
979  const UList<Type>& allData,
980  UList<Type>& localData,
981  const int tag = UPstream::msgType(),
983  const label comm = UPstream::worldComm
984  ) const;
985 
986  //- Distribute data in processor order
987  //- (in serial: performs a simple copy).
988  // Communication with default/specified communicator, message tag.
989  // \note the globalIndex offsets needed on master only.
990  template<class Type, class OutputContainer = List<Type>>
991  OutputContainer scatter
992  (
993  const UList<Type>& allData,
994  const int tag = UPstream::msgType(),
996  const label comm = UPstream::worldComm
997  ) const;
998 
999 
1000  // Scatter
1001 
1002  //- Get (potentially remote) data.
1003  //- Elements required given as global indices
1004  // Communication with default/specified communicator, message tag.
1005  template<class Type, class CombineOp>
1006  void get
1007  (
1008  List<Type>& allFld,
1009  const labelUList& globalIds,
1010  const CombineOp& cop,
1011  const label comm = UPstream::worldComm,
1012  const int tag = UPstream::msgType()
1013  ) const;
1014 
1015 
1016  // Member Operators
1017 
1018  //- Compare for equality - uses the offsets
1019  bool operator==(const globalIndex& rhs) const
1020  {
1021  return (this->offsets() == rhs.offsets());
1022  }
1023 
1024  //- Compare for inequality - uses the offsets
1025  bool operator!=(const globalIndex& rhs) const
1026  {
1027  return !(*this == rhs);
1028  }
1029 
1030  //- Compare for less-than - uses the offsets
1031  bool operator<(const globalIndex& rhs) const
1032  {
1033  return (this->offsets() < rhs.offsets());
1034  }
1035 
1036 
1037  // IOstream Operators
1038 
1039  friend Istream& operator>>(Istream& is, globalIndex& gi);
1040  friend Ostream& operator<<(Ostream& os, const globalIndex& gi);
1041 
1042 
1043  // Housekeeping
1044 
1045  //- Construct from local size, using gather/broadcast
1046  //- with default/specified communicator if parallel.
1047  FOAM_DEPRECATED_FOR(2022-03, "construct without message tag")
1048  globalIndex
1049  (
1050  const label localSize,
1051  const int tag, // message tag (unused)
1052  const label comm, // communicator
1053  const bool parallel // use parallel comms
1054  )
1055  {
1056  reset(localSize, comm, parallel);
1057  }
1058 
1059  //- Reset from local size, using gather/broadcast
1060  //- with default/specified communicator if parallel.
1061  FOAM_DEPRECATED_FOR(2022-03, "reset without message tag")
1062  void reset
1063  (
1064  const label localSize,
1065  const int tag, // message tag (unused)
1066  const label comm, // communicator
1067  const bool parallel // use parallel comms
1068  )
1069  {
1070  reset(localSize, comm, parallel);
1071  }
1072 
1073  //- Prefer localStart() to avoid confusing with offsets()
1074  FOAM_DEPRECATED_FOR(2022-02, "use localStart()")
1075  label offset(const label proci) const { return localStart(proci); }
1076 };
1077 
1078 
1079 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1080 
1081 } // End namespace Foam
1082 
1083 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1084 
1085 #include "globalIndexI.H"
1086 
1087 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1088 
1089 #ifdef NoRepository
1090  #include "globalIndexTemplates.C"
1091 #endif
1092 
1093 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
1094 
1095 #endif
1096 
1097 // ************************************************************************* //
label toLocal(const label proci, const label i) const
From global to local on proci.
Definition: globalIndexI.H:377
static labelList calcOffsets(const labelUList &counts, const bool checkOverflow=false)
Calculate offsets from a list of local sizes, with optional check for label overflow.
Definition: globalIndex.C:189
void reset(const label localSize, const label comm=UPstream::worldComm, const bool parallel=UPstream::parRun())
Reset from local size, using gather/broadcast with default/specified communicator if parallel...
Definition: globalIndex.C:346
static void mpiGatherOp(const UList< Type > &sendData, OutputContainer &allData, const label comm=UPstream::worldComm, const UPstream::commsTypes=UPstream::commsTypes::nonBlocking, const int tag=UPstream::msgType())
Use MPI_Gatherv call to collect contiguous data when possible (in serial: performs a simple copy)...
static const globalIndex & null() noexcept
Return a null globalIndex (reference to a nullObject). Behaves like an empty globalIndex.
Definition: globalIndex.H:134
commsTypes
Communications types.
Definition: UPstream.H:77
List< labelRange > ranges() const
Return start/size ranges for all data.
Definition: globalIndex.C:456
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:52
bool operator<(const globalIndex &rhs) const
Compare for less-than - uses the offsets.
Definition: globalIndex.H:1309
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
label whichProcID(const label proci, const label i) const
Which processor does global id come from? Checks proci first (assumed to occur reasonably frequently)...
Definition: globalIndexI.H:485
friend Ostream & operator<<(Ostream &os, const globalIndex &gi)
static List< labelRange > calcRanges(const labelUList &counts, const bool checkOverflow=false)
Calculate ranges (offset/size) from a list of local sizes, with optional check for label overflow...
Definition: globalIndex.C:223
Dispatch tag: Construct &#39;one-sided&#39; from local sizes, using gather but no broadcast.
Definition: globalIndex.H:118
bool contains(const label i) const noexcept
True if contained within the offsets range.
Definition: globalIndexI.H:159
label end_value() const noexcept
The value corresponding to the last offset (end offset), which is 1 beyond the end of the range...
Definition: globalIndexI.H:152
label begin_value() const noexcept
The value corresponding to the first offset.
Definition: globalIndexI.H:146
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:1252
label span() const noexcept
The span size covered by the offsets, zero if empty.
Definition: globalIndexI.H:140
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
friend Istream & operator>>(Istream &is, globalIndex &gi)
labelList localSizes() const
The local sizes.
Definition: globalIndex.C:433
Base for lists with indirect addressing, templated on the list contents type and the addressing type...
void inplaceToGlobal(const label proci, labelUList &labels) const
From local to global index on proci (inplace)
Definition: globalIndexI.H:351
labelRange range() const
Return start/size range of local (myProcNo) data.
Definition: globalIndexI.H:288
label findProcAbove(const label proci, const label i) const
Find processor above proci with specified global id - binary search.
Definition: globalIndexI.H:438
label nProcs() const noexcept
The number of processors covered by the offsets, same as the primary length()
Definition: globalIndexI.H:183
globalIndex() noexcept=default
Default construct (empty)
class FOAM_DEPRECATED_FOR(2017-05, "Foam::Enum") NamedEnum
Definition: NamedEnum.H:65
const labelList & offsets() const noexcept
Const-access to the offsets.
Definition: globalIndexI.H:205
bool single() const noexcept
True if local-only content (ie, nProcs == 1). Such content is often created with gatherNone.
Definition: globalIndexI.H:127
static void mpiGatherInplaceOp(List< Type > &fld, const label comm=UPstream::worldComm, const UPstream::commsTypes=UPstream::commsTypes::nonBlocking, const int tag=UPstream::msgType())
Use MPI_Gatherv call to inplace collect contiguous data when possible. (in serial: a no-op)...
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of &#39;true&#39; entries.
Definition: BitOps.H:73
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:61
label totalSize() const noexcept
The total addressed size, which corresponds to the end offset and also the sum of all localSizes...
Definition: globalIndexI.H:165
Dispatch tag: Construct with a single (local size) entry, no communication.
Definition: globalIndex.H:111
tmp< faMatrix< Type > > operator*(const areaScalarField::Internal &, const faMatrix< Type > &)
bool operator==(const globalIndex &rhs) const
Compare for equality - uses the offsets.
Definition: globalIndex.H:1293
static labelList calcListOffsets(const List< SubListType > &lists, const bool checkOverflow=false)
Calculate offsets from list of lists, with optional check for label overflow.
void mpiGather(const UList< Type > &sendData, OutputContainer &allData, const label comm=UPstream::worldComm, const UPstream::commsTypes=UPstream::commsTypes::nonBlocking, const int tag=UPstream::msgType()) const
Use MPI_Gatherv call for contiguous data when possible (in serial: performs a simple copy)...
Forward input iterator with const access that is used to iterate across the globalIndex offsets() tab...
Definition: globalIndex.H:600
const_iterator cbegin() const noexcept
A const_iterator set to the beginning.
Definition: globalIndexI.H:679
label offset(const label proci) const
Prefer localStart() to avoid confusing with offsets()
Definition: globalIndex.H:1359
const_iterator begin() const noexcept
A const_iterator set to the beginning.
Definition: globalIndexI.H:693
label length() const noexcept
The number of items covered by the offsets.
Definition: globalIndexI.H:133
void mpiGatherInplace(List< Type > &fld, const label comm=UPstream::worldComm, const UPstream::commsTypes=UPstream::commsTypes::nonBlocking, const int tag=UPstream::msgType()) const
Use MPI_Gatherv call to inplace collect contiguous data when possible. (in serial: a no-op)...
Istream & operator>>(Istream &, directionInfo &)
label size() const
Global sum of localSizes. Same as totalSize()
Definition: globalIndexI.H:171
void setLocalSize(const label proci, const label len)
Alter local size for given processor.
Definition: globalIndex.C:415
bool isLocal(const label proci, const label i) const
Is on processor proci.
Definition: globalIndexI.H:294
#define FOAM_DEPRECATED_STRICT(since, replacement)
Definition: stdFoam.H:55
A packed storage of objects of type <T> using an offset table for access.
const direction noexcept
Definition: Scalar.H:258
labelList sizes() const
The local sizes. Same as localSizes()
Definition: globalIndexI.H:177
static void gatherValues(const label comm, const ProcIDsContainer &procIDs, const Type &localValue, List< Type > &allValues, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking)
Collect single values in processor order on master (== procIDs[0]).
label findProc(const label proci, const label i) const
Find processor with specified global id. Check proci first, followed by binary search.
Definition: globalIndexI.H:399
OBJstream os(runTime.globalPath()/outputName)
const const_iterator end() const noexcept
A const_iterator set to beyond the end.
Definition: globalIndexI.H:700
labelRange subProcs() const noexcept
Range of process indices for addressed sub-offsets (processes)
Definition: globalIndexI.H:197
labelRange allProcs() const noexcept
Range of process indices for all addressed offsets (processes)
Definition: globalIndexI.H:189
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< ' ';}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< ' ';}gmvFile<< nl;for(const word &name :lagrangianScalarNames){ IOField< scalar > fld(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces)
Definition: boundaryPatch.C:77
label toGlobal(const label proci, const label i) const
From local to global on proci.
Definition: globalIndexI.H:308
static void gatherInplaceOp(List< Type > &fld, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm)
Inplace collect data in processor order on master (in serial: a no-op).
label findProcBelow(const label proci, const label i) const
Find processor below proci with specified global id - binary search.
Definition: globalIndexI.H:461
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
void gatherInplace(List< Type > &fld, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm) const
Inplace collect data in processor order on master (in serial: a no-op).
static labelRange calcRange(const label localSize, const label comm=UPstream::worldComm, const bool checkOverflow=false)
Calculate globally-consistent local range (offset/size) based on the local input size(s).
Definition: globalIndex.C:60
bool empty() const noexcept
Check for default constructed or total-size == 0.
Definition: globalIndexI.H:120
label n
static void gather(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
label localStart() const
Local start on myProcNo()
Definition: globalIndexI.H:239
const const_iterator cend() const noexcept
A const_iterator set to beyond the end.
Definition: globalIndexI.H:686
static void gatherOp(const UList< Type > &sendData, List< Type > &allData, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm)
Collect data in processor order on master (in serial: performs a simple copy).
labelRange back() const
The last offset range. It is (0,0) if globalIndex is empty.
Definition: globalIndex.C:517
static label calcOffset(const label localSize, const label comm=UPstream::worldComm, const bool checkOverflow=false)
Calculate globally-consistent local start offset based on the local input size(s).
Definition: globalIndex.C:125
label maxSize() const
Global max of localSizes.
Definition: globalIndexI.H:269
Inter-processor communications stream.
Definition: UPstream.H:65
void clear()
Reset to be empty (no offsets)
Definition: globalIndexI.H:217
bool operator!=(const globalIndex &rhs) const
Compare for inequality - uses the offsets.
Definition: globalIndex.H:1301
label localEnd() const
Local end on myProcNo()
Definition: globalIndexI.H:251
Namespace for OpenFOAM.
Dispatch tag: Construct &#39;one-sided&#39; from the non-master local sizes using gather but no broadcast...
Definition: globalIndex.H:125
static void scatter(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &allFld, UList< Type > &fld, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking)
Distribute data in processor order.
label maxNonLocalSize() const
The max of localSizes, excluding current (myProcNo) rank.
Definition: globalIndexI.H:276
void resize(const label n)
Change the number of entries (nProcs) in the offsets table. Extending will fill with empty local size...
Definition: globalIndex.C:332
label localSize() const
Local size on myProcNo()
Definition: globalIndexI.H:263
const labelUList localStarts() const
The local starts.
Definition: globalIndexI.H:223
labelRange front() const
The first offset range. It is (0,0) if globalIndex is empty.
Definition: globalIndex.C:506