42 #ifndef __Tpetra_DirectoryImpl_def_hpp 43 #define __Tpetra_DirectoryImpl_def_hpp 49 #include <Tpetra_Distributor.hpp> 50 #include <Tpetra_Map.hpp> 53 #include <Tpetra_Details_FixedHashTable.hpp> 54 #include <Tpetra_HashTable.hpp> 66 template<
class LO,
class GO,
class NT>
70 template<
class LO,
class GO,
class NT>
74 const Teuchos::ArrayView<const GO> &globalIDs,
75 const Teuchos::ArrayView<int> &nodeIDs,
76 const Teuchos::ArrayView<LO> &localIDs,
77 const bool computeLIDs)
const 81 TEUCHOS_TEST_FOR_EXCEPTION(nodeIDs.size() != globalIDs.size(),
82 std::invalid_argument, Teuchos::typeName(*
this) <<
"::getEntries(): " 83 "Output arrays do not have the right sizes. nodeIDs.size() = " 84 << nodeIDs.size() <<
" != globalIDs.size() = " << globalIDs.size()
86 TEUCHOS_TEST_FOR_EXCEPTION(
87 computeLIDs && localIDs.size() != globalIDs.size(),
88 std::invalid_argument, Teuchos::typeName(*
this) <<
"::getEntries(): " 89 "Output array do not have the right sizes. localIDs.size() = " 90 << localIDs.size() <<
" != globalIDs.size() = " << globalIDs.size()
98 std::fill (nodeIDs.begin(), nodeIDs.end(), -1);
100 std::fill (localIDs.begin(), localIDs.end(),
101 Teuchos::OrdinalTraits<LO>::invalid ());
104 return this->getEntriesImpl (map, globalIDs, nodeIDs, localIDs, computeLIDs);
108 template<
class LO,
class GO,
class NT>
111 numProcs_ (map.getComm ()->getSize ())
115 template<
class LO,
class GO,
class NT>
122 template<
class LO,
class GO,
class NT>
130 return (numProcs_ == 1);
134 template<
class LO,
class GO,
class NT>
138 std::ostringstream os;
139 os <<
"ReplicatedDirectory" 140 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
141 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
142 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
147 template<
class LO,
class GO,
class NT>
151 TEUCHOS_TEST_FOR_EXCEPTION(! map.
isContiguous (), std::invalid_argument,
152 Teuchos::typeName (*
this) <<
" constructor: Map is not contiguous.");
153 TEUCHOS_TEST_FOR_EXCEPTION(! map.
isUniform (), std::invalid_argument,
154 Teuchos::typeName (*
this) <<
" constructor: Map is not uniform.");
158 template<
class LO,
class GO,
class NT>
162 std::ostringstream os;
163 os <<
"ContiguousUniformDirectory" 164 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
165 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
166 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
171 template<
class LO,
class GO,
class NT>
175 const Teuchos::ArrayView<const GO> &globalIDs,
176 const Teuchos::ArrayView<int> &nodeIDs,
177 const Teuchos::ArrayView<LO> &localIDs,
178 const bool computeLIDs)
const 182 typedef typename Teuchos::ArrayView<const GO>::size_type size_type;
183 const LO invalidLid = Teuchos::OrdinalTraits<LO>::invalid ();
186 RCP<const Comm<int> > comm = map.
getComm ();
210 const size_type N_G =
212 const size_type P =
static_cast<size_type
> (comm->getSize ());
213 const size_type N_L = N_G / P;
214 const size_type R = N_G - N_L * P;
215 const size_type N_R = R * (N_L +
static_cast<size_type
> (1));
217 #ifdef HAVE_TPETRA_DEBUG 218 TEUCHOS_TEST_FOR_EXCEPTION(
219 N_G != P*N_L + R, std::logic_error,
220 "Tpetra::ContiguousUniformDirectory::getEntriesImpl: " 221 "N_G = " << N_G <<
" != P*N_L + R = " << P <<
"*" << N_L <<
" + " << R
222 <<
" = " << P*N_L + R <<
". " 223 "Please report this bug to the Tpetra developers.");
224 #endif // HAVE_TPETRA_DEBUG 226 const size_type numGids = globalIDs.size ();
229 const GO ONE =
static_cast<GO
> (1);
232 for (size_type k = 0; k < numGids; ++k) {
233 const GO g_0 = globalIDs[k] - g_min;
239 if (g_0 + ONE < ONE || g_0 >= static_cast<GO> (N_G)) {
241 localIDs[k] = invalidLid;
244 else if (g_0 < static_cast<GO> (N_R)) {
246 nodeIDs[k] =
static_cast<int> (g_0 /
static_cast<GO
> (N_L + 1));
247 localIDs[k] =
static_cast<LO
> (g_0 %
static_cast<GO
> (N_L + 1));
249 else if (g_0 >= static_cast<GO> (N_R)) {
251 const GO g_R = g_0 -
static_cast<GO
> (N_R);
252 nodeIDs[k] =
static_cast<int> (R + g_R / N_L);
253 localIDs[k] =
static_cast<int> (g_R % N_L);
255 #ifdef HAVE_TPETRA_DEBUG 257 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
258 "Tpetra::ContiguousUniformDirectory::getEntriesImpl: " 259 "should never get here. " 260 "Please report this bug to the Tpetra developers.");
262 #endif // HAVE_TPETRA_DEBUG 266 for (size_type k = 0; k < numGids; ++k) {
267 const GO g_0 = globalIDs[k] - g_min;
272 if (g_0 + ONE < ONE || g_0 >= static_cast<GO> (N_G)) {
276 else if (g_0 < static_cast<GO> (N_R)) {
278 nodeIDs[k] =
static_cast<int> (g_0 /
static_cast<GO
> (N_L + 1));
280 else if (g_0 >= static_cast<GO> (N_R)) {
282 const GO g_R = g_0 -
static_cast<GO
> (N_R);
283 nodeIDs[k] =
static_cast<int> (R + g_R / N_L);
285 #ifdef HAVE_TPETRA_DEBUG 287 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
288 "Tpetra::ContiguousUniformDirectory::getEntriesImpl: " 289 "should never get here. " 290 "Please report this bug to the Tpetra developers.");
292 #endif // HAVE_TPETRA_DEBUG 298 template<
class LO,
class GO,
class NT>
302 using Teuchos::gatherAll;
305 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
307 TEUCHOS_TEST_FOR_EXCEPTION(! map.
isDistributed (), std::invalid_argument,
308 Teuchos::typeName (*
this) <<
" constructor: Map is not distributed.");
309 TEUCHOS_TEST_FOR_EXCEPTION(! map.
isContiguous (), std::invalid_argument,
310 Teuchos::typeName (*
this) <<
" constructor: Map is not contiguous.");
312 const int numProcs = comm->getSize ();
316 allMinGIDs_ = arcp<GO> (numProcs + 1);
330 MPI_Datatype rawMpiType = MPI_INT;
331 bool useRawMpi =
true;
332 if (
typeid (GO) ==
typeid (
int)) {
333 rawMpiType = MPI_INT;
334 }
else if (
typeid (GO) ==
typeid (
long)) {
335 rawMpiType = MPI_LONG;
340 using Teuchos::rcp_dynamic_cast;
341 using Teuchos::MpiComm;
342 RCP<const MpiComm<int> > mpiComm =
343 rcp_dynamic_cast<
const MpiComm<int> > (comm);
346 if (! comm.is_null ()) {
347 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
349 MPI_Allgather (&minMyGID, 1, rawMpiType,
350 allMinGIDs_.getRawPtr (), 1, rawMpiType,
352 TEUCHOS_TEST_FOR_EXCEPTION(err != MPI_SUCCESS, std::runtime_error,
353 "Tpetra::DistributedContiguousDirectory: MPI_Allgather failed");
355 gatherAll<int, GO> (*comm, 1, &minMyGID, numProcs, allMinGIDs_.getRawPtr ());
358 gatherAll<int, GO> (*comm, 1, &minMyGID, numProcs, allMinGIDs_.getRawPtr ());
360 #else // NOT HAVE_MPI 361 gatherAll<int, GO> (*comm, 1, &minMyGID, numProcs, allMinGIDs_.getRawPtr ());
370 + Teuchos::OrdinalTraits<GO>::one ();
373 template<
class LO,
class GO,
class NT>
377 std::ostringstream os;
378 os <<
"DistributedContiguousDirectory" 379 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
380 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
381 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
385 template<
class LO,
class GO,
class NT>
389 const Teuchos::ArrayView<const GO> &globalIDs,
390 const Teuchos::ArrayView<int> &nodeIDs,
391 const Teuchos::ArrayView<LO> &localIDs,
392 const bool computeLIDs)
const 394 using Teuchos::Array;
395 using Teuchos::ArrayRCP;
396 using Teuchos::ArrayView;
402 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
403 const int myRank = comm->getRank ();
406 typename ArrayView<int>::iterator procIter = nodeIDs.begin();
407 typename ArrayView<LO>::iterator lidIter = localIDs.begin();
408 typename ArrayView<const GO>::iterator gidIter;
409 for (gidIter = globalIDs.begin(); gidIter != globalIDs.end(); ++gidIter) {
411 *procIter++ = myRank;
428 template<
class LO,
class GO,
class NT>
432 const Teuchos::ArrayView<const GO> &globalIDs,
433 const Teuchos::ArrayView<int> &nodeIDs,
434 const Teuchos::ArrayView<LO> &localIDs,
435 const bool computeLIDs)
const 437 using Teuchos::Array;
438 using Teuchos::ArrayRCP;
439 using Teuchos::ArrayView;
444 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
445 const int numProcs = comm->getSize ();
447 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid();
451 typename ArrayView<int>::iterator procIter = nodeIDs.begin();
452 typename ArrayView<LO>::iterator lidIter = localIDs.begin();
453 typename ArrayView<const GO>::iterator gidIter;
454 for (gidIter = globalIDs.begin(); gidIter != globalIDs.end(); ++gidIter) {
464 const GO one = as<GO> (1);
465 const GO two = as<GO> (2);
466 const GO nOverP_GID = as<GO> (nOverP);
467 const GO lowerBound = GID / std::max(nOverP_GID, one) + two;
468 curRank = as<int>(std::min(lowerBound, as<GO>(numProcs - 1)));
471 while (curRank >= 0 && curRank < numProcs) {
472 if (allMinGIDs_[curRank] <= GID) {
473 if (GID < allMinGIDs_[curRank + 1]) {
487 LID = as<LO> (GID - allMinGIDs_[image]);
500 template<
class LO,
class GO,
class NT>
503 oneToOneResult_ (ONE_TO_ONE_NOT_CALLED_YET),
504 locallyOneToOne_ (true),
505 useHashTables_ (false)
507 initialize (map, Teuchos::null);
510 template<
class LO,
class GO,
class NT>
514 oneToOneResult_ (ONE_TO_ONE_NOT_CALLED_YET),
515 locallyOneToOne_ (true),
516 useHashTables_ (false)
518 initialize (map, Teuchos::ptrFromRef (tie_break));
521 template<
class LO,
class GO,
class NT>
525 Teuchos::Ptr<const tie_break_type> tie_break)
527 using Teuchos::Array;
528 using Teuchos::ArrayView;
532 using Teuchos::typeName;
533 using Teuchos::TypeNameTraits;
536 typedef Array<int>::size_type size_type;
546 TEUCHOS_TEST_FOR_EXCEPTION(
sizeof(
global_size_t) <
sizeof(GO),
547 std::logic_error, typeName (*
this) <<
": sizeof(Tpetra::" 548 "global_size_t) = " <<
sizeof(
global_size_t) <<
" < sizeof(Global" 549 "Ordinal = " << TypeNameTraits<LO>::name () <<
") = " <<
sizeof(GO)
551 TEUCHOS_TEST_FOR_EXCEPTION(
sizeof(
global_size_t) <
sizeof(
int),
552 std::logic_error, typeName (*
this) <<
": sizeof(Tpetra::" 553 "global_size_t) = " <<
sizeof(
global_size_t) <<
" < sizeof(int) = " 554 <<
sizeof(
int) <<
".");
555 TEUCHOS_TEST_FOR_EXCEPTION(
sizeof(
global_size_t) <
sizeof(LO),
556 std::logic_error, typeName (*
this) <<
": sizeof(Tpetra::" 557 "global_size_t) = " <<
sizeof(
global_size_t) <<
" < sizeof(Local" 558 "Ordinal = " << TypeNameTraits<LO>::name () <<
") = " <<
sizeof(LO)
561 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
562 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
571 const global_size_t numGlobalEntries = maxAllGID - minAllGID + 1;
581 directoryMap_ = rcp (
new map_type (numGlobalEntries, minAllGID, comm,
582 GloballyDistributed, map.
getNode ()));
584 const size_t dir_numMyEntries = directoryMap_->getNodeNumElements ();
608 const size_t inverseSparsityThreshold = 10;
615 const int myRank = comm->getRank ();
617 Array<int> sendImageIDs (numMyEntries);
623 directoryMap_->getRemoteIndexList (myGlobalEntries, sendImageIDs);
624 TEUCHOS_TEST_FOR_EXCEPTION(
625 lookupStatus ==
IDNotPresent, std::logic_error, Teuchos::typeName(*
this)
626 <<
" constructor: the Directory Map could not find out where one or " 627 "more of my Map's indices should go. The input to getRemoteIndexList " 628 "is " << Teuchos::toString (myGlobalEntries) <<
", and the output is " 629 << Teuchos::toString (sendImageIDs ()) <<
". The input Map itself has " 630 "the following entries on the calling process " <<
631 map.
getComm ()->getRank () <<
": " <<
635 <<
"]. The Directory Map has " 636 << directoryMap_->getGlobalNumElements () <<
" total global indices in " 637 "[" << directoryMap_->getMinAllGlobalIndex () <<
"," <<
638 directoryMap_->getMaxAllGlobalIndex () <<
"], and the calling process " 639 "has GIDs [" << directoryMap_->getMinGlobalIndex () <<
"," <<
640 directoryMap_->getMaxGlobalIndex () <<
"]. " 641 "This probably means there is a bug in Map or Directory. " 642 "Please report this bug to the Tpetra developers.");
650 const size_t numReceives = distor.createFromSends (sendImageIDs);
664 const int packetSize = 3;
665 Array<GO> exportEntries (packetSize * numMyEntries);
667 size_type exportIndex = 0;
668 for (size_type i = 0; i < static_cast<size_type> (numMyEntries); ++i) {
669 exportEntries[exportIndex++] = myGlobalEntries[i];
670 exportEntries[exportIndex++] = as<GO> (myRank);
671 exportEntries[exportIndex++] = as<GO> (i);
677 Array<GO> importElements (packetSize * distor.getTotalReceiveLength ());
680 distor.doPostsAndWaits (exportEntries ().getConst (), packetSize, importElements ());
687 if (useHashTables_) {
702 LO* tableKeysRaw = NULL;
703 LO* tableLidsRaw = NULL;
704 int* tablePidsRaw = NULL;
706 tableKeysRaw =
new LO [numReceives];
707 tableLidsRaw =
new LO [numReceives];
708 tablePidsRaw =
new int [numReceives];
710 if (tableKeysRaw != NULL) {
711 delete [] tableKeysRaw;
713 if (tableLidsRaw != NULL) {
714 delete [] tableLidsRaw;
716 if (tablePidsRaw != NULL) {
717 delete [] tablePidsRaw;
721 ArrayRCP<LO> tableKeys (tableKeysRaw, 0, numReceives,
true);
722 ArrayRCP<LO> tableLids (tableLidsRaw, 0, numReceives,
true);
723 ArrayRCP<int> tablePids (tablePidsRaw, 0, numReceives,
true);
725 if (tie_break.is_null ()) {
727 size_type importIndex = 0;
728 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
729 const GO curGID = importElements[importIndex++];
730 const LO curLID = directoryMap_->getLocalElement (curGID);
731 TEUCHOS_TEST_FOR_EXCEPTION(
732 curLID == LINVALID, std::logic_error,
733 Teuchos::typeName(*
this) <<
" constructor: Incoming global index " 734 << curGID <<
" does not have a corresponding local index in the " 735 "Directory Map. Please report this bug to the Tpetra developers.");
736 tableKeys[i] = curLID;
737 tablePids[i] = importElements[importIndex++];
738 tableLids[i] = importElements[importIndex++];
743 typedef Kokkos::Device<
typename NT::execution_space,
744 typename NT::memory_space> DT;
748 locallyOneToOne_ = ! (lidToPidTable_->hasDuplicateKeys ());
760 typedef std::map<LO, std::vector<std::pair<int, LO> > > pair_table_type;
761 pair_table_type ownedPidLidPairs;
765 size_type importIndex = 0;
766 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
767 const GO curGID = importElements[importIndex++];
768 const LO dirMapLid = directoryMap_->getLocalElement (curGID);
769 TEUCHOS_TEST_FOR_EXCEPTION(
770 dirMapLid == LINVALID, std::logic_error,
771 Teuchos::typeName(*
this) <<
" constructor: Incoming global index " 772 << curGID <<
" does not have a corresponding local index in the " 773 "Directory Map. Please report this bug to the Tpetra developers.");
774 tableKeys[i] = dirMapLid;
775 const int PID = importElements[importIndex++];
776 const int LID = importElements[importIndex++];
786 ownedPidLidPairs[dirMapLid].push_back (std::make_pair (PID, LID));
794 const size_type numPairs =
795 static_cast<size_type
> (ownedPidLidPairs.size ());
796 for (size_type i = 0; i < numPairs; ++i) {
797 const LO dirMapLid =
static_cast<LO
> (i);
798 const GO dirMapGid = directoryMap_->getGlobalElement (dirMapLid);
799 const std::vector<std::pair<int, LO> >& pidLidList =
801 const size_t listLen = pidLidList.size ();
804 locallyOneToOne_ =
false;
813 const size_type index =
814 static_cast<size_type
> (tie_break->selectedIndex (dirMapGid,
816 tablePids[i] = pidLidList[index].first;
817 tableLids[i] = pidLidList[index].second;
822 typedef Kokkos::Device<
typename NT::execution_space,
823 typename NT::memory_space> DT;
833 if (tie_break.is_null ()) {
838 PIDs_ = arcp<int> (dir_numMyEntries);
839 std::fill (PIDs_.begin (), PIDs_.end (), -1);
840 LIDs_ = arcp<LO> (dir_numMyEntries);
841 std::fill (LIDs_.begin (), LIDs_.end (), LINVALID);
843 size_type importIndex = 0;
844 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
845 const GO curGID = importElements[importIndex++];
846 const LO curLID = directoryMap_->getLocalElement (curGID);
847 TEUCHOS_TEST_FOR_EXCEPTION(curLID == LINVALID, std::logic_error,
848 Teuchos::typeName(*
this) <<
" constructor: Incoming global index " 849 << curGID <<
" does not have a corresponding local index in the " 850 "Directory Map. Please report this bug to the Tpetra developers.");
855 if (PIDs_[curLID] != -1) {
856 locallyOneToOne_ =
false;
858 PIDs_[curLID] = importElements[importIndex++];
859 LIDs_[curLID] = importElements[importIndex++];
863 PIDs_ = arcp<int> (dir_numMyEntries);
864 LIDs_ = arcp<LO> (dir_numMyEntries);
865 std::fill (PIDs_.begin (), PIDs_.end (), -1);
874 Array<std::vector<std::pair<int, LO> > > ownedPidLidPairs (dir_numMyEntries);
875 size_type importIndex = 0;
876 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
877 const GO GID = importElements[importIndex++];
878 const int PID = importElements[importIndex++];
879 const LO LID = importElements[importIndex++];
881 const LO dirMapLid = directoryMap_->getLocalElement (GID);
882 TEUCHOS_TEST_FOR_EXCEPTION(
883 dirMapLid == LINVALID, std::logic_error,
884 Teuchos::typeName(*
this) <<
" constructor: Incoming global index " 885 << GID <<
" does not have a corresponding local index in the " 886 "Directory Map. Please report this bug to the Tpetra developers.");
887 ownedPidLidPairs[dirMapLid].push_back (std::make_pair (PID, LID));
895 const size_type numPairs =
896 static_cast<size_type
> (ownedPidLidPairs.size ());
897 for (size_type i = 0; i < numPairs; ++i) {
898 const LO dirMapLid =
static_cast<LO
> (i);
899 const GO dirMapGid = directoryMap_->getGlobalElement (dirMapLid);
900 const std::vector<std::pair<int, LO> >& pidLidList =
902 const size_t listLen = pidLidList.size ();
905 locallyOneToOne_ =
false;
914 const size_type index =
915 static_cast<size_type
> (tie_break->selectedIndex (dirMapGid,
917 PIDs_[i] = pidLidList[index].first;
918 LIDs_[i] = pidLidList[index].second;
926 template<
class LO,
class GO,
class NT>
930 std::ostringstream os;
931 os <<
"DistributedNoncontiguousDirectory" 932 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
933 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
934 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
938 template<
class LO,
class GO,
class NT>
942 const Teuchos::ArrayView<const GO> &globalIDs,
943 const Teuchos::ArrayView<int> &nodeIDs,
944 const Teuchos::ArrayView<LO> &localIDs,
945 const bool computeLIDs)
const 947 using Teuchos::Array;
948 using Teuchos::ArrayRCP;
949 using Teuchos::ArrayView;
954 typedef typename Array<GO>::size_type size_type;
956 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
957 const size_t numEntries = globalIDs.size ();
958 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid();
967 const int packetSize = computeLIDs ? 3 : 2;
973 Array<int> dirImages (numEntries);
974 res = directoryMap_->getRemoteIndexList (globalIDs, dirImages ());
976 size_t numMissing = 0;
978 for (
size_t i=0; i < numEntries; ++i) {
979 if (dirImages[i] == -1) {
982 localIDs[i] = LINVALID;
990 Array<int> sendImages;
991 distor.
createFromRecvs (globalIDs, dirImages (), sendGIDs, sendImages);
992 const size_type numSends = sendGIDs.size ();
1025 Array<global_size_t> exports (packetSize * numSends);
1038 size_type exportsIndex = 0;
1040 if (useHashTables_) {
1041 for (size_type gidIndex = 0; gidIndex < numSends; ++gidIndex) {
1042 const GO curGID = sendGIDs[gidIndex];
1044 exports[exportsIndex++] =
static_cast<global_size_t> (curGID);
1045 const LO curLID = directoryMap_->getLocalElement (curGID);
1046 TEUCHOS_TEST_FOR_EXCEPTION(curLID == LINVALID, std::logic_error,
1047 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): The Directory " 1048 "Map's global index " << curGID <<
" does not have a corresponding " 1049 "local index. Please report this bug to the Tpetra developers.");
1051 exports[exportsIndex++] =
static_cast<global_size_t> (lidToPidTable_->get (curLID));
1054 exports[exportsIndex++] =
static_cast<global_size_t> (lidToLidTable_->get (curLID));
1058 for (size_type gidIndex = 0; gidIndex < numSends; ++gidIndex) {
1059 const GO curGID = sendGIDs[gidIndex];
1061 exports[exportsIndex++] =
static_cast<global_size_t> (curGID);
1062 const LO curLID = directoryMap_->getLocalElement (curGID);
1063 TEUCHOS_TEST_FOR_EXCEPTION(curLID == LINVALID, std::logic_error,
1064 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): The Directory " 1065 "Map's global index " << curGID <<
" does not have a corresponding " 1066 "local index. Please report this bug to the Tpetra developers.");
1068 exports[exportsIndex++] =
static_cast<global_size_t> (PIDs_[curLID]);
1071 exports[exportsIndex++] =
static_cast<global_size_t> (LIDs_[curLID]);
1076 TEUCHOS_TEST_FOR_EXCEPTION(
1077 exportsIndex > exports.size (), std::logic_error,
1078 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): On Process " <<
1079 comm->getRank () <<
", exportsIndex = " << exportsIndex <<
1080 " > exports.size() = " << exports.size () <<
1081 ". Please report this bug to the Tpetra developers.");
1084 TEUCHOS_TEST_FOR_EXCEPTION(
1085 numEntries < numMissing, std::logic_error,
1086 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): On Process " 1087 << comm->getRank () <<
", numEntries = " << numEntries
1088 <<
" < numMissing = " << numMissing
1089 <<
". Please report this bug to the Tpetra developers.");
1095 const size_t numRecv = numEntries - numMissing;
1099 const size_t requiredImportLen = numRecv * packetSize;
1100 const int myRank = comm->getRank ();
1101 TEUCHOS_TEST_FOR_EXCEPTION(
1102 importLen < requiredImportLen, std::logic_error,
1103 "Tpetra::Details::DistributedNoncontiguousDirectory::getEntriesImpl: " 1104 "On Process " << myRank <<
": The 'imports' array must have length " 1105 "at least " << requiredImportLen <<
", but its actual length is " <<
1106 importLen <<
". numRecv: " << numRecv <<
", packetSize: " <<
1107 packetSize <<
", numEntries (# GIDs): " << numEntries <<
1108 ", numMissing: " << numMissing <<
": distor.getTotalReceiveLength(): " 1110 "Distributor description: " << distor.
description () <<
". " 1112 "Please report this bug to the Tpetra developers.");
1119 distor.
doPostsAndWaits (exports ().getConst (), packetSize, imports ());
1121 Array<GO> sortedIDs (globalIDs);
1122 Array<GO> offset (numEntries);
1123 for (GO ii = 0; ii < static_cast<GO> (numEntries); ++ii) {
1126 sort2 (sortedIDs.begin(), sortedIDs.begin() + numEntries, offset.begin());
1128 size_t importsIndex = 0;
1130 typedef typename Array<GO>::iterator IT;
1133 for (
size_t i = 0; i < numRecv; ++i) {
1135 const GO curGID =
static_cast<GO
> (imports[importsIndex++]);
1136 std::pair<IT, IT> p1 = std::equal_range (sortedIDs.begin(), sortedIDs.end(), curGID);
1137 if (p1.first != p1.second) {
1138 const size_t j = p1.first - sortedIDs.begin();
1140 nodeIDs[offset[j]] =
static_cast<int> (imports[importsIndex++]);
1143 localIDs[offset[j]] =
static_cast<LO
> (imports[importsIndex++]);
1145 if (nodeIDs[offset[j]] == -1) {
1151 TEUCHOS_TEST_FOR_EXCEPTION(
1152 static_cast<size_t> (importsIndex) > static_cast<size_t> (imports.size ()),
1154 "Tpetra::Details::DistributedNoncontiguousDirectory::getEntriesImpl: " 1155 "On Process " << comm->getRank () <<
": importsIndex = " <<
1156 importsIndex <<
" > imports.size() = " << imports.size () <<
". " 1157 "numRecv: " << numRecv <<
", packetSize: " << packetSize <<
", " 1158 "numEntries (# GIDs): " << numEntries <<
", numMissing: " << numMissing
1159 <<
": distor.getTotalReceiveLength(): " 1161 "the Tpetra developers.");
1167 template<
class LO,
class GO,
class NT>
1172 if (oneToOneResult_ == ONE_TO_ONE_NOT_CALLED_YET) {
1173 const int lcl121 = isLocallyOneToOne () ? 1 : 0;
1175 Teuchos::reduceAll<int, int> (comm, Teuchos::REDUCE_MIN, lcl121,
1176 Teuchos::outArg (gbl121));
1177 oneToOneResult_ = (gbl121 == 1) ? ONE_TO_ONE_TRUE : ONE_TO_ONE_FALSE;
1179 return (oneToOneResult_ == ONE_TO_ONE_TRUE);
1189 #define TPETRA_DIRECTORY_IMPL_INSTANT(LO,GO,NODE) \ 1190 template class Directory< LO , GO , NODE >; \ 1191 template class ReplicatedDirectory< LO , GO , NODE >; \ 1192 template class ContiguousUniformDirectory< LO, GO, NODE >; \ 1193 template class DistributedContiguousDirectory< LO , GO , NODE >; \ 1194 template class DistributedNoncontiguousDirectory< LO , GO , NODE >; \ 1196 #endif // __Tpetra_DirectoryImpl_def_hpp Interface for breaking ties in ownership.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
GlobalOrdinal getMinGlobalIndex() const
The minimum global index owned by the calling process.
Interface for breaking ties in ownership.
std::string description() const
A one-line human-readable description of this object.
std::string description() const
A simple one-line description of this object.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is owned by this Map on the calling process.
bool isContiguous() const
True if this Map is distributed contiguously, else false.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
LookupStatus getEntriesImpl(const map_type &map, const Teuchos::ArrayView< const GlobalOrdinal > &globalIDs, const Teuchos::ArrayView< int > &nodeIDs, const Teuchos::ArrayView< LocalOrdinal > &localIDs, const bool computeLIDs) const
Find process IDs and (optionally) local IDs for the given global IDs.
bool isUniform() const
Whether the range of global indices is uniform.
Implementation of Directory for a distributed noncontiguous Map.
bool isDistributed() const
Whether this Map is globally distributed or locally replicated.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Accessors for the Teuchos::Comm and Kokkos Node objects.
Implementation of Directory for a distributed contiguous Map.
GlobalOrdinal getMinAllGlobalIndex() const
The minimum global index over all processes in the communicator.
virtual bool isOneToOne(const Teuchos::Comm< int > &comm) const
Whether the Directory's input Map is (globally) one to one.
ReplicatedDirectory()
Constructor (that takes no arguments).
Implementation details of Tpetra.
GlobalOrdinal getMaxAllGlobalIndex() const
The maximum global index over all processes in the communicator.
virtual bool isOneToOne(const Teuchos::Comm< int > &comm) const
Whether the Directory's input Map is (globally) one to one.
size_t global_size_t
Global size_t object.
LookupStatus getEntriesImpl(const map_type &map, const Teuchos::ArrayView< const GlobalOrdinal > &globalIDs, const Teuchos::ArrayView< int > &nodeIDs, const Teuchos::ArrayView< LocalOrdinal > &localIDs, const bool computeLIDs) const
Find process IDs and (optionally) local IDs for the given global IDs.
void doPostsAndWaits(const ArrayView< const Packet > &exports, size_t numPackets, const ArrayView< Packet > &imports)
Execute the (forward) communication plan.
LookupStatus getEntries(const map_type &map, const Teuchos::ArrayView< const GlobalOrdinal > &globalIDs, const Teuchos::ArrayView< int > &nodeIDs, const Teuchos::ArrayView< LocalOrdinal > &localIDs, const bool computeLIDs) const
Sets up and executes a communication plan for a Tpetra DistObject.
size_t getTotalReceiveLength() const
Total number of values this process will receive from other processes.
Teuchos::RCP< Node > getNode() const
Get this Map's Node object.
std::string description() const
A one-line human-readable description of this object.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a view of the global indices owned by this process.
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2)
Sort the first array, and apply the resulting permutation to the second array.
size_t getNodeNumElements() const
The number of elements belonging to the calling process.
Describes a parallel distribution of objects over processes.
std::string description() const
A one-line human-readable description of this object.
Declaration of implementation details of Tpetra::Directory.
LookupStatus getEntriesImpl(const map_type &map, const Teuchos::ArrayView< const GlobalOrdinal > &globalIDs, const Teuchos::ArrayView< int > &nodeIDs, const Teuchos::ArrayView< LocalOrdinal > &localIDs, const bool computeLIDs) const
Find process IDs and (optionally) local IDs for the given global IDs.
void createFromRecvs(const ArrayView< const Ordinal > &remoteIDs, const ArrayView< const int > &remoteNodeIDs, Array< Ordinal > &exportIDs, Array< int > &exportNodeIDs)
Set up Distributor using list of process ranks from which to receive.
global_size_t getGlobalNumElements() const
The number of elements in this Map.