35template<
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]);
85template<
class T,
class NegateOp>
95 const label len = map.size();
102 for (label i = 0; i < len; ++i)
104 const label index = map[i];
108 output[i] =
values[index-1];
112 output[i] = negOp(values[-index-1]);
117 <<
"Illegal flip index '0' at " << i <<
'/' << map.size()
118 <<
" for list:" <<
values.size() <<
nl
126 for (label i = 0; i < len; ++i)
128 output[i] = values[map[i]];
134template<
class T,
class NegateOp>
140 const NegateOp& negOp
149template<
class T,
class negateOp>
153 const bool subHasFlip,
155 const bool constructHasFlip,
164 const negateOp& negOp,
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);
299 sendRequests, sendFields,
300 recvRequests, recvFields,
308template<
class T,
class CombineOp,
class negateOp>
311 const label constructSize,
313 const bool constructHasFlip,
317 const CombineOp& cop,
318 const negateOp& negOp,
326 <<
"Only contiguous is currently supported"
337 DynamicList<int> recvProcs(nProcs);
340 const labelList& map = constructMap[proci];
342 if (proci != myRank && map.size())
344 recvProcs.push_back(proci);
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];
450template<
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];
552 const labelList& map = constructMap[proci];
554 if (proci != myRank && map.size())
559 checkReceivedSize(proci, map.size(), subField.size());
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);
695 if (proci != myRank && map.size())
699 accessAndFlip(
field, map, subHasFlip, negOp)
708 pBufs.finishedSends(
false);
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())
748 checkReceivedSize(proci, map.size(), subField.size());
771 const labelList& map = constructMap[proci];
773 if (proci != myRank && map.size())
775 recvProcs.push_back(proci);
776 List<T>& subField = recvFields[proci];
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];
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)
897template<
class T,
class CombineOp,
class NegateOp>
901 const UList<labelPair>& schedule,
903 const UList<T>& inField,
905 const bool subHasFlip,
908 const label constructSize,
910 const bool constructHasFlip,
912 const CombineOp& cop,
913 const NegateOp& negOp,
928 accessAndFlip(inField, subMap[myRank], subHasFlip, negOp)
932 const labelList& map = constructMap[myRank];
935 field.resize_nocopy(constructSize);
954 <<
"Unsupport communication type " << int(commsType)
969 if (proci != myRank && map.size())
973 accessAndFlip(inField, map, subHasFlip, negOp)
982 pBufs.finishedSends(
false);
988 accessAndFlip(inField, subMap[myRank], subHasFlip, negOp)
992 field.resize_nocopy(constructSize);
996 const labelList& map = constructMap[myRank];
1015 const labelList& map = constructMap[proci];
1017 if (proci != myRank && map.size())
1022 checkReceivedSize(proci, map.size(), subField.size());
1045 const labelList& map = constructMap[proci];
1047 if (proci != myRank && map.size())
1049 recvProcs.push_back(proci);
1050 List<T>& subField = recvFields[proci];
1057 subField.data_bytes(),
1058 subField.size_bytes(),
1074 if (proci != myRank && map.size())
1076 List<T>& subField = sendFields[proci];
1079 accessAndFlip(subField, inField, map, subHasFlip, negOp);
1085 subField.cdata_bytes(),
1086 subField.size_bytes(),
1096 List<T>& subField = recvFields[myRank];
1099 accessAndFlip(subField, inField, map, subHasFlip, negOp);
1104 field.resize_nocopy(constructSize);
1109 const labelList& map = constructMap[myRank];
1110 const List<T>& subField = recvFields[myRank];
1139 for (
const int idx : indices)
1141 const int proci = recvProcs[idx];
1142 const labelList& map = constructMap[proci];
1143 const List<T>& subField = recvFields[proci];
1166template<
class T,
class NegateOp>
1170 const UList<labelPair>& schedule,
1171 const label constructSize,
1173 const bool subHasFlip,
1175 const bool constructHasFlip,
1177 const NegateOp& negOp,
1192 accessAndFlip(
field, subMap[myRank], subHasFlip, negOp)
1196 const labelList& map = constructMap[myRank];
1199 field.resize_nocopy(constructSize);
1224 if (proci != myRank && map.size())
1228 accessAndFlip(
field, map, subHasFlip, negOp)
1241 accessAndFlip(
field, subMap[myRank], subHasFlip, negOp)
1245 const labelList& map = constructMap[myRank];
1248 field.resize_nocopy(constructSize);
1264 const labelList& map = constructMap[proci];
1266 if (proci != myRank && map.size())
1271 checkReceivedSize(proci, map.size(), subField.size());
1298 accessAndFlip(
field, subMap[myRank], subHasFlip, negOp)
1302 const labelList& map = constructMap[myRank];
1316 for (
const labelPair& twoProcs : schedule)
1321 if (twoProcs.first() == myRank)
1324 const label nbrProc = twoProcs.second();
1330 accessAndFlip(
field, map, subHasFlip, negOp)
1339 const labelList& map = constructMap[nbrProc];
1341 checkReceivedSize(nbrProc, map.size(), subField.size());
1357 const label nbrProc = twoProcs.first();
1363 const labelList& map = constructMap[nbrProc];
1365 checkReceivedSize(nbrProc, map.size(), subField.size());
1381 accessAndFlip(
field, map, subHasFlip, negOp)
1388 field.transfer(newField);
1403 if (proci != myRank && map.size())
1407 accessAndFlip(
field, map, subHasFlip, negOp)
1416 pBufs.finishedSends(
false);
1422 accessAndFlip(
field, subMap[myRank], subHasFlip, negOp)
1426 field.resize_nocopy(constructSize);
1429 const labelList& map = constructMap[myRank];
1448 const labelList& map = constructMap[proci];
1450 if (proci != myRank && map.size())
1455 checkReceivedSize(proci, map.size(), subField.size());
1478 const labelList& map = constructMap[proci];
1480 if (proci != myRank && map.size())
1482 recvProcs.push_back(proci);
1483 List<T>& subField = recvFields[proci];
1506 if (proci != myRank && map.size())
1508 List<T>& subField = sendFields[proci];
1511 accessAndFlip(subField,
field, map, subHasFlip, negOp);
1527 List<T>& subField = recvFields[myRank];
1530 accessAndFlip(subField,
field, map, subHasFlip, negOp);
1535 field.resize_nocopy(constructSize);
1540 const labelList& map = constructMap[myRank];
1541 const List<T>& subField = recvFields[myRank];
1570 for (
const int idx : indices)
1572 const int proci = recvProcs[idx];
1573 const labelList& map = constructMap[proci];
1574 const List<T>& subField = recvFields[proci];
1598 <<
"Unknown communication schedule " << int(commsType)
1607 PstreamBuffers& pBufs,
1608 const UList<T>&
field
1620 accessAndFlip(
field, map, subHasFlip_, flipOp())
1623 UOPstream
os(proci, pBufs);
1629 pBufs.finishedSends(
false);
1641 field.resize_nocopy(constructSize_);
1645 const labelList& map = constructMap_[proci];
1652 checkReceivedSize(proci, map.
size(), subField.
size());
1668template<
class T,
class NegateOp>
1673 const NegateOp& negOp,
1680 whichSchedule(commsType),
1694template<
class T,
class NegateOp>
1700 const NegateOp& negOp,
1707 whichSchedule(commsType),
1723template<
class T,
class NegateOp>
1727 const NegateOp& negOp,
1758 List<T> work(std::move(values));
1762 values = std::move(work);
1792 const label constructSize,
1797 reverseDistribute<T, flipOp>
1808template<
class T,
class NegateOp>
1812 const label constructSize,
1814 const NegateOp& negOp,
1821 whichSchedule(commsType),
1839 const label constructSize,
1848 whichSchedule(commsType),
1869 const label constructSize,
1887 const label constructSize,
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
void push_back(const T &val)
Copy append an element to the end of this list.
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.
IntType start() const noexcept
The (inclusive) lower value of the range.
IntType size() const noexcept
The size of the range.
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
Output inter-processor communications stream.
Buffers for inter-processor communications streams (UOPstream, UIPstream).
void finishedSends(const bool wait=true)
Mark the send phase as being finished.
A list of pointers to objects of type <T>, with allocation/deallocation management of the pointers....
Input inter-processor communications stream using MPI send/recv etc. - operating on external buffer.
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.
A 1D vector of objects of type <T>, where the size of the vector is known and can be used for subscri...
char * data_bytes() noexcept
Return pointer to the underlying array serving as data storage,.
bool empty() const noexcept
True if List is empty (ie, size() is zero).
const char * cdata_bytes() const noexcept
Return pointer to the underlying array serving as data storage,.
void size(const label n)
Older name for setAddressableSize.
std::streamsize size_bytes() const noexcept
Number of contiguous bytes for the List data.
Output inter-processor communications stream using MPI send/recv etc. - operating on external buffer.
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.
bool send()
Send buffer contents now and not in destructor [advanced usage]. Returns true on success.
static bool waitSomeRequests(label pos, label len=-1, DynamicList< int > *indices=nullptr)
Wait until some requests (from position onwards) have finished. Corresponds to MPI_Waitsome().
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
static label nRequests() noexcept
Number of outstanding requests (on the internal list of requests).
commsTypes
Communications types.
@ scheduled
"scheduled" (MPI standard) : (MPI_Send, MPI_Recv)
@ nonBlocking
"nonBlocking" (immediate) : (MPI_Isend, MPI_Irecv)
@ buffered
"buffered" : (MPI_Bsend, MPI_Recv)
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
static void waitRequests()
Wait for all requests to finish.
static commsTypes defaultCommsType
Default commsType.
static bool & parRun() noexcept
Test if this a parallel run.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
A range or interval of labels defined by a start and a size.
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.
const List< labelPair > & whichSchedule(const UPstream::commsTypes commsType) const
Return real or dummy schedule depending on the communication type.
void send(PstreamBuffers &pBufs, const UList< T > &field) const
Do all sends using PstreamBuffers.
const labelListList & constructMap() const noexcept
From subsetted data to new reconstructed data.
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 List< labelPair > schedule(const labelListList &subMap, const labelListList &constructMap, const int tag, const label comm=UPstream::worldComm)
Calculate a communication schedule. See above.
bool constructHasFlip() const noexcept
Does constructMap include a sign.
const labelListList & subMap() const noexcept
From subsetted data back to original data.
static void checkReceivedSize(const label proci, const label expectedSize, const label receivedSize)
Fatal if expected != received size.
bool subHasFlip() const noexcept
Does subMap include a sign.
void receive(PstreamBuffers &pBufs, List< T > &field) const
Do all receives using PstreamBuffers.
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).
label comm() const noexcept
The communicator used.
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.
label constructSize() const noexcept
Constructed data size.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
OBJstream os(runTime.globalPath()/outputName)
List< T > values(const HashTable< T, Key, Hash > &tbl, const bool doSort=false)
List of values from HashTable, optionally sorted.
Pair< label > labelPair
A pair of labels.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
errorManip< error > abort(error &err)
void rhs(fvMatrix< typename Expr::value_type > &m, const Expr &expression)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
constexpr bool is_contiguous_v
The is_contiguous value of Type (after stripping of qualifiers).
errorManipArg< error, int > exit(error &err, const int errNo=1)
UList< label > labelUList
A UList of labels.
void T(FieldField< Field, Type > &f1, const FieldField< Field, Type > &f2)
constexpr char nl
The newline '\n' character (0x0a).
Functor to negate primitives. Dummy for most other types.