48 for (
const label val : map)
70 for (
const label val : map)
99 for (label index : map)
103 index =
mag(index)-1;
106 maxIndex =
max(maxIndex, index);
121 if (elements.empty())
128 bitSet unvisited(elements);
129 label nUnmapped = unvisited.count();
135 for (label index : map)
137 index =
mag(index)-1;
139 if (unvisited.unset(index))
142 if (!nUnmapped)
break;
151 for (label index : map)
153 if (unvisited.unset(index))
156 if (!nUnmapped)
break;
169 const label expectedSize,
170 const label receivedSize
173 if (receivedSize != expectedSize)
176 <<
"From processor " << proci
177 <<
" : expected " << expectedSize
178 <<
" but received " << receivedSize <<
" elements" <<
nl 198 List<labelPair> allComms;
208 if (subMap[proci].size())
211 commsSet.insert(
labelPair(myRank, proci));
213 if (constructMap[proci].size())
216 commsSet.insert(
labelPair(proci, myRank));
220 allComms = commsSet.toc();
238 List<labelPair> nbrData(fromProc);
240 for (
const labelPair& connection : nbrData)
242 allComms.push_uniq(connection);
258 toMaster << allComms;
272 ).procSchedule()[myRank]
293 return *schedulePtr_;
319 forAll(constructMap_, proci)
321 const labelList& construct = constructMap_[proci];
322 if (constructHasFlip_)
326 label index =
mag(construct[i])-1;
327 minIndex[proci] =
min(minIndex[proci], index);
328 maxIndex[proci] =
max(maxIndex[proci], index);
335 label index = construct[i];
336 minIndex[proci] =
min(minIndex[proci], index);
337 maxIndex[proci] =
max(maxIndex[proci], index);
346 localSize = maxIndex[myRank]+1;
349 os <<
"Layout: (constructSize:" << constructSize_
350 <<
" subHasFlip:" << subHasFlip_
351 <<
" constructHasFlip:" << constructHasFlip_
353 <<
"local (processor " << myRank <<
"):" <<
nl 354 <<
" start : 0" <<
nl 355 <<
" size : " << localSize <<
endl;
357 label offset = localSize;
360 if (proci != myRank && !constructMap_[proci].empty())
366 size = maxIndex[proci]-minIndex[proci]+1;
367 if (minIndex[proci] != offset)
370 <<
"offset:" << offset
371 <<
" proci:" << proci
372 <<
" minIndex:" << minIndex[proci]
377 os <<
"processor " << proci <<
':' <<
nl 378 <<
" start : " << offset <<
nl 379 <<
" size : " << size <<
endl;
389 const globalIndex& globalNumbering,
391 List<Map<label>>& compactMap
400 for (
const label globalIdx : elements)
402 if (globalIdx != -1 && !globalNumbering.isLocal(myRank, globalIdx))
404 label proci = globalNumbering.whichProcID(myRank, globalIdx);
409 compactMap.resize_nocopy(nProcs);
413 compactMap[proci].clear();
416 compactMap[proci].reserve(nNonLocal[proci]);
422 for (
const label globalIdx : elements)
424 if (globalIdx != -1 && !globalNumbering.isLocal(myRank, globalIdx))
426 label proci = globalNumbering.whichProcID(myRank, globalIdx);
427 label index = globalNumbering.toLocal(proci, globalIdx);
428 compactMap[proci].insert(index, compactMap[proci].size());
436 const globalIndex& globalNumbering,
438 List<Map<label>>& compactMap
447 for (
const labelList& cCells : cellCells)
449 for (
const label globalIdx : cCells)
451 if (globalIdx != -1 && !globalNumbering.isLocal(myRank, globalIdx))
453 label proci = globalNumbering.whichProcID(myRank, globalIdx);
459 compactMap.resize_nocopy(nProcs);
463 compactMap[proci].clear();
466 compactMap[proci].reserve(nNonLocal[proci]);
472 for (
const labelList& cCells : cellCells)
474 for (
const label globalIdx : cCells)
476 if (globalIdx != -1 && !globalNumbering.isLocal(myRank, globalIdx))
478 label proci = globalNumbering.whichProcID(myRank, globalIdx);
479 label index = globalNumbering.toLocal(proci, globalIdx);
480 compactMap[proci].insert(index, compactMap[proci].size());
490 const globalIndex& globalNumbering,
492 List<Map<label>>& compactMap,
503 compactStart.setSize(nProcs);
504 compactStart[myRank] = 0;
505 constructSize_ = globalNumbering.localSize(myRank);
506 forAll(compactStart, proci)
510 compactStart[proci] = constructSize_;
511 constructSize_ += compactMap[proci].size();
521 constructMap_.setSize(nProcs);
527 label nLocal = globalNumbering.localSize(myRank);
528 wantedRemoteElements[proci] =
identity(nLocal);
529 constructMap_[proci] =
identity(nLocal);
534 labelList& remoteElem = wantedRemoteElements[proci];
535 labelList& localElem = constructMap_[proci];
536 remoteElem.
setSize(compactMap[proci].size());
537 localElem.setSize(compactMap[proci].size());
541 const label compactI = compactStart[proci] + iter.val();
542 remoteElem[i] = iter.key();
543 localElem[i] = compactI;
544 iter.val() = compactI;
550 subMap_.setSize(nProcs);
551 Pstream::exchange<labelList, label>
553 wantedRemoteElements,
560 for (label& elem : elements)
562 elem =
renumber(globalNumbering, comm_, compactMap, elem);
570 const globalIndex& globalNumbering,
572 List<Map<label>>& compactMap,
583 compactStart.setSize(nProcs);
584 compactStart[myRank] = 0;
585 constructSize_ = globalNumbering.localSize(myRank);
586 forAll(compactStart, proci)
590 compactStart[proci] = constructSize_;
591 constructSize_ += compactMap[proci].size();
601 constructMap_.setSize(nProcs);
607 label nLocal = globalNumbering.localSize(myRank);
608 wantedRemoteElements[proci] =
identity(nLocal);
609 constructMap_[proci] =
identity(nLocal);
614 labelList& remoteElem = wantedRemoteElements[proci];
615 labelList& localElem = constructMap_[proci];
616 remoteElem.
setSize(compactMap[proci].size());
617 localElem.setSize(compactMap[proci].size());
621 const label compactI = compactStart[proci] + iter.val();
622 remoteElem[i] = iter.key();
623 localElem[i] = compactI;
624 iter.val() = compactI;
630 subMap_.setSize(nProcs);
631 Pstream::exchange<labelList, label>
633 wantedRemoteElements,
642 for (label& celli : cCells)
644 celli =
renumber(globalNumbering, comm_, compactMap, celli);
664 constructHasFlip_(
false),
666 schedulePtr_(
nullptr)
672 constructSize_(map.constructSize_),
673 subMap_(map.subMap_),
674 constructMap_(map.constructMap_),
675 subHasFlip_(map.subHasFlip_),
676 constructHasFlip_(map.constructHasFlip_),
678 schedulePtr_(nullptr)
692 const label constructSize,
695 const bool subHasFlip,
696 const bool constructHasFlip,
700 constructSize_(constructSize),
701 subMap_(
std::move(subMap)),
702 constructMap_(
std::move(constructMap)),
703 subHasFlip_(subHasFlip),
704 constructHasFlip_(constructHasFlip),
706 schedulePtr_(nullptr)
721 constructHasFlip_(false),
723 schedulePtr_(nullptr)
728 if (sendProcs.
size() != recvProcs.
size())
731 <<
"The send and receive data is not the same length. sendProcs:" 732 << sendProcs.
size() <<
" recvProcs:" << recvProcs.
size()
740 forAll(sendProcs, sampleI)
742 const label sendProc = sendProcs[sampleI];
743 const label recvProc = recvProcs[sampleI];
748 if (myRank == sendProc)
753 if (myRank == recvProc)
760 subMap_.setSize(nProcs);
764 subMap_[proci].setSize(nSend[proci]);
765 constructMap_[proci].
setSize(nRecv[proci]);
771 label maxRecvIndex = -1;
773 forAll(sendProcs, sampleI)
775 const label sendProc = sendProcs[sampleI];
776 const label recvProc = recvProcs[sampleI];
778 if (myRank == sendProc)
781 subMap_[recvProc][nSend[recvProc]++] = sampleI;
783 if (myRank == recvProc)
786 constructMap_[sendProc][nRecv[sendProc]++] = sampleI;
787 maxRecvIndex = sampleI;
791 constructSize_ = maxRecvIndex+1;
797 const globalIndex& globalNumbering,
799 List<Map<label>>& compactMap,
808 constructHasFlip_(false),
810 schedulePtr_(nullptr)
860 const globalIndex& globalNumbering,
862 List<Map<label>>& compactMap,
871 constructHasFlip_(false),
873 schedulePtr_(nullptr)
923 const layoutTypes constructLayout,
925 const bool subHasFlip,
926 const bool constructHasFlip,
931 subMap_(
std::move(subMap)),
933 subHasFlip_(subHasFlip),
934 constructHasFlip_(constructHasFlip),
936 schedulePtr_(nullptr)
946 constructMap_.
resize(nProcs);
952 forAll(constructMap_, proci)
954 const label len = recvSizes[proci];
956 constructMap_[proci] =
identity(len, constructSize_);
957 constructSize_ += len;
966 const label len = recvSizes[myRank];
968 constructMap_[myRank] =
identity(len, constructSize_);
969 constructSize_ += len;
973 forAll(constructMap_, proci)
977 const label len = recvSizes[proci];
979 constructMap_[proci] =
identity(len, constructSize_);
980 constructSize_ += len;
990 const bool subHasFlip,
991 const bool constructHasFlip,
997 layoutTypes::localFirst,
1010 const label newComm,
1018 constructHasFlip_(false),
1020 schedulePtr_(nullptr)
1028 subHasFlip_ = maps[0].subHasFlip();
1029 constructHasFlip_ = maps[0].constructHasFlip();
1031 const label nNewRanks = newToOldRanks.
size();
1040 if (localRanks.
size() != maps.
size())
1043 <<
"Number of maps:" << maps.
size()
1044 <<
" number of localRanks:" << localRanks.
size()
1049 const auto& map0 = maps[0];
1052 const auto& map = maps[mapi];
1056 (map.comm() != map0.comm())
1057 || (map.subHasFlip() != map0.subHasFlip())
1058 || (map.constructHasFlip() != map0.constructHasFlip())
1062 <<
"Maps should all be the same form" 1064 <<
" has comm:" << map.comm()
1065 <<
" subHasFlip:" << map.subHasFlip()
1066 <<
" constructHasFlip:" << map.constructHasFlip()
1067 <<
" which is different from map 0" 1071 const label localRank = localRanks[mapi];
1072 const auto& constructOwn = maps[mapi].constructMap()[localRank];
1075 if (constructOwn[i] != i)
1078 <<
"Maps constructMap not identity." 1080 <<
" constructMap:" <<
flatOutput(constructOwn)
1088 subMap_.resize_nocopy(nNewRanks);
1093 compactMaps.resize_nocopy(maps.
size());
1095 label constructi = 0;
1098 startOfLocal[mapi] = constructi;
1099 const label localRank = localRanks[mapi];
1100 const auto& map = maps[mapi].constructMap()[localRank];
1103 const label nRemote = maps[mapi].constructSize()-map.
size();
1104 compactMaps[mapi].resize(2*nRemote);
1106 constructi += map.size();
1108 startOfLocal.
last() = constructi;
1116 const label nOldProcs = maps[mapi].constructMap().
size();
1117 labelList& starts = startOfRemote[mapi];
1122 const labelList& map = maps[mapi].constructMap()[oldProci];
1131 starts[oldProci] =
min(starts[oldProci], index);
1153 labelList& myConstruct = constructMap_[myNewRank];
1158 const label localRank = localRanks[mapi];
1159 const auto& map = maps[mapi].constructMap()[localRank];
1160 const label offset = startOfLocal[mapi];
1164 if (constructHasFlip_)
1170 myConstruct[constructi++] = map[i]-offset;
1174 myConstruct[constructi++] = map[i]+offset;
1180 myConstruct[constructi++] = map[i]+offset;
1191 const auto& oldProcs = newToOldRanks[myNewRank];
1195 for (
const label oldProci : oldProcs)
1197 if (oldProci != localRanks[mapi])
1199 const auto& map = maps[mapi].constructMap()[oldProci];
1209 const label sourceMapi = localRanks.
find(oldProci);
1211 maps[sourceMapi].subMap()[localRanks[mapi]];
1223 <<
"oldProci:" << oldProci
1225 <<
" constructMap:" << map.size()
1226 <<
" sourceMapi:" << sourceMapi
1231 const label offset = startOfLocal[sourceMapi];
1233 const label nMapLocal = startOfRemote[mapi][oldProci];
1235 auto& cptMap = compactMaps[mapi];
1245 const label newIndex =
subMap[index-nMapLocal]+offset;
1251 !cptMap.insert(index, newIndex)
1252 && cptMap[index] != newIndex
1256 <<
"From oldProc:" << oldProci
1257 <<
" on map:" << mapi
1258 <<
" at index:" << i
1259 <<
" have construct slot:" << index
1260 <<
" new index:" << newIndex
1261 <<
" but already have entry:" << cptMap[index]
1262 <<
" on for that slot" 1278 forAll(newToOldRanks, newProci)
1280 if (newProci != myNewRank)
1282 const auto& oldProcs = newToOldRanks[newProci];
1287 for (
const label oldProci : oldProcs)
1289 allSize += maps[mapi].constructMap()[oldProci].
size();
1293 labelList& myConstruct = constructMap_[newProci];
1299 for (
const label oldProci : oldProcs)
1301 const auto& map = maps[mapi].constructMap()[oldProci];
1303 const label nMapLocal = startOfRemote[mapi][oldProci];
1304 SubList<label> slice(myConstruct, map.size(), allSize);
1306 if (constructHasFlip_)
1312 slice[i] = map[i]+nMapLocal-constructi;
1316 slice[i] = map[i]-nMapLocal+constructi;
1320 auto& cptMap = compactMaps[mapi];
1323 cptMap.insert(
mag(map[i])-1,
mag(slice[i])-1);
1330 slice[i] = map[i]-nMapLocal+constructi;
1331 compactMaps[mapi].insert(map[i], slice[i]);
1334 allSize += map.size();
1335 constructi += map.size();
1357 const label localRank = localRanks[mapi];
1358 allSize += maps[mapi].subMap()[localRank].
size();
1366 const label localRank = localRanks[mapi];
1367 const auto& map = maps[mapi].subMap()[localRank];
1368 SubList<label> slice(mySub, map.size(), allSize);
1376 slice[i] = map[i]-startOfLocal[mapi];
1380 slice[i] = map[i]+startOfLocal[mapi];
1388 slice[i] = map[i]+startOfLocal[mapi];
1391 allSize += map.
size();
1395 forAll(newToOldRanks, newProci)
1397 if (newProci != myNewRank)
1399 const auto& oldProcs = newToOldRanks[newProci];
1404 for (
const label oldProci : oldProcs)
1406 allSize += maps[mapi].subMap()[oldProci].
size();
1414 for (
const label oldProci : oldProcs)
1418 const auto& map = maps[mapi].subMap()[oldProci];
1419 SubList<label> slice(mySub, map.size(), allSize);
1426 slice[i] = map[i]-startOfLocal[mapi];
1430 slice[i] = map[i]+startOfLocal[mapi];
1438 slice[i] = map[i]+startOfLocal[mapi];
1441 allSize += map.
size();
1448 constructSize_ = constructi;
1459 sizes[i] = subMap_[i].size();
1470 sizes[i] = constructMap_[i].size();
1479 for (
const auto& list : subMap_)
1481 total += list.size();
1490 for (
const auto& list : constructMap_)
1492 total += list.size();
1502 constructMap_.clear();
1503 subHasFlip_ =
false;
1504 constructHasFlip_ =
false;
1506 schedulePtr_.reset(
nullptr);
1518 constructSize_ = rhs.constructSize_;
1519 subMap_.transfer(rhs.subMap_);
1520 constructMap_.transfer(rhs.constructMap_);
1521 subHasFlip_ = rhs.subHasFlip_;
1522 constructHasFlip_ = rhs.constructHasFlip_;
1524 schedulePtr_.reset(
nullptr);
1526 rhs.constructSize_ = 0;
1527 rhs.subHasFlip_ =
false;
1528 rhs.constructHasFlip_ =
false;
1546 if (globalNumbering.
isLocal(myRank, globalI))
1548 return globalNumbering.
toLocal(myRank, globalI);
1552 label proci = globalNumbering.
whichProcID(myRank, globalI);
1553 label index = globalNumbering.
toLocal(proci, globalI);
1554 return compactMap[proci][index];
1568 constructSize_ = rhs.constructSize_;
1569 subMap_ = rhs.subMap_;
1570 constructMap_ = rhs.constructMap_;
1571 subHasFlip_ = rhs.subHasFlip_;
1572 constructHasFlip_ = rhs.constructHasFlip_;
1574 schedulePtr_.reset(
nullptr);
label toLocal(const label proci, const label i) const
From global to local on proci.
void calcCompactAddressing(const globalIndex &globalNumbering, const labelUList &elements, List< Map< label >> &compactMap) const
Construct per processor compact addressing of the global elements.
void size(const label n)
Older name for setAddressableSize.
static label countUnmapped(const labelUList &elements, const labelListList &maps, const bool hasFlip)
Count the number of unmapped elements.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void resize(const label len)
Adjust allocated size of list.
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...
const List< labelPair > & schedule() const
Return a schedule. Demand driven. See above.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values (not the indices) of a list.
constexpr char nl
The newline '\n' character (0x0a)
label whichProcID(const label proci, const label i) const
Which processor does global id come from? Checks proci first (assumed to occur reasonably frequently)...
Ostream & endl(Ostream &os)
Add newline and flush stream.
static bool & parRun() noexcept
Test if this a parallel run.
void resize_nocopy(const label len)
Adjust allocated size of list without necessarily.
static int & msgType() noexcept
Message tag of standard messages.
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Can be negative if the process i...
static const List< T > & null()
Return a null List.
List< labelList > labelListList
List of labelList.
UList< label > labelUList
A UList of labels.
static void broadcast(Type &value, const label comm=UPstream::worldComm)
Broadcast content (contiguous or non-contiguous) to all communicator ranks. Does nothing in non-paral...
Various functions to operate on Lists.
#define forAll(list, i)
Loop across all elements in list.
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. ...
void setSize(const label n)
Alias for resize()
const List< labelPair > & whichSchedule(const UPstream::commsTypes commsType) const
Return real or dummy schedule depending on the communication type.
"scheduled" : (MPI_Send, MPI_Recv)
static bool hasFlipAddressing(const labelUList &map)
Test for flip addressing, where flips are encoded as negative indices and non-flips are encoded as po...
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
static constexpr int masterNo() noexcept
Relative rank for the master process - is always 0.
void printLayout(Ostream &os) const
Debug: print layout. Can only be used on maps with sorted.
label size() const noexcept
The number of entries in the list.
#define forAllIters(container, iter)
Iterate across all elements in the container object.
bool isLocal(const label proci, const label i) const
Is on processor proci.
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
void transfer(mapDistributeBase &rhs)
Transfer the contents of the argument and annul the argument.
A list of pointers to objects of type <T>, without allocation/deallocation management of the pointers...
errorManip< error > abort(error &err)
A HashTable to objects of type <T> with a labelPair key. The hashing is based on labelPair (FixedList...
label find(const T &val) const
Find index of the first occurrence of the value.
void operator=(const mapDistributeBase &rhs)
Copy assignment.
Class containing processor-to-processor mapping information.
int debug
Static debugging option.
Pair< label > labelPair
A pair of labels.
OBJstream os(runTime.globalPath()/outputName)
defineTypeNameAndDebug(combustionModel, 0)
label subMapTotalSize() const noexcept
The sum of the subMap list sizes.
T & last()
Access last element of the list, position [size()-1].
const labelListList & constructMap() const noexcept
From subsetted data to new reconstructed data.
static label renumber(const globalIndex &, const label comm, const List< Map< label >> &compactMap, const label globalElement)
Helper for construct from globalIndex. Renumbers element.
bool empty() const noexcept
True if the list is empty (ie, size() is zero)
void exchangeAddressing(const int tag, const globalIndex &globalNumbering, labelList &elements, List< Map< label >> &compactMap, labelList &compactStart)
labelList subMapSizes() const
The sizes of the subMap lists.
void clear()
Reset to zero size, only retaining communicator.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
static void exchangeSizes(const labelUList &sendProcs, const labelUList &recvProcs, const Container &sendBufs, labelList &sizes, const label tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Helper: exchange sizes of sendBufs for specified send/recv ranks.
static void checkReceivedSize(const label proci, const label expectedSize, const label receivedSize)
Fatal if expected != received size.
static label getMappedSize(const labelListList &maps, const bool hasFlip)
Scan the maps for the max addressed index.
label constructMapTotalSize() const noexcept
The sum of the constructMap list sizes.
static rangeType subProcs(const label communicator=worldComm)
Range of process indices for sub-processes.
List< label > labelList
A List of labels.
mapDistributeBase() noexcept
Default construct (uses worldComm)
const labelListList & subMap() const noexcept
From subsetted data back to original data.
HashSet< labelPair, Foam::Hash< labelPair > > labelPairHashSet
A HashSet for a labelPair. The hashing is based on labelPair (FixedList) and is thus non-commutative...
labelList constructMapSizes() const
The sizes of the constructMap lists.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Inter-processor communications stream.
FlatOutput::OutputAdaptor< Container, Delimiters > flatOutput(const Container &obj, Delimiters delim)
Global flatOutput() function with specified output delimiters.
static constexpr const zero Zero
Global zero (0)