57 const bool checkOverflow
62 const label len = counts.
size();
69 for (label i = 0; i < len; ++i)
71 const label
count = counts[i];
76 if (checkOverflow && start <
values[i])
88 template<
class SubListType>
93 const bool checkOverflow
98 const label len = lists.
size();
105 for (label i = 0; i < len; ++i)
112 if (checkOverflow && start <
values[i])
124 template<
class ProcIDsContainer,
class Type>
128 const ProcIDsContainer& procIDs,
129 const Type& localValue,
150 const int masterProci = procIDs.size() ? procIDs[0] : 0;
155 allValues[0] = localValue;
157 for (label i = 1; i < procIDs.size(); ++i)
165 reinterpret_cast<char*>(&allValues[i]),
181 if (is_contiguous<Type>::value)
187 reinterpret_cast<const char*>(&localValue),
207 template<
class ProcIDsContainer,
class Type>
212 const ProcIDsContainer& procIDs,
213 const UList<Type>&
fld,
225 !is_contiguous<Type>::value
234 const int masterProci = procIDs.size() ? procIDs[0] : 0;
238 allFld.resize_nocopy(off.back());
245 SubList<Type>(allFld, off[1]-off[0], off[0]) =
246 SubList<Type>(
fld, off[1]-off[0]);
248 for (label i = 1; i < procIDs.size(); ++i)
250 SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
252 if (procSlot.empty())
256 else if (is_contiguous<Type>::value)
262 procSlot.data_bytes(),
263 procSlot.size_bytes(),
280 else if (is_contiguous<Type>::value)
306 template<
class ProcIDsContainer,
class Type,
class Addr>
311 const ProcIDsContainer& procIDs,
312 const IndirectListBase<Type, Addr>&
fld,
320 if (is_contiguous<Type>::value)
342 !is_contiguous<Type>::value
351 const int masterProci = procIDs.size() ? procIDs[0] : 0;
355 allFld.resize_nocopy(off.back());
360 SubList<Type> localSlot(allFld, off[1]-off[0], off[0]);
361 if (!localSlot.empty())
367 for (label i = 1; i < procIDs.size(); ++i)
369 SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
371 if (procSlot.empty())
439 template<
class Type,
class Addr>
442 const IndirectListBase<Type, Addr>& sendData,
475 template<
class Type,
class OutputContainer>
478 const UList<Type>& sendData,
484 OutputContainer allData;
485 gather(sendData, allData, tag, commsType, comm);
490 template<
class Type,
class Addr,
class OutputContainer>
499 OutputContainer allData;
500 gather(sendData, allData, tag, commsType, comm);
517 gather(
fld, allData, tag, commsType, comm);
521 fld.transfer(allData);
532 template<
class Type,
class OutputContainer>
535 const UList<Type>& sendData,
536 OutputContainer& allData,
564 List<int> recvCounts;
565 List<int> recvOffsets;
570 if (is_contiguous<Type>::value)
572 if (is_contiguous_scalar<Type>::value)
575 nCmpts =
static_cast<int>(
sizeof(Type)/
sizeof(scalar));
577 else if (is_contiguous_label<Type>::value)
580 nCmpts =
static_cast<int>(
sizeof(Type)/
sizeof(label));
585 nCmpts =
static_cast<int>(
sizeof(Type));
591 const globalIndex& globalAddr = *
this;
593 if (globalAddr.totalSize() > (INT_MAX/nCmpts))
601 const label nproc = globalAddr.nProcs();
603 allData.resize_nocopy(globalAddr.totalSize());
605 recvCounts.resize(nproc);
606 recvOffsets.resize(nproc+1);
608 for (label proci = 0; proci < nproc; ++proci)
610 recvCounts[proci] = globalAddr.localSize(proci)*nCmpts;
611 recvOffsets[proci] = globalAddr.localStart(proci)*nCmpts;
613 recvOffsets[nproc] = globalAddr.totalSize()*nCmpts;
618 SubList<Type>(allData, globalAddr.range(0)) =
619 SubList<Type>(sendData, globalAddr.range(0));
634 sendData.cdata_bytes(),
635 sendData.size_bytes(),
636 allData.data_bytes(),
645 typedef scalar cmptType;
649 reinterpret_cast<const cmptType*>(sendData.cdata()),
650 (sendData.size()*nCmpts),
651 reinterpret_cast<cmptType*>(allData.data()),
660 typedef label cmptType;
664 reinterpret_cast<const cmptType*>(sendData.cdata()),
665 (sendData.size()*nCmpts),
666 reinterpret_cast<cmptType*>(allData.data()),
696 template<
class Type,
class OutputContainer>
699 const UList<Type>& sendData,
706 OutputContainer allData;
707 mpiGather(sendData, allData, comm, commsType, tag);
725 mpiGather(
fld, allData, comm, commsType, tag);
729 fld.transfer(allData);
740 template<
class Type,
class OutputContainer>
743 const UList<Type>& sendData,
744 OutputContainer& allData,
754 globalIndex(globalIndex::gatherOnly{}, sendData.size(), comm)
755 .mpiGather(sendData, allData, comm, commsType, tag);
765 template<
class Type,
class OutputContainer>
768 const UList<Type>& sendData,
775 OutputContainer allData;
776 mpiGatherOp(sendData, allData, comm, commsType, tag);
794 mpiGatherOp(
fld, allData, comm, commsType, tag);
798 fld.transfer(allData);
812 const UList<Type>& sendData,
822 globalIndex(globalIndex::gatherOnly{}, sendData.size(), comm)
823 .
gather(sendData, allData, tag, commsType, comm);
833 template<
class Type,
class Addr>
836 const IndirectListBase<Type, Addr>& sendData,
846 globalIndex(globalIndex::gatherOnly{}, sendData.size(), comm)
847 .
gather(sendData, allData, tag, commsType, comm);
857 template<
class Type,
class OutputContainer>
860 const UList<Type>& sendData,
866 OutputContainer allData;
867 gatherOp(sendData, allData, tag, commsType, comm);
872 template<
class Type,
class Addr,
class OutputContainer>
881 OutputContainer allData;
882 gatherOp(sendData, allData, tag, commsType, comm);
906 template<
class ProcIDsContainer,
class Type>
911 const ProcIDsContainer& procIDs,
912 const UList<Type>& allFld,
924 !is_contiguous<Type>::value
933 const int masterProci = procIDs.size() ? procIDs[0] : 0;
937 for (label i = 1; i < procIDs.size(); ++i)
939 const SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
941 if (procSlot.empty())
945 else if (is_contiguous<Type>::value)
951 procSlot.cdata_bytes(),
952 procSlot.size_bytes(),
968 SubList<Type>(
fld, off[1]-off[0]) =
969 SubList<Type>(allFld, off[1]-off[0], off[0]);
981 else if (is_contiguous<Type>::value)
1007 template<
class Type>
1010 const UList<Type>& allData,
1011 UList<Type>& localData,
1034 localData.deepCopy(allData);
1039 template<
class Type,
class OutputContainer>
1042 const UList<Type>& allData,
1055 UPstream::listScatterValues<label>(this->localSizes(), comm)
1058 OutputContainer localData(
count);
1059 this->
scatter(allData, localData, tag, commsType, comm);
1066 return OutputContainer(allData);
1071 template<
class Type,
class CombineOp>
1076 const CombineOp& cop,
1081 allFld.resize_nocopy(globalIds.size());
1083 if (globalIds.size())
1089 CompactListList<label> bins
1091 bin(offsets(), globalIds, order, validBins)
1095 PstreamBuffers sendBufs(comm, tag);
1097 for (
const auto proci : validBins)
1101 for (label& val : localIDs)
1103 val = toLocal(proci, val);
1106 UOPstream
os(proci, sendBufs);
1109 sendBufs.finishedSends();
1112 PstreamBuffers returnBufs(comm, tag);
1114 for (
const int proci : sendBufs.allProcs())
1116 if (sendBufs.recvDataCount(proci))
1118 UIPstream is(proci, sendBufs);
1122 List<Type>
fld(localIDs.size());
1125 UOPstream
os(proci, returnBufs);
1129 returnBufs.finishedSends();
1132 for (
const auto proci : validBins)
1134 label start = bins.offsets()[proci];
1135 const SubList<label> es
1138 bins.offsets()[proci+1]-start,
1141 UIPstream is(proci, returnBufs);
1144 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)...
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)
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. ...
static void recv(Type &value, const int fromProcNo, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm, IOstreamOption::streamFormat fmt=IOstreamOption::BINARY)
Receive and deserialize a value. Uses operator>> for de-serialization.
"scheduled" (MPI standard) : (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" (immediate) : (MPI_Isend, MPI_Irecv)
void gatherInplace(List< Type > &fld, const int tag=UPstream::msgType(), const UPstream::commsTypes=UPstream::commsTypes::nonBlocking, const label comm=UPstream::worldComm) const
Inplace collect data in processor order on master (in serial: a no-op).
static 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.
bool send()
Send buffer contents now and not in destructor [advanced usage]. Returns true on success.
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 std::streamsize 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.
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.