35 template<
class T,
class CombineOp,
class NegateOp>
47 const label len = map.
size();
54 for (label i = 0; i < len; ++i)
56 const label index = map[i];
60 cop(lhs[index-1], rhs[i]);
64 cop(lhs[-index-1], negOp(rhs[i]));
69 <<
"Illegal flip index '0' at " << i <<
'/' << map.
size()
70 <<
" for list:" << rhs.
size() <<
nl 77 for (label i = 0; i < len; ++i)
79 cop(lhs[map[i]], rhs[i]);
85 template<
class T,
class NegateOp>
95 const label len = map.size();
102 for (label i = 0; i < len; ++i)
104 const label index = map[i];
117 <<
"Illegal flip index '0' at " << i <<
'/' << map.size()
118 <<
" for list:" <<
values.size() <<
nl 126 for (label i = 0; i < len; ++i)
134 template<
class T,
class NegateOp>
140 const NegateOp& negOp
143 List<T>
output(map.size());
149 template<
class T,
class negateOp>
153 const bool subHasFlip,
155 const bool constructHasFlip,
164 const negateOp& negOp,
169 if constexpr (!is_contiguous_v<T>)
172 <<
"Only contiguous is currently supported" 182 recvRequests.
size() = 0;
184 recvFields.resize(nProcs);
188 const labelList& map = constructMap[proci];
194 else if (map.empty())
197 (void) recvFields.release(proci);
201 List<T>& subField = recvFields.try_emplace(proci);
221 sendRequests.
size() = 0;
223 sendFields.resize(nProcs);
232 (void) sendFields.release(proci);
234 else if (map.empty())
237 (void) sendFields.release(proci);
241 List<T>& subField = sendFields.try_emplace(proci);
244 accessAndFlip(subField,
field, map, subHasFlip, negOp);
268 (void) recvFields.release(myRank);
272 List<T>& subField = recvFields.try_emplace(myRank);
275 accessAndFlip(subField,
field, map, subHasFlip, negOp);
284 const UList<T>&
field,
285 labelRange& sendRequests,
286 PtrList<List<T>>& sendFields,
287 labelRange& recvRequests,
288 PtrList<List<T>>& recvFields,
299 sendRequests, sendFields,
300 recvRequests, recvFields,
308 template<
class T,
class CombineOp,
class negateOp>
311 const label constructSize,
313 const bool constructHasFlip,
317 const CombineOp& cop,
318 const negateOp& negOp,
323 if constexpr (!is_contiguous_v<T>)
326 <<
"Only contiguous is currently supported" 337 DynamicList<int> recvProcs(nProcs);
340 const labelList& map = constructMap[proci];
342 if (proci != myRank && map.size())
346 const auto* subFieldPtr = recvFields.get(proci);
349 checkReceivedSize(proci, map.size(), subFieldPtr->size());
354 <<
"From processor " << proci
355 <<
" : unallocated receive field." 356 <<
" Expected size " << map.size()
357 <<
" on comm " << comm
366 field.resize_nocopy(constructSize);
370 if (recvFields.test(myRank))
372 const labelList& map = constructMap[myRank];
373 const List<T>& subField = recvFields[myRank];
403 for (
const int proci : recvProcs)
405 const labelList& map = constructMap[proci];
406 const List<T>& subField = recvFields[proci];
428 const labelRange& requests,
429 const UPtrList<List<T>>& recvFields,
450 template<
class T,
class CombineOp,
class NegateOp>
455 const label constructSize,
457 const bool subHasFlip,
459 const bool constructHasFlip,
462 const CombineOp& cop,
463 const NegateOp& negOp,
478 accessAndFlip(
field, subMap[myRank], subHasFlip, negOp)
482 const labelList& map = constructMap[myRank];
485 field.resize_nocopy(constructSize);
511 if (proci != myRank && map.size())
515 accessAndFlip(
field, map, subHasFlip, negOp)
519 OPstream
os(commsType, proci, 0, tag, comm);
528 accessAndFlip(
field, subMap[myRank], subHasFlip, negOp)
532 const labelList& map = constructMap[myRank];
535 field.resize_nocopy(constructSize);
552 const labelList& map = constructMap[proci];
554 if (proci != myRank && map.size())
559 checkReceivedSize(proci, map.size(), subField.size());
579 newField.resize_nocopy(constructSize);
580 newField = nullValue;
587 accessAndFlip(
field, subMap[myRank], subHasFlip, negOp)
591 const labelList& map = constructMap[myRank];
606 for (
const labelPair& twoProcs : schedule)
611 if (twoProcs.first() == myRank)
614 const label nbrProc = twoProcs.second();
621 accessAndFlip(
field, map, subHasFlip, negOp)
630 const labelList& map = constructMap[nbrProc];
632 checkReceivedSize(nbrProc, map.size(), subField.size());
648 const label nbrProc = twoProcs.first();
654 const labelList& map = constructMap[nbrProc];
656 checkReceivedSize(nbrProc, map.size(), subField.size());
673 accessAndFlip(
field, map, subHasFlip, negOp)
680 field.transfer(newField);
686 if constexpr (!is_contiguous_v<T>)
688 PstreamBuffers pBufs(comm, tag);
695 if (proci != myRank && map.size())
699 accessAndFlip(
field, map, subHasFlip, negOp)
702 UOPstream
os(proci, pBufs);
714 accessAndFlip(
field, subMap[myRank], subHasFlip, negOp)
718 field.resize_nocopy(constructSize);
722 const labelList& map = constructMap[myRank];
741 const labelList& map = constructMap[proci];
743 if (proci != myRank && map.size())
745 UIPstream is(proci, pBufs);
746 List<T> subField(is);
748 checkReceivedSize(proci, map.size(), subField.size());
766 List<List<T>> recvFields(nProcs);
767 DynamicList<int> recvProcs(nProcs);
771 const labelList& map = constructMap[proci];
773 if (proci != myRank && map.size())
776 List<T>& subField = recvFields[proci];
777 subField.resize_nocopy(map.size());
793 List<List<T>> sendFields(nProcs);
799 if (proci != myRank && map.size())
801 List<T>& subField = sendFields[proci];
804 accessAndFlip(subField,
field, map, subHasFlip, negOp);
820 List<T>& subField = recvFields[myRank];
823 accessAndFlip(subField,
field, map, subHasFlip, negOp);
828 field.resize_nocopy(constructSize);
833 const labelList& map = constructMap[myRank];
834 const List<T>& subField = recvFields[myRank];
852 DynamicList<int> indices(recvProcs.size());
863 for (
const int idx : indices)
865 const int proci = recvProcs[idx];
866 const labelList& map = constructMap[proci];
867 const List<T>& subField = recvFields[proci];
891 <<
"Unknown communication schedule " << int(commsType)
897 template<
class T,
class NegateOp>
901 const UList<labelPair>& schedule,
902 const label constructSize,
904 const bool subHasFlip,
906 const bool constructHasFlip,
908 const NegateOp& negOp,
923 accessAndFlip(
field, subMap[myRank], subHasFlip, negOp)
927 const labelList& map = constructMap[myRank];
930 field.resize_nocopy(constructSize);
955 if (proci != myRank && map.size())
959 accessAndFlip(
field, map, subHasFlip, negOp)
963 OPstream
os(commsType, proci, 0, tag, comm);
972 accessAndFlip(
field, subMap[myRank], subHasFlip, negOp)
976 const labelList& map = constructMap[myRank];
979 field.resize_nocopy(constructSize);
995 const labelList& map = constructMap[proci];
997 if (proci != myRank && map.size())
1002 checkReceivedSize(proci, map.size(), subField.size());
1022 newField.resize_nocopy(constructSize);
1029 accessAndFlip(
field, subMap[myRank], subHasFlip, negOp)
1033 const labelList& map = constructMap[myRank];
1047 for (
const labelPair& twoProcs : schedule)
1052 if (twoProcs.first() == myRank)
1055 const label nbrProc = twoProcs.second();
1061 accessAndFlip(
field, map, subHasFlip, negOp)
1070 const labelList& map = constructMap[nbrProc];
1072 checkReceivedSize(nbrProc, map.size(), subField.size());
1088 const label nbrProc = twoProcs.first();
1094 const labelList& map = constructMap[nbrProc];
1096 checkReceivedSize(nbrProc, map.size(), subField.size());
1112 accessAndFlip(
field, map, subHasFlip, negOp)
1119 field.transfer(newField);
1125 if constexpr (!is_contiguous_v<T>)
1127 PstreamBuffers pBufs(comm, tag);
1134 if (proci != myRank && map.size())
1138 accessAndFlip(
field, map, subHasFlip, negOp)
1141 UOPstream
os(proci, pBufs);
1153 accessAndFlip(
field, subMap[myRank], subHasFlip, negOp)
1157 field.resize_nocopy(constructSize);
1160 const labelList& map = constructMap[myRank];
1179 const labelList& map = constructMap[proci];
1181 if (proci != myRank && map.size())
1183 UIPstream is(proci, pBufs);
1184 List<T> subField(is);
1186 checkReceivedSize(proci, map.size(), subField.size());
1204 List<List<T>> recvFields(nProcs);
1205 DynamicList<int> recvProcs(nProcs);
1209 const labelList& map = constructMap[proci];
1211 if (proci != myRank && map.size())
1214 List<T>& subField = recvFields[proci];
1215 subField.resize_nocopy(map.size());
1231 List<List<T>> sendFields(nProcs);
1237 if (proci != myRank && map.size())
1239 List<T>& subField = sendFields[proci];
1242 accessAndFlip(subField,
field, map, subHasFlip, negOp);
1258 List<T>& subField = recvFields[myRank];
1261 accessAndFlip(subField,
field, map, subHasFlip, negOp);
1266 field.resize_nocopy(constructSize);
1271 const labelList& map = constructMap[myRank];
1272 const List<T>& subField = recvFields[myRank];
1290 DynamicList<int> indices(recvProcs.size());
1301 for (
const int idx : indices)
1303 const int proci = recvProcs[idx];
1304 const labelList& map = constructMap[proci];
1305 const List<T>& subField = recvFields[proci];
1329 <<
"Unknown communication schedule " << int(commsType)
1338 PstreamBuffers& pBufs,
1339 const UList<T>&
field 1351 accessAndFlip(
field, map, subHasFlip_, flipOp())
1354 UOPstream
os(proci, pBufs);
1360 pBufs.finishedSends(
false);
1372 field.resize_nocopy(constructSize_);
1376 const labelList& map = constructMap_[proci];
1383 checkReceivedSize(proci, map.
size(), subField.
size());
1399 template<
class T,
class NegateOp>
1404 const NegateOp& negOp,
1411 whichSchedule(commsType),
1425 template<
class T,
class NegateOp>
1431 const NegateOp& negOp,
1438 whichSchedule(commsType),
1454 template<
class T,
class NegateOp>
1458 const NegateOp& negOp,
1491 distribute(commsType, work, tag);
1493 values = std::move(work);
1523 const label constructSize,
1528 reverseDistribute<T, flipOp>
1539 template<
class T,
class NegateOp>
1543 const label constructSize,
1545 const NegateOp& negOp,
1552 whichSchedule(commsType),
1570 const label constructSize,
1579 whichSchedule(commsType),
1600 const label constructSize,
1618 const label constructSize,
void send(PstreamBuffers &pBufs, const UList< T > &field) const
Do all sends using PstreamBuffers.
void size(const label n)
Older name for setAddressableSize.
errorManipArg< error, int > exit(error &err, const int errNo=1)
commsTypes
Communications types.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
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.
A range or interval of labels defined by a start and a size.
constexpr char nl
The newline '\n' character (0x0a)
static bool & parRun() noexcept
Test if this a parallel run.
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
static std::streamsize read(const UPstream::commsTypes commsType, const int fromProcNo, Type *buffer, std::streamsize count, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm, UPstream::Request *req=nullptr)
Receive buffer contents (contiguous types) from given processor.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
void push_back(const T &val)
Append an element at the end of the list.
List< labelList > labelListList
List of labelList.
static void waitRequests()
Wait for all requests to finish.
UList< label > labelUList
A UList of labels.
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Input inter-processor communications stream using MPI send/recv etc. - operating on external buffer...
static void accessAndFlip(UList< T > &output, const UList< T > &values, const labelUList &map, const bool hasFlip, const NegateOp &negOp)
Lookup field values at specified map indices and save after any flip negation operations.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run. ...
"scheduled" (MPI standard) : (MPI_Send, MPI_Recv)
static void recv(Type &value, const int fromProcNo, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm, IOstreamOption::streamFormat fmt=IOstreamOption::BINARY)
Receive and deserialize a value. Uses operator>> for de-serialization.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
void finishedSends(const bool wait=true)
Mark the send phase as being finished.
void reverseDistribute(const label constructSize, List< T > &values, const int tag=UPstream::msgType()) const
Reverse distribute data using default commsType and the default flip/negate operator.
static void flipAndCombine(UList< T > &lhs, const UList< T > &rhs, const labelUList &map, const bool hasFlip, const CombineOp &cop, const NegateOp &negOp)
Combine field values (after any flip negation operation) into the specified mapped target locations...
static bool write(const UPstream::commsTypes commsType, const int toProcNo, const Type *buffer, std::streamsize count, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm, UPstream::Request *req=nullptr, const UPstream::sendModes sendMode=UPstream::sendModes::normal)
Write buffer contents (contiguous types only) to given processor.
IntType start() const noexcept
The (inclusive) lower value of the range.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
errorManip< error > abort(error &err)
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
Pair< label > labelPair
A pair of labels.
OBJstream os(runTime.globalPath()/outputName)
Buffers for inter-processor communications streams (UOPstream, UIPstream).
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
void receive(PstreamBuffers &pBufs, List< T > &field) const
Do all receives using PstreamBuffers.
static commsTypes defaultCommsType
Default commsType.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers...
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
static Ostream & output(Ostream &os, const IntRange< T > &range)
List< label > labelList
A List of labels.
IntType size() const noexcept
The size of the range.
"buffered" : (MPI_Bsend, MPI_Recv)
bool send()
Send buffer contents now and not in destructor [advanced usage]. Returns true on success.
Functor to negate primitives. Dummy for most other types.
static void distribute(const UPstream::commsTypes commsType, const UList< labelPair > &schedule, const label constructSize, const labelListList &subMap, const bool subHasFlip, const labelListList &constructMap, const bool constructHasFlip, List< T > &field, const T &nullValue, const CombineOp &cop, const NegateOp &negOp, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Distribute combine data with specified combine operation and negate operator (for flips)...
static bool waitSomeRequests(const label pos, label len=-1, DynamicList< int > *indices=nullptr)
Wait until some requests (from position onwards) have finished. Corresponds to MPI_Waitsome() ...