42 #ifndef __Tpetra_DirectoryImpl_def_hpp 43 #define __Tpetra_DirectoryImpl_def_hpp 45 #include <Tpetra_DirectoryImpl_decl.hpp> 46 #include <Tpetra_Distributor.hpp> 47 #include <Tpetra_Map.hpp> 50 #include <Tpetra_Details_FixedHashTable.hpp> 51 #include <Tpetra_HashTable.hpp> 53 #include <unordered_map> 64 template<
class LO,
class GO,
class NT>
68 template<
class LO,
class GO,
class NT>
72 const Teuchos::ArrayView<const GO> &globalIDs,
73 const Teuchos::ArrayView<int> &nodeIDs,
74 const Teuchos::ArrayView<LO> &localIDs,
75 const bool computeLIDs)
const 79 TEUCHOS_TEST_FOR_EXCEPTION(nodeIDs.size() != globalIDs.size(),
80 std::invalid_argument, Teuchos::typeName(*
this) <<
"::getEntries(): " 81 "Output arrays do not have the right sizes. nodeIDs.size() = " 82 << nodeIDs.size() <<
" != globalIDs.size() = " << globalIDs.size()
84 TEUCHOS_TEST_FOR_EXCEPTION(
85 computeLIDs && localIDs.size() != globalIDs.size(),
86 std::invalid_argument, Teuchos::typeName(*
this) <<
"::getEntries(): " 87 "Output array do not have the right sizes. localIDs.size() = " 88 << localIDs.size() <<
" != globalIDs.size() = " << globalIDs.size()
96 std::fill (nodeIDs.begin(), nodeIDs.end(), -1);
98 std::fill (localIDs.begin(), localIDs.end(),
99 Teuchos::OrdinalTraits<LO>::invalid ());
102 return this->getEntriesImpl (map, globalIDs, nodeIDs, localIDs, computeLIDs);
106 template<
class LO,
class GO,
class NT>
109 numProcs_ (map.getComm ()->getSize ())
113 template<
class LO,
class GO,
class NT>
120 template<
class LO,
class GO,
class NT>
128 return (numProcs_ == 1);
132 template<
class LO,
class GO,
class NT>
136 std::ostringstream os;
137 os <<
"ReplicatedDirectory" 138 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
139 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
140 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
145 template<
class LO,
class GO,
class NT>
149 TEUCHOS_TEST_FOR_EXCEPTION(! map.
isContiguous (), std::invalid_argument,
150 Teuchos::typeName (*
this) <<
" constructor: Map is not contiguous.");
151 TEUCHOS_TEST_FOR_EXCEPTION(! map.
isUniform (), std::invalid_argument,
152 Teuchos::typeName (*
this) <<
" constructor: Map is not uniform.");
156 template<
class LO,
class GO,
class NT>
160 std::ostringstream os;
161 os <<
"ContiguousUniformDirectory" 162 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
163 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
164 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
169 template<
class LO,
class GO,
class NT>
173 const Teuchos::ArrayView<const GO> &globalIDs,
174 const Teuchos::ArrayView<int> &nodeIDs,
175 const Teuchos::ArrayView<LO> &localIDs,
176 const bool computeLIDs)
const 180 typedef typename Teuchos::ArrayView<const GO>::size_type size_type;
181 const LO invalidLid = Teuchos::OrdinalTraits<LO>::invalid ();
184 RCP<const Comm<int> > comm = map.
getComm ();
208 const size_type N_G =
210 const size_type P =
static_cast<size_type
> (comm->getSize ());
211 const size_type N_L = N_G / P;
212 const size_type R = N_G - N_L * P;
213 const size_type N_R = R * (N_L +
static_cast<size_type
> (1));
215 #ifdef HAVE_TPETRA_DEBUG 216 TEUCHOS_TEST_FOR_EXCEPTION(
217 N_G != P*N_L + R, std::logic_error,
218 "Tpetra::ContiguousUniformDirectory::getEntriesImpl: " 219 "N_G = " << N_G <<
" != P*N_L + R = " << P <<
"*" << N_L <<
" + " << R
220 <<
" = " << P*N_L + R <<
". " 221 "Please report this bug to the Tpetra developers.");
222 #endif // HAVE_TPETRA_DEBUG 224 const size_type numGids = globalIDs.size ();
227 const GO ONE =
static_cast<GO
> (1);
230 for (size_type k = 0; k < numGids; ++k) {
231 const GO g_0 = globalIDs[k] - g_min;
237 if (g_0 + ONE < ONE || g_0 >= static_cast<GO> (N_G)) {
239 localIDs[k] = invalidLid;
242 else if (g_0 < static_cast<GO> (N_R)) {
244 nodeIDs[k] =
static_cast<int> (g_0 /
static_cast<GO
> (N_L + 1));
245 localIDs[k] =
static_cast<LO
> (g_0 %
static_cast<GO
> (N_L + 1));
247 else if (g_0 >= static_cast<GO> (N_R)) {
249 const GO g_R = g_0 -
static_cast<GO
> (N_R);
250 nodeIDs[k] =
static_cast<int> (R + g_R / N_L);
251 localIDs[k] =
static_cast<int> (g_R % N_L);
253 #ifdef HAVE_TPETRA_DEBUG 255 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
256 "Tpetra::ContiguousUniformDirectory::getEntriesImpl: " 257 "should never get here. " 258 "Please report this bug to the Tpetra developers.");
260 #endif // HAVE_TPETRA_DEBUG 264 for (size_type k = 0; k < numGids; ++k) {
265 const GO g_0 = globalIDs[k] - g_min;
270 if (g_0 + ONE < ONE || g_0 >= static_cast<GO> (N_G)) {
274 else if (g_0 < static_cast<GO> (N_R)) {
276 nodeIDs[k] =
static_cast<int> (g_0 /
static_cast<GO
> (N_L + 1));
278 else if (g_0 >= static_cast<GO> (N_R)) {
280 const GO g_R = g_0 -
static_cast<GO
> (N_R);
281 nodeIDs[k] =
static_cast<int> (R + g_R / N_L);
283 #ifdef HAVE_TPETRA_DEBUG 285 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
286 "Tpetra::ContiguousUniformDirectory::getEntriesImpl: " 287 "should never get here. " 288 "Please report this bug to the Tpetra developers.");
290 #endif // HAVE_TPETRA_DEBUG 296 template<
class LO,
class GO,
class NT>
300 using Teuchos::gatherAll;
303 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
305 TEUCHOS_TEST_FOR_EXCEPTION(! map.
isDistributed (), std::invalid_argument,
306 Teuchos::typeName (*
this) <<
" constructor: Map is not distributed.");
307 TEUCHOS_TEST_FOR_EXCEPTION(! map.
isContiguous (), std::invalid_argument,
308 Teuchos::typeName (*
this) <<
" constructor: Map is not contiguous.");
310 const int numProcs = comm->getSize ();
314 allMinGIDs_ = arcp<GO> (numProcs + 1);
328 MPI_Datatype rawMpiType = MPI_INT;
329 bool useRawMpi =
true;
330 if (
typeid (GO) ==
typeid (
int)) {
331 rawMpiType = MPI_INT;
332 }
else if (
typeid (GO) ==
typeid (
long)) {
333 rawMpiType = MPI_LONG;
338 using Teuchos::rcp_dynamic_cast;
339 using Teuchos::MpiComm;
340 RCP<const MpiComm<int> > mpiComm =
341 rcp_dynamic_cast<
const MpiComm<int> > (comm);
344 if (! comm.is_null ()) {
345 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
347 MPI_Allgather (&minMyGID, 1, rawMpiType,
348 allMinGIDs_.getRawPtr (), 1, rawMpiType,
350 TEUCHOS_TEST_FOR_EXCEPTION(err != MPI_SUCCESS, std::runtime_error,
351 "Tpetra::DistributedContiguousDirectory: MPI_Allgather failed");
353 gatherAll<int, GO> (*comm, 1, &minMyGID, numProcs, allMinGIDs_.getRawPtr ());
356 gatherAll<int, GO> (*comm, 1, &minMyGID, numProcs, allMinGIDs_.getRawPtr ());
358 #else // NOT HAVE_MPI 359 gatherAll<int, GO> (*comm, 1, &minMyGID, numProcs, allMinGIDs_.getRawPtr ());
368 + Teuchos::OrdinalTraits<GO>::one ();
371 template<
class LO,
class GO,
class NT>
375 std::ostringstream os;
376 os <<
"DistributedContiguousDirectory" 377 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
378 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
379 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
383 template<
class LO,
class GO,
class NT>
387 const Teuchos::ArrayView<const GO> &globalIDs,
388 const Teuchos::ArrayView<int> &nodeIDs,
389 const Teuchos::ArrayView<LO> &localIDs,
390 const bool computeLIDs)
const 392 using Teuchos::Array;
393 using Teuchos::ArrayRCP;
394 using Teuchos::ArrayView;
400 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
401 const int myRank = comm->getRank ();
404 typename ArrayView<int>::iterator procIter = nodeIDs.begin();
405 typename ArrayView<LO>::iterator lidIter = localIDs.begin();
406 typename ArrayView<const GO>::iterator gidIter;
407 for (gidIter = globalIDs.begin(); gidIter != globalIDs.end(); ++gidIter) {
409 *procIter++ = myRank;
426 template<
class LO,
class GO,
class NT>
430 const Teuchos::ArrayView<const GO> &globalIDs,
431 const Teuchos::ArrayView<int> &nodeIDs,
432 const Teuchos::ArrayView<LO> &localIDs,
433 const bool computeLIDs)
const 435 using Teuchos::Array;
436 using Teuchos::ArrayRCP;
437 using Teuchos::ArrayView;
442 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
443 const int numProcs = comm->getSize ();
445 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid();
449 typename ArrayView<int>::iterator procIter = nodeIDs.begin();
450 typename ArrayView<LO>::iterator lidIter = localIDs.begin();
451 typename ArrayView<const GO>::iterator gidIter;
452 for (gidIter = globalIDs.begin(); gidIter != globalIDs.end(); ++gidIter) {
462 const GO one = as<GO> (1);
463 const GO two = as<GO> (2);
464 const GO nOverP_GID = as<GO> (nOverP);
465 const GO lowerBound = GID / std::max(nOverP_GID, one) + two;
466 curRank = as<int>(std::min(lowerBound, as<GO>(numProcs - 1)));
469 while (curRank >= 0 && curRank < numProcs) {
470 if (allMinGIDs_[curRank] <= GID) {
471 if (GID < allMinGIDs_[curRank + 1]) {
485 LID = as<LO> (GID - allMinGIDs_[image]);
498 template<
class LO,
class GO,
class NT>
501 oneToOneResult_ (ONE_TO_ONE_NOT_CALLED_YET),
502 locallyOneToOne_ (true),
503 useHashTables_ (false)
505 initialize (map, Teuchos::null);
508 template<
class LO,
class GO,
class NT>
512 oneToOneResult_ (ONE_TO_ONE_NOT_CALLED_YET),
513 locallyOneToOne_ (true),
514 useHashTables_ (false)
516 initialize (map, Teuchos::ptrFromRef (tie_break));
519 template<
class LO,
class GO,
class NT>
523 Teuchos::Ptr<const tie_break_type> tie_break)
525 using Teuchos::Array;
526 using Teuchos::ArrayView;
530 using Teuchos::typeName;
531 using Teuchos::TypeNameTraits;
534 typedef Array<int>::size_type size_type;
544 TEUCHOS_TEST_FOR_EXCEPTION(
sizeof(
global_size_t) <
sizeof(GO),
545 std::logic_error, typeName (*
this) <<
": sizeof(Tpetra::" 546 "global_size_t) = " <<
sizeof(
global_size_t) <<
" < sizeof(Global" 547 "Ordinal = " << TypeNameTraits<LO>::name () <<
") = " <<
sizeof(GO)
549 TEUCHOS_TEST_FOR_EXCEPTION(
sizeof(
global_size_t) <
sizeof(
int),
550 std::logic_error, typeName (*
this) <<
": sizeof(Tpetra::" 551 "global_size_t) = " <<
sizeof(
global_size_t) <<
" < sizeof(int) = " 552 <<
sizeof(
int) <<
".");
553 TEUCHOS_TEST_FOR_EXCEPTION(
sizeof(
global_size_t) <
sizeof(LO),
554 std::logic_error, typeName (*
this) <<
": sizeof(Tpetra::" 555 "global_size_t) = " <<
sizeof(
global_size_t) <<
" < sizeof(Local" 556 "Ordinal = " << TypeNameTraits<LO>::name () <<
") = " <<
sizeof(LO)
559 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
560 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
569 const global_size_t numGlobalEntries = maxAllGID - minAllGID + 1;
579 directoryMap_ = rcp (
new map_type (numGlobalEntries, minAllGID, comm,
580 GloballyDistributed, map.
getNode ()));
582 const size_t dir_numMyEntries = directoryMap_->getNodeNumElements ();
606 const size_t inverseSparsityThreshold = 10;
613 const int myRank = comm->getRank ();
615 Array<int> sendImageIDs (numMyEntries);
621 directoryMap_->getRemoteIndexList (myGlobalEntries, sendImageIDs);
622 TEUCHOS_TEST_FOR_EXCEPTION(
623 lookupStatus ==
IDNotPresent, std::logic_error, Teuchos::typeName(*
this)
624 <<
" constructor: the Directory Map could not find out where one or " 625 "more of my Map's indices should go. The input to getRemoteIndexList " 626 "is " << Teuchos::toString (myGlobalEntries) <<
", and the output is " 627 << Teuchos::toString (sendImageIDs ()) <<
". The input Map itself has " 628 "the following entries on the calling process " <<
629 map.
getComm ()->getRank () <<
": " <<
633 <<
"]. The Directory Map has " 634 << directoryMap_->getGlobalNumElements () <<
" total global indices in " 635 "[" << directoryMap_->getMinAllGlobalIndex () <<
"," <<
636 directoryMap_->getMaxAllGlobalIndex () <<
"], and the calling process " 637 "has GIDs [" << directoryMap_->getMinGlobalIndex () <<
"," <<
638 directoryMap_->getMaxGlobalIndex () <<
"]. " 639 "This probably means there is a bug in Map or Directory. " 640 "Please report this bug to the Tpetra developers.");
648 const size_t numReceives = distor.createFromSends (sendImageIDs);
662 const int packetSize = 3;
663 Array<GO> exportEntries (packetSize * numMyEntries);
665 size_type exportIndex = 0;
666 for (size_type i = 0; i < static_cast<size_type> (numMyEntries); ++i) {
667 exportEntries[exportIndex++] = myGlobalEntries[i];
668 exportEntries[exportIndex++] = as<GO> (myRank);
669 exportEntries[exportIndex++] = as<GO> (i);
675 Array<GO> importElements (packetSize * distor.getTotalReceiveLength ());
678 distor.doPostsAndWaits (exportEntries ().getConst (), packetSize, importElements ());
685 if (useHashTables_) {
700 LO* tableKeysRaw = NULL;
701 LO* tableLidsRaw = NULL;
702 int* tablePidsRaw = NULL;
704 tableKeysRaw =
new LO [numReceives];
705 tableLidsRaw =
new LO [numReceives];
706 tablePidsRaw =
new int [numReceives];
708 if (tableKeysRaw != NULL) {
709 delete [] tableKeysRaw;
711 if (tableLidsRaw != NULL) {
712 delete [] tableLidsRaw;
714 if (tablePidsRaw != NULL) {
715 delete [] tablePidsRaw;
719 ArrayRCP<LO> tableKeys (tableKeysRaw, 0, numReceives,
true);
720 ArrayRCP<LO> tableLids (tableLidsRaw, 0, numReceives,
true);
721 ArrayRCP<int> tablePids (tablePidsRaw, 0, numReceives,
true);
723 if (tie_break.is_null ()) {
725 size_type importIndex = 0;
726 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
727 const GO curGID = importElements[importIndex++];
728 const LO curLID = directoryMap_->getLocalElement (curGID);
729 TEUCHOS_TEST_FOR_EXCEPTION(
730 curLID == LINVALID, std::logic_error,
731 Teuchos::typeName(*
this) <<
" constructor: Incoming global index " 732 << curGID <<
" does not have a corresponding local index in the " 733 "Directory Map. Please report this bug to the Tpetra developers.");
734 tableKeys[i] = curLID;
735 tablePids[i] = importElements[importIndex++];
736 tableLids[i] = importElements[importIndex++];
741 typedef Kokkos::Device<
typename NT::execution_space,
742 typename NT::memory_space> DT;
746 locallyOneToOne_ = ! (lidToPidTable_->hasDuplicateKeys ());
758 typedef std::map<LO, std::vector<std::pair<int, LO> > > pair_table_type;
759 pair_table_type ownedPidLidPairs;
763 size_type importIndex = 0;
764 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
765 const GO curGID = importElements[importIndex++];
766 const LO dirMapLid = directoryMap_->getLocalElement (curGID);
767 TEUCHOS_TEST_FOR_EXCEPTION(
768 dirMapLid == LINVALID, std::logic_error,
769 Teuchos::typeName(*
this) <<
" constructor: Incoming global index " 770 << curGID <<
" does not have a corresponding local index in the " 771 "Directory Map. Please report this bug to the Tpetra developers.");
772 tableKeys[i] = dirMapLid;
773 const int PID = importElements[importIndex++];
774 const int LID = importElements[importIndex++];
784 ownedPidLidPairs[dirMapLid].push_back (std::make_pair (PID, LID));
792 const size_type numPairs =
793 static_cast<size_type
> (ownedPidLidPairs.size ());
794 for (size_type i = 0; i < numPairs; ++i) {
795 const LO dirMapLid =
static_cast<LO
> (i);
796 const GO dirMapGid = directoryMap_->getGlobalElement (dirMapLid);
797 const std::vector<std::pair<int, LO> >& pidLidList =
799 const size_t listLen = pidLidList.size ();
802 locallyOneToOne_ =
false;
811 const size_type index =
812 static_cast<size_type
> (tie_break->selectedIndex (dirMapGid,
814 tablePids[i] = pidLidList[index].first;
815 tableLids[i] = pidLidList[index].second;
820 typedef Kokkos::Device<
typename NT::execution_space,
821 typename NT::memory_space> DT;
831 if (tie_break.is_null ()) {
836 PIDs_ = arcp<int> (dir_numMyEntries);
837 std::fill (PIDs_.begin (), PIDs_.end (), -1);
838 LIDs_ = arcp<LO> (dir_numMyEntries);
839 std::fill (LIDs_.begin (), LIDs_.end (), LINVALID);
841 size_type importIndex = 0;
842 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
843 const GO curGID = importElements[importIndex++];
844 const LO curLID = directoryMap_->getLocalElement (curGID);
845 TEUCHOS_TEST_FOR_EXCEPTION(curLID == LINVALID, std::logic_error,
846 Teuchos::typeName(*
this) <<
" constructor: Incoming global index " 847 << curGID <<
" does not have a corresponding local index in the " 848 "Directory Map. Please report this bug to the Tpetra developers.");
853 if (PIDs_[curLID] != -1) {
854 locallyOneToOne_ =
false;
856 PIDs_[curLID] = importElements[importIndex++];
857 LIDs_[curLID] = importElements[importIndex++];
861 PIDs_ = arcp<int> (dir_numMyEntries);
862 LIDs_ = arcp<LO> (dir_numMyEntries);
863 std::fill (PIDs_.begin (), PIDs_.end (), -1);
872 Array<std::vector<std::pair<int, LO> > > ownedPidLidPairs (dir_numMyEntries);
873 size_type importIndex = 0;
874 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
875 const GO GID = importElements[importIndex++];
876 const int PID = importElements[importIndex++];
877 const LO LID = importElements[importIndex++];
879 const LO dirMapLid = directoryMap_->getLocalElement (GID);
880 TEUCHOS_TEST_FOR_EXCEPTION(
881 dirMapLid == LINVALID, std::logic_error,
882 Teuchos::typeName(*
this) <<
" constructor: Incoming global index " 883 << GID <<
" does not have a corresponding local index in the " 884 "Directory Map. Please report this bug to the Tpetra developers.");
885 ownedPidLidPairs[dirMapLid].push_back (std::make_pair (PID, LID));
893 const size_type numPairs =
894 static_cast<size_type
> (ownedPidLidPairs.size ());
895 for (size_type i = 0; i < numPairs; ++i) {
896 const LO dirMapLid =
static_cast<LO
> (i);
897 const GO dirMapGid = directoryMap_->getGlobalElement (dirMapLid);
898 const std::vector<std::pair<int, LO> >& pidLidList =
900 const size_t listLen = pidLidList.size ();
903 locallyOneToOne_ =
false;
912 const size_type index =
913 static_cast<size_type
> (tie_break->selectedIndex (dirMapGid,
915 PIDs_[i] = pidLidList[index].first;
916 LIDs_[i] = pidLidList[index].second;
924 template<
class LO,
class GO,
class NT>
928 std::ostringstream os;
929 os <<
"DistributedNoncontiguousDirectory" 930 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
931 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
932 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
936 template<
class LO,
class GO,
class NT>
940 const Teuchos::ArrayView<const GO> &globalIDs,
941 const Teuchos::ArrayView<int> &nodeIDs,
942 const Teuchos::ArrayView<LO> &localIDs,
943 const bool computeLIDs)
const 945 using Teuchos::Array;
946 using Teuchos::ArrayRCP;
947 using Teuchos::ArrayView;
952 typedef typename Array<GO>::size_type size_type;
954 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
955 const size_t numEntries = globalIDs.size ();
956 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid();
965 const int packetSize = computeLIDs ? 3 : 2;
971 Array<int> dirImages (numEntries);
972 res = directoryMap_->getRemoteIndexList (globalIDs, dirImages ());
974 size_t numMissing = 0;
976 for (
size_t i=0; i < numEntries; ++i) {
977 if (dirImages[i] == -1) {
980 localIDs[i] = LINVALID;
988 Array<int> sendImages;
989 distor.
createFromRecvs (globalIDs, dirImages (), sendGIDs, sendImages);
990 const size_type numSends = sendGIDs.size ();
1023 Array<global_size_t> exports (packetSize * numSends);
1036 size_type exportsIndex = 0;
1038 if (useHashTables_) {
1039 for (size_type gidIndex = 0; gidIndex < numSends; ++gidIndex) {
1040 const GO curGID = sendGIDs[gidIndex];
1042 exports[exportsIndex++] =
static_cast<global_size_t> (curGID);
1043 const LO curLID = directoryMap_->getLocalElement (curGID);
1044 TEUCHOS_TEST_FOR_EXCEPTION(curLID == LINVALID, std::logic_error,
1045 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): The Directory " 1046 "Map's global index " << curGID <<
" does not have a corresponding " 1047 "local index. Please report this bug to the Tpetra developers.");
1049 exports[exportsIndex++] =
static_cast<global_size_t> (lidToPidTable_->get (curLID));
1052 exports[exportsIndex++] =
static_cast<global_size_t> (lidToLidTable_->get (curLID));
1056 for (size_type gidIndex = 0; gidIndex < numSends; ++gidIndex) {
1057 const GO curGID = sendGIDs[gidIndex];
1059 exports[exportsIndex++] =
static_cast<global_size_t> (curGID);
1060 const LO curLID = directoryMap_->getLocalElement (curGID);
1061 TEUCHOS_TEST_FOR_EXCEPTION(curLID == LINVALID, std::logic_error,
1062 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): The Directory " 1063 "Map's global index " << curGID <<
" does not have a corresponding " 1064 "local index. Please report this bug to the Tpetra developers.");
1066 exports[exportsIndex++] =
static_cast<global_size_t> (PIDs_[curLID]);
1069 exports[exportsIndex++] =
static_cast<global_size_t> (LIDs_[curLID]);
1074 TEUCHOS_TEST_FOR_EXCEPTION(
1075 exportsIndex > exports.size (), std::logic_error,
1076 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): On Process " <<
1077 comm->getRank () <<
", exportsIndex = " << exportsIndex <<
1078 " > exports.size() = " << exports.size () <<
1079 ". Please report this bug to the Tpetra developers.");
1082 TEUCHOS_TEST_FOR_EXCEPTION(
1083 numEntries < numMissing, std::logic_error,
1084 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): On Process " 1085 << comm->getRank () <<
", numEntries = " << numEntries
1086 <<
" < numMissing = " << numMissing
1087 <<
". Please report this bug to the Tpetra developers.");
1093 const size_t numRecv = numEntries - numMissing;
1097 const size_t requiredImportLen = numRecv * packetSize;
1098 const int myRank = comm->getRank ();
1099 TEUCHOS_TEST_FOR_EXCEPTION(
1100 importLen < requiredImportLen, std::logic_error,
1101 "Tpetra::Details::DistributedNoncontiguousDirectory::getEntriesImpl: " 1102 "On Process " << myRank <<
": The 'imports' array must have length " 1103 "at least " << requiredImportLen <<
", but its actual length is " <<
1104 importLen <<
". numRecv: " << numRecv <<
", packetSize: " <<
1105 packetSize <<
", numEntries (# GIDs): " << numEntries <<
1106 ", numMissing: " << numMissing <<
": distor.getTotalReceiveLength(): " 1108 "Distributor description: " << distor.
description () <<
". " 1110 "Please report this bug to the Tpetra developers.");
1119 distor.
doPostsAndWaits (exports ().getConst (), packetSize, imports ());
1129 std::unordered_map<GO, std::pair<int, LO> > received (numRecv);
1132 size_t importsIndex = 0;
1133 for (
size_t i = 0; i < numRecv; i++) {
1134 const GO curGID =
static_cast<GO
> (imports[importsIndex++]);
1135 const int curPID =
static_cast<int> (imports[importsIndex++]);
1136 std::pair<int, LO> curPair;
1138 const LO curLID =
static_cast<LO
> (imports[importsIndex++]);
1139 curPair = std::make_pair (curPID, curLID);
1142 curPair = std::make_pair (curPID, LINVALID);
1144 received[curGID] = curPair;
1148 for (
size_t i = 0; i < numEntries; ++i) {
1149 const GO curGID = globalIDs[i];
1151 auto tableIter = received.find (curGID);
1152 if (tableIter == received.end ()) {
1156 localIDs[i] = LINVALID;
1160 auto curPair = tableIter->second;
1161 nodeIDs[i] = curPair.first;
1162 if (nodeIDs[i] == -1) {
1165 localIDs[i] = LINVALID;
1168 else if (computeLIDs) {
1169 localIDs[i] = curPair.second;
1174 TEUCHOS_TEST_FOR_EXCEPTION(
1175 static_cast<size_t> (importsIndex) > static_cast<size_t> (imports.size ()),
1177 "Tpetra::Details::DistributedNoncontiguousDirectory::getEntriesImpl: " 1178 "On Process " << comm->getRank () <<
": importsIndex = " <<
1179 importsIndex <<
" > imports.size() = " << imports.size () <<
". " 1180 "numRecv: " << numRecv <<
", packetSize: " << packetSize <<
", " 1181 "numEntries (# GIDs): " << numEntries <<
", numMissing: " << numMissing
1182 <<
": distor.getTotalReceiveLength(): " 1184 "the Tpetra developers.");
1190 template<
class LO,
class GO,
class NT>
1195 if (oneToOneResult_ == ONE_TO_ONE_NOT_CALLED_YET) {
1196 const int lcl121 = isLocallyOneToOne () ? 1 : 0;
1198 Teuchos::reduceAll<int, int> (comm, Teuchos::REDUCE_MIN, lcl121,
1199 Teuchos::outArg (gbl121));
1200 oneToOneResult_ = (gbl121 == 1) ? ONE_TO_ONE_TRUE : ONE_TO_ONE_FALSE;
1202 return (oneToOneResult_ == ONE_TO_ONE_TRUE);
1212 #define TPETRA_DIRECTORY_IMPL_INSTANT(LO,GO,NODE) \ 1213 template class Directory< LO , GO , NODE >; \ 1214 template class ReplicatedDirectory< LO , GO , NODE >; \ 1215 template class ContiguousUniformDirectory< LO, GO, NODE >; \ 1216 template class DistributedContiguousDirectory< LO , GO , NODE >; \ 1217 template class DistributedNoncontiguousDirectory< LO , GO , NODE >; \ 1219 #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.
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.
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.