47 ArrayRCP<const GO> decompEntries;
48 if (decomposition->getLocalLength() > 0)
49 decompEntries = decomposition->getData(0);
51 auto rowMap = decomposition->getMap();
52 auto comm = rowMap->getComm();
53 const auto myRank = comm->getRank();
54 const auto numProcs = comm->getSize();
55 Xpetra::UnderlyingLib lib = rowMap->lib();
58 myGIDs.reserve(decomposition->getLocalLength());
63 typedef std::map<GO, Array<GO> > map_type;
65 for (LO i = 0; i < decompEntries.size(); i++) {
66 GO
id = decompEntries[i];
67 GO GID = rowMap->getGlobalElement(i);
70 myGIDs.push_back(GID);
72 sendMap[id].push_back(GID);
74 decompEntries = Teuchos::null;
76 int numSend = sendMap.size(), numRecv;
79 Array<GO> myParts(numSend), myPart(1);
82 for (
typename map_type::const_iterator it = sendMap.begin(); it != sendMap.end(); it++)
83 myParts[cnt++] = it->first;
85 const GO numLocalKept = myGIDs.size();
90 GO partsIndexBase = 0;
91 RCP<Map> partsIHave = MapFactory ::Build(lib, Teuchos::OrdinalTraits<Xpetra::global_size_t>::invalid(), myParts(), partsIndexBase, comm);
92 RCP<Map> partsIOwn = MapFactory ::Build(lib, numProcs, myPart(), partsIndexBase, comm);
93 RCP<Export> partsExport = ExportFactory::Build(partsIHave, partsIOwn);
95 RCP<GOVector> partsISend = Xpetra::VectorFactory<GO, LO, GO, NO>::Build(partsIHave);
96 RCP<GOVector> numPartsIRecv = Xpetra::VectorFactory<GO, LO, GO, NO>::Build(partsIOwn);
98 ArrayRCP<GO> partsISendData = partsISend->getDataNonConst(0);
99 for (
int i = 0; i < numSend; i++)
100 partsISendData[i] = 1;
102 (numPartsIRecv->getDataNonConst(0))[0] = 0;
104 numPartsIRecv->doExport(*partsISend, *partsExport, Xpetra::ADD);
105 numRecv = (numPartsIRecv->getData(0))[0];
108 RCP<const Teuchos::MpiComm<int> > tmpic = rcp_dynamic_cast<const Teuchos::MpiComm<int> >(comm);
109 TEUCHOS_TEST_FOR_EXCEPTION(tmpic == Teuchos::null,
Exceptions::RuntimeError,
"Cannot cast base Teuchos::Comm to Teuchos::MpiComm object.");
110 RCP<const Teuchos::OpaqueWrapper<MPI_Comm> > rawMpiComm = tmpic->getRawMpiComm();
113 MPI_Datatype MpiType = Teuchos::Details::MpiTypeTraits<GO>::getType();
117 Array<MPI_Request> sendReqs(numSend);
119 for (
typename map_type::iterator it = sendMap.begin(); it != sendMap.end(); it++)
120 MPI_Isend(
static_cast<void*
>(it->second.getRawPtr()), it->second.size(), MpiType, Teuchos::as<GO>(it->first), msgTag, *rawMpiComm, &sendReqs[cnt++]);
123 size_t totalGIDs = myGIDs.size();
124 for (
int i = 0; i < numRecv; i++) {
126 MPI_Probe(MPI_ANY_SOURCE, msgTag, *rawMpiComm, &status);
129 int fromRank = status.MPI_SOURCE, count;
130 MPI_Get_count(&status, MpiType, &count);
132 recvMap[fromRank].resize(count);
133 MPI_Recv(
static_cast<void*
>(recvMap[fromRank].getRawPtr()), count, MpiType, fromRank, msgTag, *rawMpiComm, &status);
140 Array<MPI_Status> sendStatuses(numSend);
141 MPI_Waitall(numSend, sendReqs.getRawPtr(), sendStatuses.getRawPtr());
145 myGIDs.reserve(totalGIDs);
146 for (
typename map_type::const_iterator it = recvMap.begin(); it != recvMap.end(); it++) {
147 int offset = myGIDs.size(), len = it->second.size();
149 myGIDs.resize(offset + len);
150 memcpy(myGIDs.getRawPtr() + offset, it->second.getRawPtr(), len *
sizeof(GO));
155 std::sort(myGIDs.begin(), myGIDs.end());
157 return std::make_tuple(myGIDs, numLocalKept);