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-2022 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 class labelRange;
59 
60 Istream& operator>>(Istream& is, globalIndex& gi);
61 Ostream& operator<<(Ostream& os, const globalIndex& gi);
62 
63 
64 /*---------------------------------------------------------------------------*\
65  Class globalIndex Declaration
66 \*---------------------------------------------------------------------------*/
67 
68 class globalIndex
69 {
70  // Private Data
71 
72  //- Start of proci. Size is nProcs()+1. (so like CompactListList)
73  labelList offsets_;
74 
75 
76  // Private Member Functions
77 
78  //- Sort and bin. validBins contains bins with non-zero size.
80  bin
81  (
82  const labelUList& offsets,
83  const labelUList& globalIds,
84  labelList& order,
85  DynamicList<label>& validBins
86  );
87 
88  //- Report overflow at specified index
89  static void reportOverflowAndExit
90  (
91  const label idx,
92  const labelUList& localLens = labelUList::null()
93  );
94 
95 public:
96 
97  // Public Data Types
98 
99  //- Disambiguation tag (list construction dispatch)
100  enum accessType : char { OFFSETS, SIZES };
101 
102  //- Dispatch tag.
103  //- Construct with a single (local size) entry, no communication.
104  struct gatherNone{};
105 
106  //- Dispatch tag.
107  //- Construct 'one-sided' from local sizes,
108  //- using gather but no broadcast.
109  struct gatherOnly{};
110 
111  //- Dispatch tag.
112  //- Construct 'one-sided' from the non-master local sizes
113  //- using gather but no broadcast.
114  struct gatherNonLocal{};
115 
117  // Constructors
118 
119  //- Default construct (empty)
120  globalIndex() noexcept = default;
121 
122  //- Copy construct from a list of offsets.
123  //- No communication required
124  inline explicit globalIndex(const labelUList& listOffsets);
125 
126  //- Move construct from a list of offsets.
127  //- No communication required
128  inline explicit globalIndex(labelList&& listOffsets);
129 
130  //- Copy construct from a list of offsets or sizes.
131  //- No communication required
132  inline globalIndex
133  (
134  const labelUList& offsetsOrSizes,
135  enum accessType accType
136  );
137 
138  //- Construct from local size, using gather/broadcast
139  //- with default/specified communicator if parallel.
140  inline explicit globalIndex
141  (
142  const label localSize,
143  const label comm = UPstream::worldComm,
144  const bool parallel = UPstream::parRun()
145  );
146 
147  //- Construct with a single (local size) entry, no communication
148  inline globalIndex
149  (
150  const globalIndex::gatherNone,
151  const label localSize,
152  const label comm = -1
153  );
154 
155  //- Construct 'one-sided' from local sizes.
156  //- Uses UPstream::listGatherValues, but no broadcast.
157  //- Will be empty on non-master processes.
158  //
159  // \note can be used when Pstream::parRun() is false.
160  inline globalIndex
161  (
162  const globalIndex::gatherOnly,
163  const label localSize,
164  const label comm = UPstream::worldComm
165  );
166 
167  //- Construct 'one-sided' from the non-master local sizes
168  //- (ie, master size is treated as 0).
169  //- Uses UPstream::listGatherValues, but no broadcast.
170  //- Will be empty on non-master processes.
171  //
172  // \note can be used when Pstream::parRun() is false.
173  inline globalIndex
174  (
176  const label localSize,
177  const label comm = UPstream::worldComm
178  );
179 
180  //- Construct from Istream.
181  //- No communication required
182  explicit globalIndex(Istream& is);
183 
184 
185  // Member Functions
186 
187  //- Check for default constructed or global sum == 0
188  inline bool empty() const;
189 
190  //- Global sum of localSizes. Same as totalSize()
191  inline label size() const;
192 
193  //- Global sum of localSizes.
194  inline label totalSize() const;
195 
196  //- The local sizes. Same as localSizes()
197  inline labelList sizes() const;
198 
199  //- The local starts
200  inline const labelUList localStarts() const;
201 
202  //- The local sizes
203  labelList localSizes() const;
204 
205  //- Global max of localSizes
206  inline label maxSize() const;
207 
208 
209  // Access
210 
211  //- Const-access to the offsets
212  inline const labelList& offsets() const noexcept;
213 
214  //- Write-access to the offsets, for changing after construction
215  inline labelList& offsets() noexcept;
216 
217 
218  // Dimensions
219 
220  //- The number of processors covered by the offsets
221  inline label nProcs() const noexcept;
222 
223  //- Range of process indices for all addressed offsets (processes)
224  inline labelRange allProcs() const noexcept;
225 
226  //- Range of process indices for addressed sub-offsets (processes)
227  inline labelRange subProcs() const noexcept;
228 
229 
230  // Edit
231 
232  //- Reset to be empty (no offsets)
233  inline void clear();
234 
235  //- Reset from local size, using gather/broadcast
236  //- with default/specified communicator if parallel.
237  void reset
238  (
239  const label localSize,
240  const label comm = UPstream::worldComm,
241  const bool parallel = UPstream::parRun()
242  );
243 
244  //- Reset from list of local sizes,
245  //- with optional check for label overflow.
246  //- No communication required
247  void reset
248  (
249  const labelUList& localLens,
250  const bool checkOverflow = false
251  );
252 
253  //- Reset to a single (local size) entry, no communication
254  inline void reset
255  (
256  const globalIndex::gatherNone,
257  const label localSize,
258  const label comm = -1
259  );
260 
261  //- Reset as 'one-sided' from local sizes.
262  //- Uses UPstream::listGatherValues, but no broadcast.
263  //- Will be empty on non-master processes.
264  //
265  // \note can be used when Pstream::parRun() is false.
266  inline void reset
267  (
268  const globalIndex::gatherOnly,
269  const label localSize,
270  const label comm = UPstream::worldComm
271  );
272 
273  //- Reset as 'one-sided' from the non-master local sizes
274  //- (ie, master size is treated as 0).
275  //- Uses UPstream::listGatherValues, but no broadcast.
276  //- Will be empty on non-master processes.
277  //
278  // \note can be used when Pstream::parRun() is false.
279  inline void reset
280  (
282  const label localSize,
283  const label comm = UPstream::worldComm
284  );
285 
286  //- Alter local size for given processor
287  void setLocalSize(const label proci, const label len);
288 
289 
290  // Queries
291 
292  // Queries relating to my processor (using world communicator)
293 
294  //- My local start
295  inline label localStart() const;
296 
297  //- My local size
298  inline label localSize() const;
299 
300  //- The max of localSizes, excluding current processor
301  inline label maxNonLocalSize() const;
302 
303  //- Return start/size range of local processor data
304  inline labelRange range() const;
305 
306  //- Return start/size ranges for all data
307  List<labelRange> ranges() const;
308 
309  //- Is on local processor
310  inline bool isLocal(const label i) const;
311 
312  //- From local to global index
313  inline label toGlobal(const label i) const;
314 
315  //- From local to global index
316  inline labelList toGlobal(const labelUList& labels) const;
317 
318  //- From local to global index (inplace)
319  inline void inplaceToGlobal(labelUList& labels) const;
320 
321  //- From global to local on current processor.
322  // FatalError if not on local processor.
323  inline label toLocal(const label i) const;
324 
325 
326  // Global (off-processor) queries
327 
328  //- Start of proci data
329  inline label localStart(const label proci) const;
330 
331  //- Size of proci data
332  inline label localSize(const label proci) const;
333 
334  //- The max of localSizes, excluding the specified processor
335  label maxNonLocalSize(const label proci) const;
336 
337  //- Return start/size range of proci data
338  inline labelRange range(const label proci) const;
339 
340  //- Is on processor proci
341  inline bool isLocal(const label proci, const label i) const;
342 
343  //- From local to global on proci
344  inline label toGlobal(const label proci, const label i) const;
345 
346  //- From local to global on proci
347  inline labelList toGlobal
348  (
349  const label proci,
350  const labelUList& labels
351  ) const;
352 
353  //- From local to global index on proci (inplace)
354  inline void inplaceToGlobal
355  (
356  const label proci,
357  labelUList& labels
358  ) const;
359 
360 
361  //- From global to local on proci
362  inline label toLocal(const label proci, const label i) const;
363 
364  //- Which processor does global id come from?
365  // Does an initial check for isLocal first (assumed to occur
366  // reasonably frequently) followed by a binary search.
367  //- Fatal for out of range ids (eg, negative or >= totalSize()
368  inline label whichProcID(const label i) const;
369 
370 
371  // Iteration
372 
373  //- Forward input iterator with const access
374  class const_iterator
375  {
376  //- The parent class for which this is an iterator
377  const globalIndex* parent_;
378 
379  //- The index into the parent
380  label proci_;
381 
382 
383  public:
384 
385  // Constructors
386 
387  //- Construct from globalIndex list at given index
388  explicit const_iterator
389  (
390  const globalIndex* globalIdx,
391  const label proci = 0
392  ) noexcept;
393 
394 
395  // Member Operators
396 
397  //- The associated local proc
398  inline label proci() const noexcept;
399 
400  //- The local start
401  inline label start() const;
402 
403  //- The local size
404  inline label size() const;
405 
406  //- The local range
407  inline labelRange range() const;
408 
409  //- The local range
410  inline labelRange operator*() const;
411 
412  inline const_iterator& operator++();
413  inline const_iterator operator++(int);
414 
415  inline const_iterator& operator--();
416  inline const_iterator operator--(int);
417 
418  inline bool operator==(const const_iterator& iter) const noexcept;
419  inline bool operator!=(const const_iterator& iter) const noexcept;
420  };
421 
422 
423  //- A const_iterator set to the beginning
424  inline const_iterator cbegin() const noexcept;
425 
426  //- A const_iterator set to beyond the end
427  inline const const_iterator cend() const noexcept;
428 
429  //- A const_iterator set to the beginning
430  inline const_iterator begin() const noexcept;
431 
432  //- A const_iterator set to beyond the end
433  inline const const_iterator end() const noexcept;
434 
435 
436  // Helper Functions
437 
438  //- Calculate offsets from a list of local sizes,
439  //- with optional check for label overflow
440  static labelList calcOffsets
441  (
442  const labelUList& localLens,
443  const bool checkOverflow = false
444  );
445 
446  //- Calculate offsets from list of lists,
447  //- with optional check for label overflow
448  template<class SubListType>
450  (
451  const List<SubListType>& lists,
452  const bool checkOverflow = false
453  );
454 
455  //- Calculate ranges (offset/size) from a list of local sizes,
456  //- with optional check for label overflow
457  static List<labelRange> calcRanges
458  (
459  const labelUList& localLens,
460  const bool checkOverflow = false
461  );
462 
463  //- Collect single values in processor order on master (== procIDs[0]).
464  // Handles contiguous/non-contiguous data.
465  template<class ProcIDsContainer, class Type>
466  static void gatherValues
467  (
468  const label comm,
469  const ProcIDsContainer& procIDs,
470  const Type& localValue,
471  List<Type>& allValues,
472  const int tag = UPstream::msgType(),
473  const UPstream::commsTypes = UPstream::commsTypes::nonBlocking
474  );
475 
476  //- Collect data in processor order on master (== procIDs[0]).
477  // Handles contiguous/non-contiguous data, skips empty fields.
478  template<class ProcIDsContainer, class Type>
479  static void gather
480  (
481  const labelUList& offsets,
482  const label comm,
483  const ProcIDsContainer& procIDs,
484  const UList<Type>& fld,
485  List<Type>& allFld,
486  const int tag = UPstream::msgType(),
487  const UPstream::commsTypes = UPstream::commsTypes::nonBlocking
488  );
489 
490  //- Collect indirect data in processor order on master
491  // Handles contiguous/non-contiguous data, skips empty fields.
492  template<class Type, class Addr>
493  static void gather
494  (
495  const labelUList& offsets,
496  const label comm,
497  const UList<int>& procIDs,
498  const IndirectListBase<Type, Addr>& fld,
499  List<Type>& allFld,
500  const int tag = UPstream::msgType(),
501  const UPstream::commsTypes = UPstream::commsTypes::nonBlocking
502  );
503 
504 
505  // Misc low-level gather routines
506 
507  //- Inplace collect in processor order on master (== procIDs[0]).
508  // Note: adjust naming?
509  template<class ProcIDsContainer, class Type>
510  static void gather
511  (
512  const labelUList& offsets,
513  const label comm,
514  const ProcIDsContainer& procIDs,
515  List<Type>& fld,
516  const int tag = UPstream::msgType(),
517  const UPstream::commsTypes ct = UPstream::commsTypes::nonBlocking
518  )
519  {
520  List<Type> allData;
521  gather(offsets, comm, procIDs, fld, allData, tag, ct);
522  if (Pstream::myProcNo(comm) == procIDs[0])
523  {
524  fld.transfer(allData);
525  }
526  }
527 
528  //- Collect data in processor order on master (== procIDs[0]).
529  // \note the globalIndex offsets needed on master only.
530  template<class ProcIDsContainer, class Type>
531  void gather
532  (
533  const label comm,
534  const ProcIDsContainer& procIDs,
535  const UList<Type>& fld,
536  List<Type>& allFld,
537  const int tag = UPstream::msgType(),
539  ) const
540  {
541  gather(offsets_, comm, procIDs, fld, allFld, tag, ct);
542  }
543 
544  //- Inplace collect in processor order on master (== procIDs[0]).
545  // \note the globalIndex offsets needed on master only.
546  // Note: adjust naming?
547  template<class ProcIDsContainer, class Type>
548  void gather
549  (
550  const label comm,
551  const ProcIDsContainer& procIDs,
552  List<Type>& fld,
553  const int tag = UPstream::msgType(),
555  ) const
556  {
557  gather(offsets_, comm, procIDs, fld, tag, ct);
558  }
559 
560 
561  // Gather
562 
563  //- Collect data in processor order on master
564  //- (in serial: performs a simple copy).
565  // Communication with default/specified communicator, message tag.
566  template<class Type>
567  void gather
568  (
569  const UList<Type>& sendData,
570  List<Type>& allData,
571  const int tag = UPstream::msgType(),
573  const label comm = UPstream::worldComm
574  ) const;
575 
576  //- Collect data indirectly in processor order on master
577  //- (in serial: performs a simple copy).
578  // Communication with default/specified communicator, message tag.
579  template<class Type, class Addr>
580  void gather
581  (
582  const IndirectListBase<Type, Addr>& sendData,
583  List<Type>& allData,
584  const int tag = UPstream::msgType(),
586  const label comm = UPstream::worldComm
587  ) const;
588 
589  //- Collect data in processor order on master
590  //- (in serial: performs a simple copy).
591  // Communication with default/specified communicator, message tag.
592  //
593  // \return output (master), zero-sized on non-master
594  template<class Type, class OutputContainer = List<Type>>
595  OutputContainer gather
596  (
597  const UList<Type>& sendData,
598  const int tag = UPstream::msgType(),
600  const label comm = UPstream::worldComm
601  ) const;
602 
603  //- Collect data indirectly in processor order on master.
604  // Communication with default/specified communicator, message tag.
605  //
606  // \return output (master), zero-sized on non-master
607  template<class Type, class Addr, class OutputContainer = List<Type>>
608  OutputContainer gather
609  (
610  const IndirectListBase<Type, Addr>& sendData,
611  const int tag = UPstream::msgType(),
613  const label comm = UPstream::worldComm
614  ) const;
615 
616  //- Inplace collect data in processor order on master
617  //- (in serial: a no-op).
618  // Communication with default/specified communicator, message tag.
619  // After the gather, the field is zero-sized on the slaves.
620  template<class Type>
621  void gatherInplace
622  (
623  List<Type>& fld,
624  const int tag = UPstream::msgType(),
626  const label comm = UPstream::worldComm
627  ) const;
628 
629  //- Use MPI_Gatherv call for contiguous data when possible
630  //- (in serial: performs a simple copy).
631  // Communication with default/specified communicator.
632  // \attention The nProcs for globalIndex and communicator
633  // must match!!
634  //
635  // The allData is output (master), zero-sized on non-master
636  template<class Type, class OutputContainer = List<Type>>
637  void mpiGather
638  (
639  const UList<Type>& sendData,
640  OutputContainer& allData,
641  const label comm = UPstream::worldComm,
642 
643  // For fallback routines:
645  const int tag = UPstream::msgType()
646  ) const;
647 
648  //- Use MPI_Gatherv call for contiguous data when possible
649  //- (in serial: performs a simple copy).
650  // Communication with default/specified communicator.
651  // \attention The nProcs for globalIndex and communicator
652  // must match!!
653  //
654  // \return output (master), zero-sized on non-master
655  template<class Type, class OutputContainer = List<Type>>
656  OutputContainer mpiGather
657  (
658  const UList<Type>& sendData,
659  const label comm = UPstream::worldComm,
660 
661  // For fallback routines:
663  const int tag = UPstream::msgType()
664  ) const;
665 
666  //- Use MPI_Gatherv call to inplace collect contiguous data
667  //- when possible.
668  //- (in serial: a no-op).
669  // Communication with default/specified communicator.
670  // \attention The nProcs for globalIndex and communicator
671  // must match!!
672  //
673  // After the gather, the field is zero-sized on non-master.
674  template<class Type>
675  void mpiGatherInplace
676  (
677  List<Type>& fld,
678  const label comm = UPstream::worldComm,
679 
680  // For fallback routines:
682  const int tag = UPstream::msgType()
683  ) const;
684 
685 
686  // Gather Operations
687 
688  //- Use MPI_Gatherv call to collect contiguous data when possible
689  //- (in serial: performs a simple copy).
690  // Communication with default/specified communicator.
691  //
692  // The allData is output (master), zero-sized on non-master
693  template<class Type, class OutputContainer = List<Type>>
694  static void mpiGatherOp
695  (
696  const UList<Type>& sendData,
697  OutputContainer& allData,
698  const label comm = UPstream::worldComm,
699 
700  // For fallback routines:
702  const int tag = UPstream::msgType()
703  );
704 
705  //- Use MPI_Gatherv call to collect contiguous data when possible
706  //- (in serial: performs a simple copy).
707  // Communication with default/specified communicator.
708  //
709  // \return output (master), zero-sized on non-master
710  template<class Type, class OutputContainer = List<Type>>
711  static OutputContainer mpiGatherOp
712  (
713  const UList<Type>& sendData,
714  const label comm = UPstream::worldComm,
715 
716  // For fallback routines:
718  const int tag = UPstream::msgType()
719  );
720 
721  //- Use MPI_Gatherv call to inplace collect contiguous data
722  //- when possible.
723  //- (in serial: a no-op).
724  // Communication with default/specified communicator.
725  //
726  // After the gather, the field is zero-sized on non-master.
727  template<class Type>
728  static void mpiGatherInplaceOp
729  (
730  List<Type>& fld,
731  const label comm = UPstream::worldComm,
732 
733  // For fallback routines:
735  const int tag = UPstream::msgType()
736  );
737 
738  //- Collect data in processor order on master
739  //- (in serial: performs a simple copy).
740  // Communication with default/specified communicator, message tag.
741  //
742  // The allFld is output (master), zero-sized on non-master
743  template<class Type>
744  static void gatherOp
745  (
746  const UList<Type>& sendData,
747  List<Type>& allData,
748  const int tag = UPstream::msgType(),
750  const label comm = UPstream::worldComm
751  );
752 
753  //- Collect data in processor order on master
754  //- (in serial: performs a simple copy).
755  // Communication with default/specified communicator, message tag.
756  //
757  // The allFld is output (master), zero-sized on non-master
758  template<class Type, class Addr>
759  static void gatherOp
760  (
761  const IndirectListBase<Type, Addr>& sendData,
762  List<Type>& allData,
763  const int tag = UPstream::msgType(),
765  const label comm = UPstream::worldComm
766  );
767 
768  //- Collect and return data in processor order on master
769  //- (in serial: performs a simple copy).
770  // Communication with default/specified communicator, message tag.
771  //
772  // \return output (master), zero-sized on non-master
773  template<class Type, class OutputContainer = List<Type>>
774  static OutputContainer gatherOp
775  (
776  const UList<Type>& sendData,
777  const int tag = UPstream::msgType(),
779  const label comm = UPstream::worldComm
780  );
781 
782  //- Collect and return data in processor order on master
783  //- (in serial: performs a simple copy).
784  // Communication with default/specified communicator, message tag.
785  //
786  // \return output (master), zero-sized on non-master
787  template<class Type, class Addr, class OutputContainer = List<Type>>
788  static OutputContainer gatherOp
789  (
790  const IndirectListBase<Type, Addr>& sendData,
791  const int tag = UPstream::msgType(),
793  const label comm = UPstream::worldComm
794  );
795 
796  //- Inplace collect data in processor order on master
797  //- (in serial: a no-op).
798  // Communication with default/specified communicator, message tag.
799  //
800  // After the gather, the field is zero-sized on the slaves.
801  template<class Type>
802  static void gatherInplaceOp
803  (
804  List<Type>& fld,
805  const int tag = UPstream::msgType(),
807  const label comm = UPstream::worldComm
808  );
809 
810 
811  // Scatter
812 
813  //- Distribute data in processor order.
814  // Requires fld to be correctly sized!
815  // Communication with default/specified communicator, message tag.
816  template<class ProcIDsContainer, class Type>
817  static void scatter
818  (
819  const labelUList& offsets,
820  const label comm,
821  const ProcIDsContainer& procIDs,
822  const UList<Type>& allFld,
823  UList<Type>& fld,
824  const int tag = UPstream::msgType(),
826  );
827 
828  //- Distribute data in processor order.
829  // Requires fld to be correctly sized!
830  // Communication with default/specified communicator, message tag.
831  // \note the globalIndex offsets needed on master only.
832  template<class ProcIDsContainer, class Type>
833  void scatter
834  (
835  const label comm,
836  const ProcIDsContainer& procIDs,
837  const UList<Type>& allFld,
838  UList<Type>& fld,
839  const int tag = UPstream::msgType(),
840  const UPstream::commsTypes ct =
842  ) const
843  {
844  scatter(offsets_, comm, procIDs, allFld, fld, tag, ct);
845  }
846 
847  //- Distribute data in processor order.
848  // Requires fld to be correctly sized!
849  // Communication with default/specified communicator, message tag.
850  // \note the globalIndex offsets needed on master only.
851  template<class Type>
852  void scatter
853  (
854  const UList<Type>& allData,
855  UList<Type>& localData,
856  const int tag = UPstream::msgType(),
858  const label comm = UPstream::worldComm
859  ) const;
860 
861  //- Distribute data in processor order
862  //- (in serial: performs a simple copy).
863  // Communication with default/specified communicator, message tag.
864  // \note the globalIndex offsets needed on master only.
865  template<class Type, class OutputContainer = List<Type>>
866  OutputContainer scatter
867  (
868  const UList<Type>& allData,
869  const int tag = UPstream::msgType(),
871  const label comm = UPstream::worldComm
872  ) const;
873 
874 
875  // Scatter
876 
877  //- Get (potentially remote) data.
878  //- Elements required given as global indices
879  // Communication with default/specified communicator, message tag.
880  template<class Type, class CombineOp>
881  void get
882  (
883  List<Type>& allFld,
884  const labelUList& globalIds,
885  const CombineOp& cop,
886  const label comm = UPstream::worldComm,
887  const int tag = UPstream::msgType()
888  ) const;
889 
890 
891  // IOstream Operators
892 
893  friend Istream& operator>>(Istream& is, globalIndex& gi);
894  friend Ostream& operator<<(Ostream& os, const globalIndex& gi);
895 
896 
897  // Housekeeping
898 
899  //- Construct with a single (local size) entry, no communication
901  (
902  const label localSize,
904  const label comm = -1
905  )
906  :
907  globalIndex(gatherNone{}, localSize, comm)
908  {}
909 
910  //- Construct 'one-sided' from local sizes.
912  (
913  const label localSize,
914  const globalIndex::gatherOnly,
915  const label comm = UPstream::worldComm
916  )
917  :
918  globalIndex(gatherOnly{}, localSize, comm)
919  {}
920 
921  //- Construct from local size, using gather/broadcast
922  //- with default/specified communicator if parallel.
923  FOAM_DEPRECATED_FOR(2022-03, "construct without message tag")
925  (
926  const label localSize,
927  const int tag, // message tag (unused)
928  const label comm, // communicator
929  const bool parallel // use parallel comms
930  )
931  {
932  reset(localSize, comm, parallel);
933  }
934 
935  //- Reset from local size, using gather/broadcast
936  //- with default/specified communicator if parallel.
937  FOAM_DEPRECATED_FOR(2022-03, "reset without message tag")
938  void reset
939  (
940  const label localSize,
941  const int tag, // message tag (unused)
942  const label comm, // communicator
943  const bool parallel // use parallel comms
944  )
945  {
946  reset(localSize, comm, parallel);
947  }
948 
949  //- Prefer localStart() to avoid confusing with offsets()
950  FOAM_DEPRECATED_FOR(2022-02, "use localStart()")
951  label offset(const label proci) const { return localStart(proci); }
952 
953  //- Reset as 'one-sided' from local sizes [gather, but no broadcast]
954  //- Will be empty on non-master processes.
955  //
956  // \note can be used when Pstream::parRun() is false.
957  void reset
958  (
959  const label localSize,
960  const globalIndex::gatherOnly,
961  const label comm = UPstream::worldComm
962  )
963  {
964  reset(globalIndex::gatherOnly{}, localSize, comm);
965  }
966 };
967 
968 
969 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
970 
971 } // End namespace Foam
972 
973 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
974 
975 #include "globalIndexI.H"
976 
977 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
978 
979 #ifdef NoRepository
980  #include "globalIndexTemplates.C"
981 #endif
982 
983 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
984 
985 #endif
986 
987 // ************************************************************************* //
bool isLocal(const label i) const
Is on local processor.
Definition: globalIndexI.H:262
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:188
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 List< labelRange > calcRanges(const labelUList &localLens, const bool checkOverflow=false)
Calculate ranges (offset/size) from a list of local sizes, with optional check for label overflow...
Definition: globalIndex.C:84
commsTypes
Types of communications.
Definition: UPstream.H:66
List< labelRange > ranges() const
Return start/size ranges for all data.
Definition: globalIndex.C:296
A range or interval of labels defined by a start and a size.
Definition: labelRange.H:51
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
friend Ostream & operator<<(Ostream &os, const globalIndex &gi)
Dispatch tag. Construct &#39;one-sided&#39; from local sizes, using gather but no broadcast.
Definition: globalIndex.H:116
static int & msgType() noexcept
Message tag of standard messages.
Definition: UPstream.H:806
static int myProcNo(const label communicator=worldComm)
Number of this process (starting from masterNo() = 0)
Definition: UPstream.H:688
void inplaceToGlobal(labelUList &labels) const
From local to global index (inplace)
Definition: globalIndexI.H:321
static label worldComm
Default world communicator (all processors). May differ from globalComm if local worlds are in use...
Definition: UPstream.H:361
friend Istream & operator>>(Istream &is, globalIndex &gi)
labelList localSizes() const
The local sizes.
Definition: globalIndex.C:273
Base for lists with indirect addressing, templated on the list contents type and the addressing type...
labelRange range() const
Return start/size range of local processor data.
Definition: globalIndexI.H:250
label nProcs() const noexcept
The number of processors covered by the offsets.
Definition: globalIndexI.H:156
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:179
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)...
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
Dispatch tag. Construct with a single (local size) entry, no communication.
Definition: globalIndex.H:109
tmp< faMatrix< Type > > operator*(const areaScalarField::Internal &, const faMatrix< Type > &)
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.
Definition: globalIndex.H:487
const_iterator cbegin() const noexcept
A const_iterator set to the beginning.
Definition: globalIndexI.H:521
label offset(const label proci) const
Prefer localStart() to avoid confusing with offsets()
Definition: globalIndex.H:1185
const_iterator begin() const noexcept
A const_iterator set to the beginning.
Definition: globalIndexI.H:535
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:144
void setLocalSize(const label proci, const label len)
Alter local size for given processor.
Definition: globalIndex.C:255
label toLocal(const label i) const
From global to local on current processor.
Definition: globalIndexI.H:343
label whichProcID(const label i) const
Which processor does global id come from?
Definition: globalIndexI.H:349
A packed storage unstructured matrix of objects of type <T> using an offset table for access...
An Ostream is an abstract base class for all output systems (streams, files, token lists...
Definition: Ostream.H:55
const direction noexcept
Definition: Scalar.H:258
labelList sizes() const
The local sizes. Same as localSizes()
Definition: globalIndexI.H:150
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]).
OBJstream os(runTime.globalPath()/outputName)
static const UList< label > & null()
Return a UList reference to a nullObject.
Definition: UListI.H:46
const const_iterator end() const noexcept
A const_iterator set to beyond the end.
Definition: globalIndexI.H:542
labelRange subProcs() const noexcept
Range of process indices for addressed sub-offsets (processes)
Definition: globalIndexI.H:171
labelRange allProcs() const noexcept
Range of process indices for all addressed offsets (processes)
Definition: globalIndexI.H:163
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:76
label toGlobal(const label i) const
From local to global index.
Definition: globalIndexI.H:278
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).
"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).
accessType
Disambiguation tag (list construction dispatch)
Definition: globalIndex.H:103
bool operator!=(const eddy &a, const eddy &b)
Definition: eddy.H:299
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
My local start.
Definition: globalIndexI.H:213
bool empty() const
Check for default constructed or global sum == 0.
Definition: globalIndexI.H:131
const const_iterator cend() const noexcept
A const_iterator set to beyond the end.
Definition: globalIndexI.H:528
tmp< faMatrix< Type > > operator==(const faMatrix< Type > &, const faMatrix< Type > &)
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).
label maxSize() const
Global max of localSizes.
Definition: globalIndexI.H:231
Inter-processor communications stream.
Definition: UPstream.H:54
void clear()
Reset to be empty (no offsets)
Definition: globalIndexI.H:191
static labelList calcOffsets(const labelUList &localLens, const bool checkOverflow=false)
Calculate offsets from a list of local sizes, with optional check for label overflow.
Definition: globalIndex.C:51
Namespace for OpenFOAM.
Dispatch tag. Construct &#39;one-sided&#39; from the non-master local sizes using gather but no broadcast...
Definition: globalIndex.H:123
label totalSize() const
Global sum of localSizes.
Definition: globalIndexI.H:137
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 processor.
Definition: globalIndexI.H:238
label localSize() const
My local size.
Definition: globalIndexI.H:225
const labelUList localStarts() const
The local starts.
Definition: globalIndexI.H:197