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