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>
303 using Teuchos::gatherAll;
306 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
308 TEUCHOS_TEST_FOR_EXCEPTION(! map.
isDistributed (), std::invalid_argument,
309 Teuchos::typeName (*
this) <<
" constructor: Map is not distributed.");
310 TEUCHOS_TEST_FOR_EXCEPTION(! map.
isContiguous (), std::invalid_argument,
311 Teuchos::typeName (*
this) <<
" constructor: Map is not contiguous.");
313 const int numProcs = comm->getSize ();
317 allMinGIDs_ = arcp<GO> (numProcs + 1);
331 MPI_Datatype rawMpiType = MPI_INT;
332 bool useRawMpi =
true;
333 if (
typeid (GO) ==
typeid (
int)) {
334 rawMpiType = MPI_INT;
335 }
else if (
typeid (GO) ==
typeid (
long)) {
336 rawMpiType = MPI_LONG;
341 using Teuchos::rcp_dynamic_cast;
342 using Teuchos::MpiComm;
343 RCP<const MpiComm<int> > mpiComm =
344 rcp_dynamic_cast<
const MpiComm<int> > (comm);
347 if (! comm.is_null ()) {
348 MPI_Comm rawMpiComm = * (mpiComm->getRawMpiComm ());
350 MPI_Allgather (&minMyGID, 1, rawMpiType,
351 allMinGIDs_.getRawPtr (), 1, rawMpiType,
353 TEUCHOS_TEST_FOR_EXCEPTION(err != MPI_SUCCESS, std::runtime_error,
354 "Tpetra::DistributedContiguousDirectory: MPI_Allgather failed");
356 gatherAll<int, GO> (*comm, 1, &minMyGID, numProcs, allMinGIDs_.getRawPtr ());
359 gatherAll<int, GO> (*comm, 1, &minMyGID, numProcs, allMinGIDs_.getRawPtr ());
361 #else // NOT HAVE_MPI 362 gatherAll<int, GO> (*comm, 1, &minMyGID, numProcs, allMinGIDs_.getRawPtr ());
371 + Teuchos::OrdinalTraits<GO>::one ();
374 template<
class LO,
class GO,
class NT>
378 std::ostringstream os;
379 os <<
"DistributedContiguousDirectory" 380 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
381 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
382 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
386 template<
class LO,
class GO,
class NT>
390 const Teuchos::ArrayView<const GO> &globalIDs,
391 const Teuchos::ArrayView<int> &nodeIDs,
392 const Teuchos::ArrayView<LO> &localIDs,
393 const bool computeLIDs)
const 395 using Teuchos::Array;
396 using Teuchos::ArrayRCP;
397 using Teuchos::ArrayView;
403 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
404 const int myRank = comm->getRank ();
407 typename ArrayView<int>::iterator procIter = nodeIDs.begin();
408 typename ArrayView<LO>::iterator lidIter = localIDs.begin();
409 typename ArrayView<const GO>::iterator gidIter;
410 for (gidIter = globalIDs.begin(); gidIter != globalIDs.end(); ++gidIter) {
412 *procIter++ = myRank;
429 template<
class LO,
class GO,
class NT>
433 const Teuchos::ArrayView<const GO> &globalIDs,
434 const Teuchos::ArrayView<int> &nodeIDs,
435 const Teuchos::ArrayView<LO> &localIDs,
436 const bool computeLIDs)
const 438 using Teuchos::Array;
439 using Teuchos::ArrayRCP;
440 using Teuchos::ArrayView;
445 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
446 const int numProcs = comm->getSize ();
448 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid();
452 typename ArrayView<int>::iterator procIter = nodeIDs.begin();
453 typename ArrayView<LO>::iterator lidIter = localIDs.begin();
454 typename ArrayView<const GO>::iterator gidIter;
455 for (gidIter = globalIDs.begin(); gidIter != globalIDs.end(); ++gidIter) {
465 const GO one = as<GO> (1);
466 const GO two = as<GO> (2);
467 const GO nOverP_GID = as<GO> (nOverP);
468 const GO lowerBound = GID / std::max(nOverP_GID, one) + two;
469 curRank = as<int>(std::min(lowerBound, as<GO>(numProcs - 1)));
472 while (curRank >= 0 && curRank < numProcs) {
473 if (allMinGIDs_[curRank] <= GID) {
474 if (GID < allMinGIDs_[curRank + 1]) {
488 LID = as<LO> (GID - allMinGIDs_[image]);
501 template<
class LO,
class GO,
class NT>
504 oneToOneResult_ (ONE_TO_ONE_NOT_CALLED_YET),
505 locallyOneToOne_ (true),
506 useHashTables_ (false)
508 initialize (map, Teuchos::null);
511 template<
class LO,
class GO,
class NT>
515 oneToOneResult_ (ONE_TO_ONE_NOT_CALLED_YET),
516 locallyOneToOne_ (true),
517 useHashTables_ (false)
519 initialize (map, Teuchos::ptrFromRef (tie_break));
522 template<
class LO,
class GO,
class NT>
526 Teuchos::Ptr<const tie_break_type> tie_break)
529 using Teuchos::Array;
530 using Teuchos::ArrayRCP;
531 using Teuchos::ArrayView;
535 using Teuchos::typeName;
536 using Teuchos::TypeNameTraits;
539 typedef Array<int>::size_type size_type;
549 TEUCHOS_TEST_FOR_EXCEPTION(
sizeof(
global_size_t) <
sizeof(GO),
550 std::logic_error, typeName (*
this) <<
": sizeof(Tpetra::" 551 "global_size_t) = " <<
sizeof(
global_size_t) <<
" < sizeof(Global" 552 "Ordinal = " << TypeNameTraits<LO>::name () <<
") = " <<
sizeof(GO)
554 TEUCHOS_TEST_FOR_EXCEPTION(
sizeof(
global_size_t) <
sizeof(
int),
555 std::logic_error, typeName (*
this) <<
": sizeof(Tpetra::" 556 "global_size_t) = " <<
sizeof(
global_size_t) <<
" < sizeof(int) = " 557 <<
sizeof(
int) <<
".");
558 TEUCHOS_TEST_FOR_EXCEPTION(
sizeof(
global_size_t) <
sizeof(LO),
559 std::logic_error, typeName (*
this) <<
": sizeof(Tpetra::" 560 "global_size_t) = " <<
sizeof(
global_size_t) <<
" < sizeof(Local" 561 "Ordinal = " << TypeNameTraits<LO>::name () <<
") = " <<
sizeof(LO)
564 RCP<const Teuchos::Comm<int> > comm = map.getComm ();
565 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
566 const GO minAllGID = map.getMinAllGlobalIndex ();
567 const GO maxAllGID = map.getMaxAllGlobalIndex ();
574 const global_size_t numGlobalEntries = maxAllGID - minAllGID + 1;
584 directoryMap_ = rcp (
new map_type (numGlobalEntries, minAllGID, comm,
585 GloballyDistributed, map.getNode ()));
587 const size_t dir_numMyEntries = directoryMap_->getNodeNumElements ();
611 const size_t inverseSparsityThreshold = 10;
613 dir_numMyEntries >= inverseSparsityThreshold * map.getNodeNumElements ();
618 const int myRank = comm->getRank ();
619 const size_t numMyEntries = map.getNodeNumElements ();
620 Array<int> sendImageIDs (numMyEntries);
621 ArrayView<const GO> myGlobalEntries = map.getNodeElementList ();
626 directoryMap_->getRemoteIndexList (myGlobalEntries, sendImageIDs);
627 TEUCHOS_TEST_FOR_EXCEPTION(
628 lookupStatus ==
IDNotPresent, std::logic_error, Teuchos::typeName(*
this)
629 <<
" constructor: the Directory Map could not find out where one or " 630 "more of my Map's indices should go. The input to getRemoteIndexList " 631 "is " << Teuchos::toString (myGlobalEntries) <<
", and the output is " 632 << Teuchos::toString (sendImageIDs ()) <<
". The input Map itself has " 633 "the following entries on the calling process " <<
634 map.getComm ()->getRank () <<
": " <<
635 Teuchos::toString (map.getNodeElementList ()) <<
", and has " 636 << map.getGlobalNumElements () <<
" total global indices in [" 637 << map.getMinAllGlobalIndex () <<
"," << map.getMaxAllGlobalIndex ()
638 <<
"]. The Directory Map has " 639 << directoryMap_->getGlobalNumElements () <<
" total global indices in " 640 "[" << directoryMap_->getMinAllGlobalIndex () <<
"," <<
641 directoryMap_->getMaxAllGlobalIndex () <<
"], and the calling process " 642 "has GIDs [" << directoryMap_->getMinGlobalIndex () <<
"," <<
643 directoryMap_->getMaxGlobalIndex () <<
"]. " 644 "This probably means there is a bug in Map or Directory. " 645 "Please report this bug to the Tpetra developers.");
653 const size_t numReceives = distor.createFromSends (sendImageIDs);
667 const int packetSize = 3;
668 Array<GO> exportEntries (packetSize * numMyEntries);
670 size_type exportIndex = 0;
671 for (size_type i = 0; i < static_cast<size_type> (numMyEntries); ++i) {
672 exportEntries[exportIndex++] = myGlobalEntries[i];
673 exportEntries[exportIndex++] = as<GO> (myRank);
674 exportEntries[exportIndex++] = as<GO> (i);
680 Array<GO> importElements (packetSize * distor.getTotalReceiveLength ());
683 distor.doPostsAndWaits (exportEntries ().getConst (), packetSize, importElements ());
690 if (useHashTables_) {
705 LO* tableKeysRaw = NULL;
706 LO* tableLidsRaw = NULL;
707 int* tablePidsRaw = NULL;
709 tableKeysRaw =
new LO [numReceives];
710 tableLidsRaw =
new LO [numReceives];
711 tablePidsRaw =
new int [numReceives];
713 if (tableKeysRaw != NULL) {
714 delete [] tableKeysRaw;
716 if (tableLidsRaw != NULL) {
717 delete [] tableLidsRaw;
719 if (tablePidsRaw != NULL) {
720 delete [] tablePidsRaw;
724 ArrayRCP<LO> tableKeys (tableKeysRaw, 0, numReceives,
true);
725 ArrayRCP<LO> tableLids (tableLidsRaw, 0, numReceives,
true);
726 ArrayRCP<int> tablePids (tablePidsRaw, 0, numReceives,
true);
728 if (tie_break.is_null ()) {
730 size_type importIndex = 0;
731 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
732 const GO curGID = importElements[importIndex++];
733 const LO curLID = directoryMap_->getLocalElement (curGID);
734 TEUCHOS_TEST_FOR_EXCEPTION(
735 curLID == LINVALID, std::logic_error,
736 Teuchos::typeName(*
this) <<
" constructor: Incoming global index " 737 << curGID <<
" does not have a corresponding local index in the " 738 "Directory Map. Please report this bug to the Tpetra developers.");
739 tableKeys[i] = curLID;
740 tablePids[i] = importElements[importIndex++];
741 tableLids[i] = importElements[importIndex++];
746 typedef Kokkos::Device<
typename NT::execution_space,
747 typename NT::memory_space> DT;
749 rcp (
new Details::FixedHashTable<LO, int, DT> (tableKeys (),
751 locallyOneToOne_ = ! (lidToPidTable_->hasDuplicateKeys ());
753 rcp (
new Details::FixedHashTable<LO, LO, DT> (tableKeys (),
763 typedef std::map<LO, std::vector<std::pair<int, LO> > > pair_table_type;
764 pair_table_type ownedPidLidPairs;
768 size_type importIndex = 0;
769 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
770 const GO curGID = importElements[importIndex++];
771 const LO dirMapLid = directoryMap_->getLocalElement (curGID);
772 TEUCHOS_TEST_FOR_EXCEPTION(
773 dirMapLid == LINVALID, std::logic_error,
774 Teuchos::typeName(*
this) <<
" constructor: Incoming global index " 775 << curGID <<
" does not have a corresponding local index in the " 776 "Directory Map. Please report this bug to the Tpetra developers.");
777 tableKeys[i] = dirMapLid;
778 const int PID = importElements[importIndex++];
779 const int LID = importElements[importIndex++];
789 ownedPidLidPairs[dirMapLid].push_back (std::make_pair (PID, LID));
797 const size_type numPairs =
798 static_cast<size_type
> (ownedPidLidPairs.size ());
799 for (size_type i = 0; i < numPairs; ++i) {
800 const LO dirMapLid =
static_cast<LO
> (i);
801 const GO dirMapGid = directoryMap_->getGlobalElement (dirMapLid);
802 const std::vector<std::pair<int, LO> >& pidLidList =
804 const size_t listLen = pidLidList.size ();
807 locallyOneToOne_ =
false;
816 const size_type index =
817 static_cast<size_type
> (tie_break->selectedIndex (dirMapGid,
819 tablePids[i] = pidLidList[index].first;
820 tableLids[i] = pidLidList[index].second;
825 typedef Kokkos::Device<
typename NT::execution_space,
826 typename NT::memory_space> DT;
828 rcp (
new Details::FixedHashTable<LO, int, DT> (tableKeys (),
831 rcp (
new Details::FixedHashTable<LO, LO, DT> (tableKeys (),
836 if (tie_break.is_null ()) {
841 PIDs_ = arcp<int> (dir_numMyEntries);
842 std::fill (PIDs_.begin (), PIDs_.end (), -1);
843 LIDs_ = arcp<LO> (dir_numMyEntries);
844 std::fill (LIDs_.begin (), LIDs_.end (), LINVALID);
846 size_type importIndex = 0;
847 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
848 const GO curGID = importElements[importIndex++];
849 const LO curLID = directoryMap_->getLocalElement (curGID);
850 TEUCHOS_TEST_FOR_EXCEPTION(curLID == LINVALID, std::logic_error,
851 Teuchos::typeName(*
this) <<
" constructor: Incoming global index " 852 << curGID <<
" does not have a corresponding local index in the " 853 "Directory Map. Please report this bug to the Tpetra developers.");
858 if (PIDs_[curLID] != -1) {
859 locallyOneToOne_ =
false;
861 PIDs_[curLID] = importElements[importIndex++];
862 LIDs_[curLID] = importElements[importIndex++];
866 PIDs_ = arcp<int> (dir_numMyEntries);
867 LIDs_ = arcp<LO> (dir_numMyEntries);
868 std::fill (PIDs_.begin (), PIDs_.end (), -1);
877 Array<std::vector<std::pair<int, LO> > > ownedPidLidPairs (dir_numMyEntries);
878 size_type importIndex = 0;
879 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
880 const GO GID = importElements[importIndex++];
881 const int PID = importElements[importIndex++];
882 const LO LID = importElements[importIndex++];
884 const LO dirMapLid = directoryMap_->getLocalElement (GID);
885 TEUCHOS_TEST_FOR_EXCEPTION(
886 dirMapLid == LINVALID, std::logic_error,
887 Teuchos::typeName(*
this) <<
" constructor: Incoming global index " 888 << GID <<
" does not have a corresponding local index in the " 889 "Directory Map. Please report this bug to the Tpetra developers.");
890 ownedPidLidPairs[dirMapLid].push_back (std::make_pair (PID, LID));
898 const size_type numPairs =
899 static_cast<size_type
> (ownedPidLidPairs.size ());
900 for (size_type i = 0; i < numPairs; ++i) {
901 const LO dirMapLid =
static_cast<LO
> (i);
902 const GO dirMapGid = directoryMap_->getGlobalElement (dirMapLid);
903 const std::vector<std::pair<int, LO> >& pidLidList =
905 const size_t listLen = pidLidList.size ();
908 locallyOneToOne_ =
false;
917 const size_type index =
918 static_cast<size_type
> (tie_break->selectedIndex (dirMapGid,
920 PIDs_[i] = pidLidList[index].first;
921 LIDs_[i] = pidLidList[index].second;
929 template<
class LO,
class GO,
class NT>
933 std::ostringstream os;
934 os <<
"DistributedNoncontiguousDirectory" 935 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
936 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
937 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
941 template<
class LO,
class GO,
class NT>
945 const Teuchos::ArrayView<const GO> &globalIDs,
946 const Teuchos::ArrayView<int> &nodeIDs,
947 const Teuchos::ArrayView<LO> &localIDs,
948 const bool computeLIDs)
const 950 using Teuchos::Array;
951 using Teuchos::ArrayRCP;
952 using Teuchos::ArrayView;
957 typedef typename Array<GO>::size_type size_type;
959 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
960 const size_t numEntries = globalIDs.size ();
961 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid();
970 const int packetSize = computeLIDs ? 3 : 2;
976 Array<int> dirImages (numEntries);
977 res = directoryMap_->getRemoteIndexList (globalIDs, dirImages ());
979 size_t numMissing = 0;
981 for (
size_t i=0; i < numEntries; ++i) {
982 if (dirImages[i] == -1) {
985 localIDs[i] = LINVALID;
993 Array<int> sendImages;
994 distor.
createFromRecvs (globalIDs, dirImages (), sendGIDs, sendImages);
995 const size_type numSends = sendGIDs.size ();
1028 Array<global_size_t> exports (packetSize * numSends);
1041 size_type exportsIndex = 0;
1043 if (useHashTables_) {
1044 for (size_type gidIndex = 0; gidIndex < numSends; ++gidIndex) {
1045 const GO curGID = sendGIDs[gidIndex];
1047 exports[exportsIndex++] =
static_cast<global_size_t> (curGID);
1048 const LO curLID = directoryMap_->getLocalElement (curGID);
1049 TEUCHOS_TEST_FOR_EXCEPTION(curLID == LINVALID, std::logic_error,
1050 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): The Directory " 1051 "Map's global index " << curGID <<
" does not have a corresponding " 1052 "local index. Please report this bug to the Tpetra developers.");
1054 exports[exportsIndex++] =
static_cast<global_size_t> (lidToPidTable_->get (curLID));
1057 exports[exportsIndex++] =
static_cast<global_size_t> (lidToLidTable_->get (curLID));
1061 for (size_type gidIndex = 0; gidIndex < numSends; ++gidIndex) {
1062 const GO curGID = sendGIDs[gidIndex];
1064 exports[exportsIndex++] =
static_cast<global_size_t> (curGID);
1065 const LO curLID = directoryMap_->getLocalElement (curGID);
1066 TEUCHOS_TEST_FOR_EXCEPTION(curLID == LINVALID, std::logic_error,
1067 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): The Directory " 1068 "Map's global index " << curGID <<
" does not have a corresponding " 1069 "local index. Please report this bug to the Tpetra developers.");
1071 exports[exportsIndex++] =
static_cast<global_size_t> (PIDs_[curLID]);
1074 exports[exportsIndex++] =
static_cast<global_size_t> (LIDs_[curLID]);
1079 TEUCHOS_TEST_FOR_EXCEPTION(
1080 exportsIndex > exports.size (), std::logic_error,
1081 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): On Process " <<
1082 comm->getRank () <<
", exportsIndex = " << exportsIndex <<
1083 " > exports.size() = " << exports.size () <<
1084 ". Please report this bug to the Tpetra developers.");
1087 TEUCHOS_TEST_FOR_EXCEPTION(
1088 numEntries < numMissing, std::logic_error,
1089 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): On Process " 1090 << comm->getRank () <<
", numEntries = " << numEntries
1091 <<
" < numMissing = " << numMissing
1092 <<
". Please report this bug to the Tpetra developers.");
1098 const size_t numRecv = numEntries - numMissing;
1102 const size_t requiredImportLen = numRecv * packetSize;
1103 const int myRank = comm->getRank ();
1104 TEUCHOS_TEST_FOR_EXCEPTION(
1105 importLen < requiredImportLen, std::logic_error,
1106 "Tpetra::Details::DistributedNoncontiguousDirectory::getEntriesImpl: " 1107 "On Process " << myRank <<
": The 'imports' array must have length " 1108 "at least " << requiredImportLen <<
", but its actual length is " <<
1109 importLen <<
". numRecv: " << numRecv <<
", packetSize: " <<
1110 packetSize <<
", numEntries (# GIDs): " << numEntries <<
1111 ", numMissing: " << numMissing <<
": distor.getTotalReceiveLength(): " 1113 "Distributor description: " << distor.
description () <<
". " 1115 "Please report this bug to the Tpetra developers.");
1122 distor.
doPostsAndWaits (exports ().getConst (), packetSize, imports ());
1124 Array<GO> sortedIDs (globalIDs);
1125 Array<GO> offset (numEntries);
1126 for (GO ii = 0; ii < static_cast<GO> (numEntries); ++ii) {
1129 sort2 (sortedIDs.begin(), sortedIDs.begin() + numEntries, offset.begin());
1131 size_t importsIndex = 0;
1133 typedef typename Array<GO>::iterator IT;
1136 for (
size_t i = 0; i < numRecv; ++i) {
1138 const GO curGID =
static_cast<GO
> (imports[importsIndex++]);
1139 std::pair<IT, IT> p1 = std::equal_range (sortedIDs.begin(), sortedIDs.end(), curGID);
1140 if (p1.first != p1.second) {
1141 const size_t j = p1.first - sortedIDs.begin();
1143 nodeIDs[offset[j]] =
static_cast<int> (imports[importsIndex++]);
1146 localIDs[offset[j]] =
static_cast<LO
> (imports[importsIndex++]);
1148 if (nodeIDs[offset[j]] == -1) {
1154 TEUCHOS_TEST_FOR_EXCEPTION(
1155 static_cast<size_t> (importsIndex) > static_cast<size_t> (imports.size ()),
1157 "Tpetra::Details::DistributedNoncontiguousDirectory::getEntriesImpl: " 1158 "On Process " << comm->getRank () <<
": importsIndex = " <<
1159 importsIndex <<
" > imports.size() = " << imports.size () <<
". " 1160 "numRecv: " << numRecv <<
", packetSize: " << packetSize <<
", " 1161 "numEntries (# GIDs): " << numEntries <<
", numMissing: " << numMissing
1162 <<
": distor.getTotalReceiveLength(): " 1164 "the Tpetra developers.");
1170 template<
class LO,
class GO,
class NT>
1175 if (oneToOneResult_ == ONE_TO_ONE_NOT_CALLED_YET) {
1176 const int lcl121 = isLocallyOneToOne () ? 1 : 0;
1178 Teuchos::reduceAll<int, int> (comm, Teuchos::REDUCE_MIN, lcl121,
1179 Teuchos::outArg (gbl121));
1180 oneToOneResult_ = (gbl121 == 1) ? ONE_TO_ONE_TRUE : ONE_TO_ONE_FALSE;
1182 return (oneToOneResult_ == ONE_TO_ONE_TRUE);
1192 #define TPETRA_DIRECTORY_IMPL_INSTANT(LO,GO,NODE) \ 1193 template class Directory< LO , GO , NODE >; \ 1194 template class ReplicatedDirectory< LO , GO , NODE >; \ 1195 template class ContiguousUniformDirectory< LO, GO, NODE >; \ 1196 template class DistributedContiguousDirectory< LO , GO , NODE >; \ 1197 template class DistributedNoncontiguousDirectory< LO , GO , NODE >; \ 1199 #endif // __Tpetra_DirectoryImpl_def_hpp Interface for breaking ties in ownership.
void doPostsAndWaits(const Teuchos::ArrayView< const Packet > &exports, size_t numPackets, const Teuchos::ArrayView< Packet > &imports)
Execute the (forward) communication plan.
GlobalOrdinal getMaxAllGlobalIndex() const
The maximum global index over all processes in the communicator.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
std::string description() const
A one-line human-readable description of this object.
GlobalOrdinal getMinAllGlobalIndex() const
The minimum global index over all processes in the communicator.
Interface for breaking ties in ownership.
bool isNodeGlobalElement(GlobalOrdinal globalIndex) const
Whether the given global index is owned by this Map on the calling process.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
size_t getTotalReceiveLength() const
Total number of values this process will receive from other processes.
bool isContiguous() const
True if this Map is distributed contiguously, else false.
Implementation of Directory for a distributed noncontiguous Map.
Implementation of Directory for a distributed contiguous Map.
global_size_t getGlobalNumElements() const
The number of elements in this Map.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
ReplicatedDirectory()
Constructor (that takes no arguments).
Implementation details of Tpetra.
size_t global_size_t
Global size_t object.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Accessors for the Teuchos::Comm and Kokkos Node objects.
bool isDistributed() const
Whether this Map is globally distributed or locally replicated.
std::string description() const
A one-line human-readable description of this object.
Sets up and executes a communication plan for a Tpetra DistObject.
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.
std::string description() const
A one-line human-readable description of this object.
GlobalOrdinal getMinGlobalIndex() const
The minimum global index owned by the calling 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.
Describes a parallel distribution of objects over processes.
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.
virtual bool isOneToOne(const Teuchos::Comm< int > &comm) const
Whether the Directory's input Map is (globally) one to one.
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.
std::string description() const
Return a one-line description of this object.
virtual bool isOneToOne(const Teuchos::Comm< int > &comm) const
Whether the Directory's input Map is (globally) one to one.
Declaration of implementation details of Tpetra::Directory.
bool isUniform() const
Whether the range of global indices is uniform.
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
void createFromRecvs(const Teuchos::ArrayView< const Ordinal > &remoteIDs, const Teuchos::ArrayView< const int > &remoteProcIDs, Teuchos::Array< Ordinal > &exportIDs, Teuchos::Array< int > &exportProcIDs)
Set up Distributor using list of process ranks from which to receive.