59#ifndef Foam_globalIndex_H
60#define Foam_globalIndex_H
102 static void reportOverflowAndExit
105 const label prevOffset = -1,
106 const label count = 0
110 static inline void checkOverflowAndExit
113 const label prevOffset,
118 inline labelRange range_impl(label proci)
const noexcept;
149 struct gatherNonLocal{};
188 const label comm =
UPstream::worldComm,
189 const
bool parallel =
UPstream::parRun()
197 int communicator = -1
209 const label comm =
UPstream::worldComm
222 const label comm =
UPstream::worldComm
318 const label comm =
UPstream::worldComm,
319 const
bool parallel =
UPstream::parRun()
328 const
bool checkOverflow = false
336 int communicator = -1
348 const label comm =
UPstream::worldComm
361 const label comm =
UPstream::worldComm
377 inline label
localStart(const label proci) const;
383 inline label
localSize(const label proci) const;
395 inline
bool isLocal(const label proci, const label i) const;
398 inline label
toGlobal(const label proci, const label i) const;
416 inline label
toLocal(const label proci, const label i) const;
421 inline label
findProc(const label proci, const label i) const;
426 inline label
findProcAbove(const label proci, const label i) const;
432 inline label
findProcBelow(const label proci, const label i) const;
438 inline label
whichProcID(const label proci, const label i) const;
462 inline
bool isLocal(const label i) const;
465 inline label
toGlobal(const label i) const;
475 inline label
toLocal(const label i) const;
511 inline label index() const
noexcept;
514 inline label start() const;
517 inline label
size() const;
570 template<class IntType>
574 const label comm =
UPstream::worldComm
581 template<class IntType>
586 [[maybe_unused]] const
bool checkOverflow
591 if constexpr (
sizeof(IntType) <
sizeof(int64_t))
608 template<
class IntType>
624 template<
class IntType>
625 std::enable_if_t<std::is_integral_v<IntType>, IntRange<IntType>>
630 const bool checkOverflow
635 return IntRange<IntType>(start,
localSize);
643 template<
class IntType>
655 const bool checkOverflow =
false
664 const bool checkOverflow =
false
669 template<
class SubListType>
673 const bool checkOverflow =
false
681 const bool checkOverflow =
false
695 const bool absoluteLocalNodeOffsets =
false
704 template<
class ProcIDsContainer,
class Type>
709 const ProcIDsContainer& procIDs,
710 const Type& localValue,
717 template<
class ProcIDsContainer,
class Type>
722 const ProcIDsContainer& procIDs,
732 template<
class ProcIDsContainer,
class Type,
class Addr>
737 const ProcIDsContainer& procIDs,
746 template<
class ProcIDsContainer,
class Type>
751 const ProcIDsContainer& procIDs,
759 template<
class ProcIDsContainer,
class Type>
763 const ProcIDsContainer& procIDs,
773 template<
class ProcIDsContainer,
class Type>
777 const ProcIDsContainer& procIDs,
807 template<
class Type,
class Addr>
824 template<
class Type,
class OutputContainer = List<Type>>
838 template<
class Type,
class Addr,
class OutputContainer = List<Type>>
866 template<
class Type,
class OutputContainer = List<Type>>
871 OutputContainer& allData,
886 template<
class Type,
class OutputContainer = List<Type>>
926 template<
class Type,
class OutputContainer = List<Type>>
930 OutputContainer& allData,
943 template<
class Type,
class OutputContainer = List<Type>>
990 template<
class Type,
class Addr>
1006 template<
class Type,
class OutputContainer = List<Type>>
1021 template<
class Type,
class Addr,
class OutputContainer = List<Type>>
1036 template<
class Type>
1052 template<
class ProcIDsContainer,
class Type>
1057 const ProcIDsContainer& procIDs,
1068 template<
class ProcIDsContainer,
class Type>
1072 const ProcIDsContainer& procIDs,
1079 scatter(offsets_, comm, procIDs, allFld,
fld, tag, commsType);
1086 template<
class Type>
1100 template<
class Type,
class OutputContainer = List<Type>>
1116 template<
class Type,
class CombineOp>
1121 const CombineOp& cop,
1138 return !(*
this ==
rhs);
1201 #include "globalIndex.txx"
Info<< nl;Info<< "Write faMesh in vtk format:"<< nl;{ vtk::uindirectPatchWriter writer(aMesh.patch(), fileName(aMesh.time().globalPath()/vtkBaseFileName));writer.writeGeometry();globalIndex procAddr(aMesh.nFaces());labelList cellIDs;if(UPstream::master()) { cellIDs.resize(procAddr.totalSize());for(const labelRange &range :procAddr.ranges()) { auto slice=cellIDs.slice(range);slice=identity(range);} } writer.beginCellData(4);writer.writeProcIDs();writer.write("cellID", cellIDs);writer.write("area", aMesh.S().field());writer.write("normal", aMesh.faceAreaNormals());writer.beginPointData(1);writer.write("normal", aMesh.pointAreaNormals());Info<< " "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edges")));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
A packed storage of objects of type <T> using an offset table for access.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Base for lists with indirect addressing, templated on the list contents type and the addressing type....
An interval of (signed) integers defined by a start and a size.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
A tuple of integers comprising start, size, total.
An Ostream is an abstract base class for all output systems (streams, files, token lists,...
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Inter-processor communications stream.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
commsTypes
Communications types.
@ nonBlocking
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
static int & msgType() noexcept
Message tag of standard messages.
static bool is_parallel(const label communicator=worldComm)
True if parallel algorithm or exchange is required.
static label worldComm
Communicator for all ranks. May differ from commGlobal() if local worlds are in use.
Forward input iterator with const access that is used to iterate across the globalIndex offsets() tab...
const_iterator & operator--()
const_iterator & operator++()
label index() const noexcept
The index into the arrays.
const_iterator(const globalIndex *globalIdx, const label i=0) noexcept
Construct from globalIndex list at given index.
label start() const
The local start.
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
globalIndex() noexcept=default
Default construct (empty).
label size_type
The type that can represent the size.
bool single() const noexcept
True if local-only content (ie, nProcs == 1). Such content is often created with gatherNone.
label localEnd(const label proci) const
End of proci data.
const const_iterator end() const noexcept
A const_iterator set to beyond the end.
void gatherInplace(List< Type > &fld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm) const
Inplace collect data in processor order on master (in serial: a no-op).
bool operator<(const globalIndex &rhs) const
Compare for less-than - uses the offsets.
label maxSize() const
Global max of localSizes.
void scatter(const label comm, const ProcIDsContainer &procIDs, const UList< Type > &allFld, UList< Type > &fld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking) const
Distribute data in processor order.
static void gather(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const IndirectListBase< Type, Addr > &fld, UList< Type > &allFld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking)
Collect indirect data in processor order on master.
static labelList calcOffsets(const labelUList &counts, const bool checkOverflow=false)
Calculate offsets from a list of local sizes, with optional check for label overflow.
label totalSize() const noexcept
The total addressed size, which corresponds to the end offset and also the sum of all localSizes.
static void gatherInplaceOp(List< Type > &fld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm)
Inplace collect data in processor order on master (in serial: a no-op).
void gather(const UList< Type > &sendData, List< Type > &allData, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm) const
Collect data in processor order on master (in serial: performs a simple copy).
label localSize() const
Local size on myProcNo().
const_iterator cbegin() const noexcept
A const_iterator set to the beginning.
static void gather(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &fld, UList< Type > &allFld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking)
Collect data in processor order on master (== procIDs[0]).
static OutputContainer gatherOp(const UList< Type > &sendData, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm)
Collect and return data in processor order on master (in serial: performs a simple copy).
static void mpiGatherOp(const UList< Type > &sendData, OutputContainer &allData, const label comm=UPstream::worldComm, UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const int tag=UPstream::msgType())
Use MPI_Gatherv call to collect contiguous data when possible (in serial: performs a simple copy).
const const_iterator cend() const noexcept
A const_iterator set to beyond the end.
static IntType calcOffset(IntType localSize, const label comm=UPstream::worldComm)
Based on the local input size(s), calculate a globally-consistent local start offset.
void get(List< Type > &allFld, const labelUList &globalIds, const CombineOp &cop, const label comm=UPstream::worldComm, const int tag=UPstream::msgType()) const
Get (potentially remote) data. Elements required given as global indices.
bool empty() const noexcept
Check for default constructed or total-size == 0.
static List< IntType > calcRecvSizes(IntType localSize, const label comm=UPstream::worldComm)
Get the receive sizes. On master the length == nProcs and element [0] corresponds to the max of all o...
friend Ostream & operator<<(Ostream &os, const globalIndex &gi)
labelRange range() const
Return start/size range of local (myProcNo) data.
static OutputContainer mpiGatherOp(const UList< Type > &sendData, const label comm=UPstream::worldComm, UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const int tag=UPstream::msgType())
Use MPI_Gatherv call to collect contiguous data when possible (in serial: performs a simple copy).
List< labelRange > ranges() const
Return start/size ranges for all data.
static const globalIndex & null() noexcept
Return a null globalIndex (reference to a nullObject). Behaves like an empty globalIndex.
label findProcBelow(const label proci, const label i) const
Find processor below proci with specified global id - binary search.
label toLocal(const label proci, const label i) const
From global to local on proci.
label maxNonLocalSize(const label proci) const
The max of localSizes, excluding the specified processor.
OffsetRange< label > slice(label proci) const noexcept
Return start/size/total slab addressing for proci data.
label span() const noexcept
The span size covered by the offsets, zero if empty.
label localStart() const
Local start on myProcNo().
label findProc(const label proci, const label i) const
Find processor with specified global id. Check proci first, followed by binary search.
label nProcs() const noexcept
The number of processors covered by the offsets, same as the primary length().
void inplaceToGlobal(const label proci, labelUList &labels) const
From local to global index on proci (inplace).
labelList localSizes() const
The local sizes.
const labelUList localStarts() const
The local starts.
static labelList calcOffsets(const IndirectListBase< label, Addr > &counts, const bool checkOverflow=false)
Calculate offsets from an indirect list of local sizes, with optional check for label overflow.
void resize(const label n)
Change the number of entries (nProcs) in the offsets table. Extending will fill with empty local size...
static void gatherOp(const UList< Type > &sendData, List< Type > &allData, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm)
Collect data in processor order on master (in serial: performs a simple copy).
labelRange range(label proci) const noexcept
Return start/size range of proci data.
label end_value() const noexcept
The value corresponding to the last offset (end offset), which is 1 beyond the end of the range.
label length() const noexcept
The number of items covered by the offsets.
label offset(const label proci) const
Prefer localStart() to avoid confusing with offsets().
labelRange subProcs() const noexcept
Range of process indices for addressed sub-offsets (processes).
void mpiGather(const UList< Type > &sendData, OutputContainer &allData, const label comm=UPstream::worldComm, UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const int tag=UPstream::msgType()) const
Use MPI_Gatherv call for contiguous data when possible (in serial: performs a simple copy).
void gather(const IndirectListBase< Type, Addr > &sendData, List< Type > &allData, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm) const
Collect data indirectly in processor order on master (in serial: performs a simple copy).
static void scatter(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, const UList< Type > &allFld, UList< Type > &fld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking)
Distribute data in processor order.
void gather(const label comm, const ProcIDsContainer &procIDs, const UList< Type > &fld, List< Type > &allFld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking) const
Collect data in processor order on master (== procIDs[0]).
OutputContainer mpiGather(const UList< Type > &sendData, const label comm=UPstream::worldComm, UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const int tag=UPstream::msgType()) const
Use MPI_Gatherv call for contiguous data when possible (in serial: performs a simple copy).
void setLocalSize(const label proci, const label len)
Alter local size for given processor.
bool splitNodeOffsets(labelList &interNodeOffsets, labelList &localNodeOffsets, const label communicator=UPstream::worldComm, const bool absoluteLocalNodeOffsets=false) const
Split the top-level offsets into inter-node and local-node components suitable to a two-stage hierarc...
static std::enable_if_t< std::is_integral_v< IntType >, IntRange< IntType > > calcRange(IntType localSize, const label comm=UPstream::worldComm)
Based on the local input size(s), calculate a globally-consistent range (offset/size).
label whichProcID(const label proci, const label i) const
Which processor does global id come from? Checks proci first (assumed to occur reasonably frequently)...
bool isLocal(const label proci, const label i) const
Is on processor proci.
bool contains(const label i) const noexcept
True if contained within the offsets range.
labelList sizes() const
The local sizes. Same as localSizes().
static void gatherInplace(const labelUList &offsets, const label comm, const ProcIDsContainer &procIDs, List< Type > &fld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking)
Inplace collect in processor order on master (== procIDs[0]).
labelRange front() const
The first offset range. It is (0,0) if globalIndex is empty.
label value_type
Type of values contained.
label toGlobal(const label proci, const label i) const
From local to global on proci.
static void mpiGatherInplaceOp(List< Type > &fld, const label comm=UPstream::worldComm, UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const int tag=UPstream::msgType())
Use MPI_Gatherv call to inplace collect contiguous data when possible. (in serial: a no-op).
label localStart(const label proci) const
Start of proci data.
static labelList calcListOffsets(const List< SubListType > &lists, const bool checkOverflow=false)
Calculate offsets from list of lists, with optional check for label overflow.
label size() const noexcept
Global sum of localSizes. Same as totalSize().
labelRange back() const
The last offset range. It is (0,0) if globalIndex is empty.
labelRange allProcs() const noexcept
Range of process indices for all addressed offsets (processes).
void clear()
Reset to be empty (no offsets).
void scatter(const UList< Type > &allData, UList< Type > &localData, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm) const
Distribute data in processor order.
void gatherInplace(const label comm, const ProcIDsContainer &procIDs, List< Type > &fld, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking) const
Inplace collect in processor order on master (== procIDs[0]).
OutputContainer gather(const UList< Type > &sendData, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm) const
Collect data in processor order on master (in serial: performs a simple copy).
static std::enable_if_t< std::is_integral_v< IntType >, IntRange< IntType > > calcRange(IntType localSize, const label comm, const bool checkOverflow)
Based on the local input size(s), calculate a globally-consistent range (offset/size)....
const_iterator begin() const noexcept
A const_iterator set to the beginning.
void reset(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.
label localSize(const label proci) const
Size of proci data.
label begin_value() const noexcept
The value corresponding to the first offset.
void mpiGatherInplace(List< Type > &fld, const label comm=UPstream::worldComm, UPstream::commsTypes commsType=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).
friend Istream & operator>>(Istream &is, globalIndex &gi)
const labelList & offsets() const noexcept
Const-access to the offsets.
OutputContainer scatter(const UList< Type > &allData, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm) const
Distribute data in processor order (in serial: performs a simple copy).
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.
bool operator!=(const globalIndex &rhs) const
Compare for inequality - uses the offsets.
label findProcAbove(const label proci, const label i) const
Find processor above proci with specified global id - binary search.
static void gatherOp(const IndirectListBase< Type, Addr > &sendData, List< Type > &allData, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm)
Collect data in processor order on master (in serial: performs a simple copy).
static List< Type > listGatherValues(const label comm, const ProcIDsContainer &procIDs, const Type &localValue, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking)
Collect single values in processor order on master (== procIDs[0]).
OutputContainer gather(const IndirectListBase< Type, Addr > &sendData, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm) const
Collect data indirectly in processor order on master.
static OutputContainer gatherOp(const IndirectListBase< Type, Addr > &sendData, const int tag=UPstream::msgType(), UPstream::commsTypes commsType=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm)
Collect and return data in processor order on master (in serial: performs a simple copy).
bool operator==(const globalIndex &rhs) const
Compare for equality - uses the offsets.
A range or interval of labels defined by a start and a size.
limits reset(1/(limits.max()+VSMALL), 1/(limits.min()+VSMALL))
OBJstream os(runTime.globalPath()/outputName)
const T & NullObjectRef() noexcept
Const reference (of type T) to the nullObject.
List< label > labelList
A List of labels.
tmp< faMatrix< Type > > operator*(const areaScalarField::Internal &, const faMatrix< Type > &)
Ostream & operator<<(Ostream &, const boundaryPatch &p)
Write boundaryPatch as dictionary entries (without surrounding braces).
Istream & operator>>(Istream &, directionInfo &)
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
UList< label > labelUList
A UList of labels.
#define FOAM_DEPRECATED_FOR(since, replacement)
#define FOAM_DEPRECATED_STRICT(since, replacement)
Dispatch tag: Construct 'one-sided' from the non-master local sizes using gather but no broadcast.
Dispatch tag: Construct with a single (local size) entry, no communication.
Dispatch tag: Construct 'one-sided' from local sizes, using gather but no broadcast.