44 std::vector<global_size_type> &allOwnedRanges,
45 const MPI_Comm & mpiComm)
48 int err = MPI_Comm_size(mpiComm, &nprocs);
49 std::string errMsg =
"Error occured while using MPI_Comm_size. "
53 std::vector<int> recvCounts(nprocs, 2);
54 std::vector<int> displs(nprocs, 0);
55 allOwnedRanges.resize(2 * nprocs);
56 for (
unsigned int i = 0; i < nprocs; ++i)
59 std::vector<global_size_type> ownedRanges = {ownedRangeStart,
61 MPI_Allgatherv(&ownedRanges[0],
72 getGhostProcIdToLocalGhostIndicesMap(
73 const std::vector<global_size_type> &ghostIndices,
75 const std::vector<global_size_type> &allOwnedRanges,
76 std::map<
size_type, std::vector<size_type>>
77 & ghostProcIdToLocalGhostIndices,
78 const MPI_Comm &mpiComm)
81 int err = MPI_Comm_size(mpiComm, &nprocs);
82 std::string errMsg =
"Error occured while using MPI_Comm_size. "
98 std::vector<global_size_type> locallyOwnedRangesEnd(nprocs);
103 std::vector<size_type> locallyOwnedRangesEndProcIds(nprocs);
104 for (
unsigned int i = 0; i < nprocs; ++i)
106 locallyOwnedRangesEnd[i] = allOwnedRanges[2 * i + 1];
110 if (allOwnedRanges[2 * i + 1] == allOwnedRanges[2 * i])
111 locallyOwnedRangesEnd[i] = (nGlobalIndices + 1 + i);
112 locallyOwnedRangesEndProcIds[i] = i;
115 std::sort(locallyOwnedRangesEndProcIds.begin(),
116 locallyOwnedRangesEndProcIds.end(),
118 return locallyOwnedRangesEnd[x] <
119 locallyOwnedRangesEnd[y];
122 std::sort(locallyOwnedRangesEnd.begin(), locallyOwnedRangesEnd.end());
124 const size_type numGhosts = ghostIndices.size();
125 for (
unsigned int iGhost = 0; iGhost < numGhosts; ++iGhost)
128 auto up = std::upper_bound(locallyOwnedRangesEnd.begin(),
129 locallyOwnedRangesEnd.end(),
131 std::string msg =
"Ghost index " + std::to_string(ghostIndex) +
132 " not found in any of the processors";
135 std::distance(locallyOwnedRangesEnd.begin(), up);
136 size_type procId = locallyOwnedRangesEndProcIds[upPos];
137 ghostProcIdToLocalGhostIndices[procId].push_back(iGhost);
142 checkContiguity(
const std::vector<size_type> &v)
145 bool returnValue =
true;
146 for (
unsigned int i = 1; i < N; ++i)
148 if ((v[i] - 1) != v[i - 1])
165 compareRangeMetaData(
const RangeMetaData &x,
const RangeMetaData &y)
168 return (!x.isRangeStart);
172 std::vector<size_type>
173 getOverlappingRangeIds(
const std::vector<global_size_type> &ranges)
176 std::vector<RangeMetaData> rangeMetaDataVec(0);
177 for (
unsigned int i = 0; i < numRanges; ++i)
180 left.Id = ranges[2 * i];
182 left.isRangeStart =
true;
185 right.Id = ranges[2 * i + 1];
187 right.isRangeStart =
false;
190 if (left.Id != right.Id)
192 rangeMetaDataVec.push_back(left);
193 rangeMetaDataVec.push_back(right);
196 std::sort(rangeMetaDataVec.begin(),
197 rangeMetaDataVec.end(),
198 compareRangeMetaData);
199 int currentOpen = -1;
201 std::vector<size_type> returnValue(0);
202 for (
unsigned int i = 0; i < rangeMetaDataVec.size(); ++i)
204 size_type rangeId = rangeMetaDataVec[i].rangeId;
205 if (rangeMetaDataVec[i].isRangeStart)
207 if (currentOpen == -1)
209 currentOpen = rangeId;
216 returnValue.push_back(currentOpen);
219 returnValue.push_back(rangeId);
220 if (ranges[2 * rangeId + 1] > ranges[2 * currentOpen + 1])
222 currentOpen = rangeId;
229 if (rangeId == currentOpen)
244 template <dftfe::utils::MemorySpace memorySpace>
246 const std::pair<global_size_type, global_size_type> &locallyOwnedRange,
247 const std::vector<dftfe::global_size_type> & ghostIndices,
248 const MPI_Comm & mpiComm)
269 std::string errMsg =
"Error occured while using MPI_Comm_size. "
275 errMsg =
"Error occured while using MPI_Comm_rank. "
282 "In processor " + std::to_string(
d_myRank) +
283 ", invalid locally owned range found "
284 "(i.e., the second value in the range is less than the first value).");
294 bool isStrictlyIncreasing = std::is_sorted(ghostIndices.begin(),
296 std::less_equal<>());
298 isStrictlyIncreasing,
299 "In processor " + std::to_string(
d_myRank) +
300 ", the ghost indices passed to MPIPatternP2P is not a strictly increasing set.");
306 std::copy(ghostIndices.begin(),
323 std::vector<size_type> overlappingRangeIds =
326 overlappingRangeIds.size() == 0,
327 "Detected overlapping ranges among the locallyOwnedRanges passed "
331 for (
unsigned int i = 0; i <
d_nprocs; ++i)
337 if (ghostIndices.size() > 0)
341 "Detected global ghost index to be larger than (nGlobalIndices-1)");
344 std::map<size_type, std::vector<size_type>>
345 ghostProcIdToLocalGhostIndices;
346 getGhostProcIdToLocalGhostIndicesMap(ghostIndices,
349 ghostProcIdToLocalGhostIndices,
357 std::vector<size_type> flattenedLocalGhostIndicesTmp(0);
358 auto it = ghostProcIdToLocalGhostIndices.begin();
359 unsigned int iGhostProc = 0;
360 for (; it != ghostProcIdToLocalGhostIndices.end(); ++it)
363 const std::vector<size_type> localGhostIndicesInGhostProc =
365 bool isContiguous = checkContiguity(localGhostIndicesInGhostProc);
366 std::string msg =
"In rank " + std::to_string(
d_myRank) +
367 ", the local ghost indices that are owned"
370 " does not form a contiguous set.";
373 localGhostIndicesInGhostProc.size();
376 *(localGhostIndicesInGhostProc.begin());
378 *(localGhostIndicesInGhostProc.end() - 1) + 1;
383 std::copy(localGhostIndicesInGhostProc.begin(),
384 localGhostIndicesInGhostProc.end(),
385 back_inserter(flattenedLocalGhostIndicesTmp));
389 std::string msg =
"In rank " + std::to_string(
d_myRank) +
391 " the sizes of ghost indices. Expected size: " +
394 std::to_string(flattenedLocalGhostIndicesTmp.size());
404 &flattenedLocalGhostIndicesTmp[0]);
432 &sendRequests[iGhost]);
433 std::string errMsg =
"Error occured while using MPI_Isend. "
448 &recvRequests[iTarget]);
449 std::string errMsg =
"Error occured while using MPI_Irecv. "
455 if (sendRequests.size() > 0)
459 sendStatuses.data());
460 errMsg =
"Error occured while using MPI_Waitall. "
466 if (recvRequests.size() > 0)
470 recvStatuses.data());
471 errMsg =
"Error occured while using MPI_Waitall. "
478 size_type totalOwnedIndicesForTargetProcs =
484 std::vector<size_type> flattenedLocalTargetIndicesTmp(
485 totalOwnedIndicesForTargetProcs, 0);
492 const int numGhostIndicesInProc =
499 for (
unsigned int iIndex = 0; iIndex < numGhostIndicesInProc;
503 flattenedLocalGhostIndicesTmp[startIndex + iIndex];
510 ghostIndices[ghostLocalIndex];
513 localIndicesForGhostProc[startIndex + iIndex] =
514 (
size_type)(ghostGlobalIndex - ghostProcOwnedIndicesStart);
517 localIndicesForGhostProc[startIndex + iIndex] <
523 err = MPI_Isend(&localIndicesForGhostProc[startIndex],
524 numGhostIndicesInProc,
529 &sendRequests[iGhost]);
530 std::string errMsg =
"Error occured while using MPI_Isend. "
534 startIndex += numGhostIndicesInProc;
541 const int numOwnedIndicesForTarget =
543 err = MPI_Irecv(&flattenedLocalTargetIndicesTmp[startIndex],
544 numOwnedIndicesForTarget,
549 &recvRequests[iTarget]);
550 std::string errMsg =
"Error occured while using MPI_Irecv. "
554 startIndex += numOwnedIndicesForTarget;
557 if (sendRequests.size() > 0)
561 sendStatuses.data());
562 errMsg =
"Error occured while using MPI_Waitall. "
568 if (recvRequests.size() > 0)
572 recvStatuses.data());
573 errMsg =
"Error occured while using MPI_Waitall. "
579 for (
size_type i = 0; i < totalOwnedIndicesForTargetProcs; ++i)
583 "Detected local owned target index to be larger than (nLocallyOwnedIndices-1)");
587 if (totalOwnedIndicesForTargetProcs > 0)
588 memoryTransfer.
copy(totalOwnedIndicesForTargetProcs,
590 &flattenedLocalTargetIndicesTmp[0]);
601 template <dftfe::utils::MemorySpace memorySpace>
624 "In processor " + std::to_string(
d_myRank) +
625 ", invalid locally owned range found "
626 "(i.e., the second value in the range is less than the first value).");
631 for (
unsigned int i = 0; i <
d_nprocs; ++i)
641 template <dftfe::utils::MemorySpace memorySpace>
642 std::pair<global_size_type, global_size_type>
648 template <dftfe::utils::MemorySpace memorySpace>
649 const std::vector<global_size_type> &
655 template <dftfe::utils::MemorySpace memorySpace>
656 const std::vector<size_type> &
662 template <dftfe::utils::MemorySpace memorySpace>
663 const std::vector<size_type> &
670 template <dftfe::utils::MemorySpace memorySpace>
671 const std::vector<size_type> &
677 template <dftfe::utils::MemorySpace memorySpace>
687 numGhostIndicesInProc = *itNumGhostIndices;
688 if (procId == *itProcIds)
695 "The processor Id " + std::to_string(procId) +
696 " does not contain any ghost indices for the current processor"
697 " (i.e., processor Id " +
701 return numGhostIndicesInProc;
704 template <dftfe::utils::MemorySpace memorySpace>
715 numGhostIndicesInProc = *itNumGhostIndices;
716 if (procId == *itProcIds)
719 cumulativeIndices += numGhostIndicesInProc;
724 "The processor Id " + std::to_string(procId) +
725 " does not contain any ghost indices for the current processor"
726 " (i.e., processor Id " +
732 numGhostIndicesInProc,
739 template <dftfe::utils::MemorySpace memorySpace>
740 const std::vector<size_type> &
746 template <dftfe::utils::MemorySpace memorySpace>
747 const std::vector<size_type> &
753 template <dftfe::utils::MemorySpace memorySpace>
760 template <dftfe::utils::MemorySpace memorySpace>
770 numOwnedIndicesForProc = *itNumOwnedIndices;
771 if (procId == *itProcIds)
777 std::string msg =
"There are no owned indices for "
778 " target processor Id " +
779 std::to_string(procId) +
780 " in the current processor"
781 " (i.e., processor Id " +
785 return numOwnedIndicesForProc;
788 template <dftfe::utils::MemorySpace memorySpace>
799 numOwnedIndicesForProc = *itNumOwnedIndices;
800 if (procId == *itProcIds)
803 cumulativeIndices += numOwnedIndicesForProc;
807 std::string msg =
"There are no owned indices for "
808 " target processor Id " +
809 std::to_string(procId) +
810 " in the current processor"
811 " (i.e., processor Id " +
818 numOwnedIndicesForProc,
827 template <dftfe::utils::MemorySpace memorySpace>
834 template <dftfe::utils::MemorySpace memorySpace>
841 template <dftfe::utils::MemorySpace memorySpace>
848 template <dftfe::utils::MemorySpace memorySpace>
855 template <dftfe::utils::MemorySpace memorySpace>
862 template <dftfe::utils::MemorySpace memorySpace>
870 template <dftfe::utils::MemorySpace memorySpace>
888 "In processor " + std::to_string(
d_myRank) +
889 ", the local index " + std::to_string(localId) +
890 " passed to localToGlobal() in MPIPatternP2P is"
891 " larger than number of locally owned plus ghost indices.";
897 template <dftfe::utils::MemorySpace memorySpace>
915 "In processor " + std::to_string(
d_myRank) +
916 ", the global index " + std::to_string(globalId) +
917 " passed to globalToLocal() in MPIPatternP2P is"
918 " neither present in its locally owned range nor in its "
927 template <dftfe::utils::MemorySpace memorySpace>
936 template <dftfe::utils::MemorySpace memorySpace>
947 template <dftfe::utils::MemorySpace memorySpace>
iterator begin()
Return iterator pointing to the beginning of point data.
Definition MemoryStorage.t.cc:130
Definition MemoryTransfer.h:33
static void copy(std::size_t size, ValueType *dst, const ValueType *src)
Copy array from the memory space of source to the memory space of destination.
Definition OptimizedIndexSet.h:44
SizeTypeVector getOwnedLocalIndices(const size_type procId) const
Definition MPIPatternP2P.t.cc:790
size_type globalToLocal(const global_size_type globalId) const
Definition MPIPatternP2P.t.cc:899
const std::vector< size_type > & getGhostLocalIndicesRanges() const
Definition MPIPatternP2P.t.cc:672
size_type getNumGhostIndicesInProc(const size_type procId) const
Definition MPIPatternP2P.t.cc:679
MPIPatternP2P(const std::pair< global_size_type, global_size_type > &locallyOwnedRange, const std::vector< dftfe::global_size_type > &ghostIndices, const MPI_Comm &mpiComm)
Constructor. This constructor is the typical way of creation of an MPI pattern.
Definition MPIPatternP2P.t.cc:245
global_size_type localToGlobal(const size_type localId) const
Definition MPIPatternP2P.t.cc:872
size_type d_numTargetProcs
Definition MPIPatternP2P.h:326
size_type getNumOwnedIndicesForTargetProc(const size_type procId) const
Definition MPIPatternP2P.t.cc:762
utils::MemoryStorage< size_type, memorySpace > SizeTypeVector
Definition MPIPatternP2P.h:62
size_type thisProcessId() const
Definition MPIPatternP2P.t.cc:843
SizeTypeVector d_flattenedLocalTargetIndices
Definition MPIPatternP2P.h:363
OptimizedIndexSet< global_size_type > d_ghostIndicesOptimizedIndexSet
Definition MPIPatternP2P.h:242
int d_myRank
Rank of the current processor.
Definition MPIPatternP2P.h:369
SizeTypeVector getGhostLocalIndices(const size_type procId) const
Definition MPIPatternP2P.t.cc:706
int d_nprocs
Number of processors in the MPI Communicator.
Definition MPIPatternP2P.h:366
const std::vector< size_type > & getGhostProcIds() const
Definition MPIPatternP2P.t.cc:657
std::pair< global_size_type, global_size_type > getLocallyOwnedRange() const
Definition MPIPatternP2P.t.cc:643
std::set< global_size_type > d_ghostIndicesSetSTL
Definition MPIPatternP2P.h:234
const SizeTypeVector & getOwnedLocalIndicesForTargetProcs() const
Definition MPIPatternP2P.t.cc:755
size_type localOwnedSize() const
Definition MPIPatternP2P.t.cc:857
size_type d_numGhostProcs
Definition MPIPatternP2P.h:249
global_size_type d_nGlobalIndices
Definition MPIPatternP2P.h:374
const std::vector< size_type > & getTargetProcIds() const
Definition MPIPatternP2P.t.cc:741
const std::vector< size_type > & getNumOwnedIndicesForTargetProcs() const
Definition MPIPatternP2P.t.cc:748
size_type d_numGhostIndices
Definition MPIPatternP2P.h:223
bool isCompatible(const MPIPatternP2P< memorySpace > &rhs) const
Definition MPIPatternP2P.t.cc:949
SizeTypeVector d_flattenedLocalGhostIndices
Definition MPIPatternP2P.h:297
std::vector< size_type > d_targetProcIds
Definition MPIPatternP2P.h:333
std::vector< global_size_type > d_allOwnedRanges
Definition MPIPatternP2P.h:213
global_size_type nGlobalIndices() const
Definition MPIPatternP2P.t.cc:850
std::vector< size_type > d_numGhostIndicesInGhostProcs
Definition MPIPatternP2P.h:261
std::pair< global_size_type, global_size_type > d_locallyOwnedRange
Definition MPIPatternP2P.h:202
const std::vector< size_type > & getNumGhostIndicesInProcs() const
Definition MPIPatternP2P.t.cc:664
size_type nmpiProcesses() const
Definition MPIPatternP2P.t.cc:836
bool inLocallyOwnedRange(const global_size_type globalId) const
Definition MPIPatternP2P.t.cc:929
bool isGhostEntry(const global_size_type globalId) const
Definition MPIPatternP2P.t.cc:938
size_type localGhostSize() const
Definition MPIPatternP2P.t.cc:864
const MPI_Comm & mpiCommunicator() const
Definition MPIPatternP2P.t.cc:829
std::vector< size_type > d_numOwnedIndicesForTargetProcs
Definition MPIPatternP2P.h:341
std::vector< global_size_type > d_ghostIndices
Definition MPIPatternP2P.h:229
size_type d_numLocallyOwnedIndices
Definition MPIPatternP2P.h:218
std::vector< size_type > d_ghostProcIds
Definition MPIPatternP2P.h:255
std::vector< size_type > d_localGhostIndicesRanges
A vector of size 2 times the number of ghost processors to store the range of local ghost indices tha...
Definition MPIPatternP2P.h:319
MPI_Comm d_mpiComm
MPI Communicator object.
Definition MPIPatternP2P.h:377
const std::vector< global_size_type > & getGhostIndices() const
Definition MPIPatternP2P.t.cc:650
Definition MPIRequestersNBX.h:38
std::vector< size_type > getRequestingRankIds() override
Definition MPICommunicatorP2P.h:46
@ MPI_P2P_PATTERN_TAG
Definition MPITags.h:41
void throwException(bool condition, std::string msg="")
Definition pseudoPotentialToDftfeConverter.cc:34
unsigned int size_type
Definition TypeConfig.h:6
unsigned long int global_size_type
Definition TypeConfig.h:7