38 const bool checkOverflow
43 const label len = counts.
size();
50 for (label i = 0; i < len; ++i)
52 const label
count = counts[i];
57 if (checkOverflow && start <
values[i])
69 template<
class SubListType>
74 const bool checkOverflow
79 const label len = lists.
size();
86 for (label i = 0; i < len; ++i)
93 if (checkOverflow && start <
values[i])
105 template<
class ProcIDsContainer,
class Type>
109 const ProcIDsContainer& procIDs,
110 const Type& localValue,
132 const int masterProci = procIDs.size() ? procIDs[0] : 0;
137 allValues[0] = localValue;
139 for (label i = 1; i < procIDs.size(); ++i)
147 reinterpret_cast<char*>(&allValues[i]),
155 IPstream fromProc(commsType, procIDs[i], 0, tag, comm);
156 fromProc >> allValues[i];
164 if (is_contiguous<Type>::value)
170 reinterpret_cast<const char*>(&localValue),
178 OPstream toMaster(commsType, masterProci, 0, tag, comm);
179 toMaster << localValue;
191 template<
class ProcIDsContainer,
class Type>
196 const ProcIDsContainer& procIDs,
197 const UList<Type>&
fld,
210 !is_contiguous<Type>::value
219 const int masterProci = procIDs.size() ? procIDs[0] : 0;
223 allFld.resize_nocopy(off.back());
230 SubList<Type>(allFld, off[1]-off[0], off[0]) =
231 SubList<Type>(
fld, off[1]-off[0]);
233 for (label i = 1; i < procIDs.size(); ++i)
235 SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
237 if (procSlot.empty())
241 else if (is_contiguous<Type>::value)
247 procSlot.data_bytes(),
248 procSlot.size_bytes(),
255 IPstream fromProc(commsType, procIDs[i], 0, tag, comm);
256 fromProc >> procSlot;
266 else if (is_contiguous<Type>::value)
280 OPstream toMaster(commsType, masterProci, 0, tag, comm);
293 template<
class ProcIDsContainer,
class Type,
class Addr>
298 const ProcIDsContainer& procIDs,
299 const IndirectListBase<Type, Addr>&
fld,
307 if (is_contiguous<Type>::value)
330 !is_contiguous<Type>::value
339 const int masterProci = procIDs.size() ? procIDs[0] : 0;
343 allFld.resize_nocopy(off.back());
348 SubList<Type> localSlot(allFld, off[1]-off[0], off[0]);
349 if (!localSlot.empty())
355 for (label i = 1; i < procIDs.size(); ++i)
357 SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
359 if (procSlot.empty())
365 IPstream fromProc(commsType, procIDs[i], 0, tag, comm);
366 fromProc >> procSlot;
378 OPstream toMaster(commsType, masterProci, 0, tag, comm);
429 template<
class Type,
class Addr>
432 const IndirectListBase<Type, Addr>& sendData,
465 template<
class Type,
class OutputContainer>
468 const UList<Type>& sendData,
474 OutputContainer allData;
475 gather(sendData, allData, tag, commsType, comm);
480 template<
class Type,
class Addr,
class OutputContainer>
489 OutputContainer allData;
490 gather(sendData, allData, tag, commsType, comm);
507 gather(
fld, allData, tag, commsType, comm);
511 fld.transfer(allData);
522 template<
class Type,
class OutputContainer>
525 const UList<Type>& sendData,
526 OutputContainer& allData,
554 List<int> recvCounts;
555 List<int> recvOffsets;
560 if (is_contiguous<Type>::value)
562 if (is_contiguous_scalar<Type>::value)
565 nCmpts =
static_cast<int>(
sizeof(Type)/
sizeof(scalar));
567 else if (is_contiguous_label<Type>::value)
570 nCmpts =
static_cast<int>(
sizeof(Type)/
sizeof(label));
575 nCmpts =
static_cast<int>(
sizeof(Type));
581 const globalIndex& globalAddr = *
this;
583 if (globalAddr.totalSize() > (INT_MAX/nCmpts))
591 const label nproc = globalAddr.nProcs();
593 allData.resize_nocopy(globalAddr.totalSize());
595 recvCounts.resize(nproc);
596 recvOffsets.resize(nproc+1);
598 for (label proci = 0; proci < nproc; ++proci)
600 recvCounts[proci] = globalAddr.localSize(proci)*nCmpts;
601 recvOffsets[proci] = globalAddr.localStart(proci)*nCmpts;
603 recvOffsets[nproc] = globalAddr.totalSize()*nCmpts;
608 SubList<Type>(allData, globalAddr.range(0)) =
609 SubList<Type>(sendData, globalAddr.range(0));
624 sendData.cdata_bytes(),
625 sendData.size_bytes(),
626 allData.data_bytes(),
635 typedef scalar cmptType;
639 reinterpret_cast<const cmptType*>(sendData.cdata()),
640 (sendData.size()*nCmpts),
641 reinterpret_cast<cmptType*>(allData.data()),
650 typedef label cmptType;
654 reinterpret_cast<const cmptType*>(sendData.cdata()),
655 (sendData.size()*nCmpts),
656 reinterpret_cast<cmptType*>(allData.data()),
686 template<
class Type,
class OutputContainer>
689 const UList<Type>& sendData,
696 OutputContainer allData;
697 mpiGather(sendData, allData, comm, commsType, tag);
715 mpiGather(
fld, allData, comm, commsType, tag);
719 fld.transfer(allData);
730 template<
class Type,
class OutputContainer>
733 const UList<Type>& sendData,
734 OutputContainer& allData,
744 globalIndex(globalIndex::gatherOnly{}, sendData.size(), comm)
745 .mpiGather(sendData, allData, comm, commsType, tag);
755 template<
class Type,
class OutputContainer>
758 const UList<Type>& sendData,
765 OutputContainer allData;
766 mpiGatherOp(sendData, allData, comm, commsType, tag);
784 mpiGatherOp(
fld, allData, comm, commsType, tag);
788 fld.transfer(allData);
802 const UList<Type>& sendData,
812 globalIndex(globalIndex::gatherOnly{}, sendData.size(), comm)
813 .
gather(sendData, allData, tag, commsType, comm);
823 template<
class Type,
class Addr>
826 const IndirectListBase<Type, Addr>& sendData,
836 globalIndex(globalIndex::gatherOnly{}, sendData.size(), comm)
837 .
gather(sendData, allData, tag, commsType, comm);
847 template<
class Type,
class OutputContainer>
850 const UList<Type>& sendData,
856 OutputContainer allData;
857 gatherOp(sendData, allData, tag, commsType, comm);
862 template<
class Type,
class Addr,
class OutputContainer>
871 OutputContainer allData;
872 gatherOp(sendData, allData, tag, commsType, comm);
896 template<
class ProcIDsContainer,
class Type>
901 const ProcIDsContainer& procIDs,
902 const UList<Type>& allFld,
915 !is_contiguous<Type>::value
924 const int masterProci = procIDs.size() ? procIDs[0] : 0;
928 for (label i = 1; i < procIDs.size(); ++i)
930 const SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
932 if (procSlot.empty())
936 else if (is_contiguous<Type>::value)
942 procSlot.cdata_bytes(),
943 procSlot.size_bytes(),
950 OPstream toProc(commsType, procIDs[i], 0, tag, comm);
960 SubList<Type>(
fld, off[1]-off[0]) =
961 SubList<Type>(allFld, off[1]-off[0], off[0]);
973 else if (is_contiguous<Type>::value)
987 IPstream fromMaster(commsType, masterProci, 0, tag, comm);
1000 template<
class Type>
1003 const UList<Type>& allData,
1004 UList<Type>& localData,
1027 localData.deepCopy(allData);
1032 template<
class Type,
class OutputContainer>
1035 const UList<Type>& allData,
1048 UPstream::listScatterValues<label>(this->localSizes(), comm)
1051 OutputContainer localData(
count);
1052 this->
scatter(allData, localData, tag, commsType, comm);
1059 return OutputContainer(allData);
1064 template<
class Type,
class CombineOp>
1069 const CombineOp& cop,
1074 allFld.resize_nocopy(globalIds.size());
1076 if (globalIds.size())
1082 CompactListList<label> bins
1084 bin(offsets(), globalIds, order, validBins)
1090 for (
const auto proci : validBins)
1094 for (label& val : localIDs)
1096 val = toLocal(proci, val);
1099 UOPstream
os(proci, sendBufs);
1102 sendBufs.finishedSends();
1107 for (
const int proci : sendBufs.allProcs())
1109 if (sendBufs.recvDataCount(proci))
1111 UIPstream is(proci, sendBufs);
1115 List<Type>
fld(localIDs.size());
1118 UOPstream
os(proci, returnBufs);
1122 returnBufs.finishedSends();
1125 for (
const auto proci : validBins)
1127 label start = bins.offsets()[proci];
1128 const SubList<label> es
1131 bins.offsets()[proci+1]-start,
1134 UIPstream is(proci, returnBufs);
1137 UIndirectList<Type>(allFld, es) =
fld;
static labelList calcOffsets(const labelUList &counts, const bool checkOverflow=false)
Calculate offsets from a list of local sizes, with optional check for label overflow.
void size(const label n)
Older name for setAddressableSize.
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 label read(const UPstream::commsTypes commsType, const int fromProcNo, char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm, UPstream::Request *req=nullptr)
Read buffer contents from given processor.
commsTypes
Communications types.
static label nRequests() noexcept
Number of outstanding requests (on the internal list of requests)
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
static bool & parRun() noexcept
Test if this a parallel run.
Dispatch tag: Construct 'one-sided' from local sizes, using gather but no broadcast.
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
Base for lists with indirect addressing, templated on the list contents type and the addressing type...
static void waitRequests()
Wait for all requests to finish.
UList< label > labelUList
A UList of labels.
void gather(const Type *sendData, Type *recvData, int count, MPI_Datatype datatype, const label comm, UPstream::Request *req=nullptr, label *requestID=nullptr)
Input inter-processor communications stream.
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)...
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
"scheduled" : (MPI_Send, MPI_Recv)
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)...
void clear()
Clear the list, i.e. set size to zero.
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)...
static void gather(const char *sendData, int sendCount, char *recvData, const UList< int > &recvCounts, const UList< int > &recvOffsets, const label communicator=worldComm)
Receive variable length char data from all ranks.
label size() const noexcept
The number of elements in the list.
void scatter(const Type *sendData, Type *recvData, int count, MPI_Datatype datatype, const label comm, UPstream::Request *req=nullptr, label *requestID=nullptr)
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)
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.
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))
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).
A template class to specify that a data type can be considered as being contiguous in memory...
static bool broadcast(char *buf, const std::streamsize bufSize, const label communicator, const int rootProcNo=masterNo())
Broadcast buffer contents to all processes in given communicator. The sizes must match on all process...
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
static bool write(const UPstream::commsTypes commsType, const int toProcNo, const char *buf, const std::streamsize bufSize, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm, UPstream::Request *req=nullptr, const UPstream::sendModes sendMode=UPstream::sendModes::normal)
Write buffer contents to given processor.
"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 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]).
List< label > labelList
A List of labels.
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).
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.