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>
55 #include "Teuchos_Comm.hpp"
58 #ifdef HAVE_TPETRACORE_MPI
60 #endif // HAVE_TPETRACORE_MPI
65 template<
class LO,
class GO,
class NT>
69 template<
class LO,
class GO,
class NT>
73 const Teuchos::ArrayView<const GO> &globalIDs,
74 const Teuchos::ArrayView<int> &nodeIDs,
75 const Teuchos::ArrayView<LO> &localIDs,
76 const bool computeLIDs)
const
80 TEUCHOS_TEST_FOR_EXCEPTION(nodeIDs.size() != globalIDs.size(),
81 std::invalid_argument, Teuchos::typeName(*
this) <<
"::getEntries(): "
82 "Output arrays do not have the right sizes. nodeIDs.size() = "
83 << nodeIDs.size() <<
" != globalIDs.size() = " << globalIDs.size()
85 TEUCHOS_TEST_FOR_EXCEPTION(
86 computeLIDs && localIDs.size() != globalIDs.size(),
87 std::invalid_argument, Teuchos::typeName(*
this) <<
"::getEntries(): "
88 "Output array do not have the right sizes. localIDs.size() = "
89 << localIDs.size() <<
" != globalIDs.size() = " << globalIDs.size()
97 std::fill (nodeIDs.begin(), nodeIDs.end(), -1);
99 std::fill (localIDs.begin(), localIDs.end(),
100 Teuchos::OrdinalTraits<LO>::invalid ());
103 return this->getEntriesImpl (map, globalIDs, nodeIDs, localIDs, computeLIDs);
107 template<
class LO,
class GO,
class NT>
110 numProcs_ (map.getComm ()->getSize ())
114 template<
class LO,
class GO,
class NT>
121 template<
class LO,
class GO,
class NT>
129 return (numProcs_ == 1);
133 template<
class LO,
class GO,
class NT>
137 std::ostringstream os;
138 os <<
"ReplicatedDirectory"
139 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
140 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
141 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
146 template<
class LO,
class GO,
class NT>
150 TEUCHOS_TEST_FOR_EXCEPTION(! map.
isContiguous (), std::invalid_argument,
151 Teuchos::typeName (*
this) <<
" constructor: Map is not contiguous.");
152 TEUCHOS_TEST_FOR_EXCEPTION(! map.
isUniform (), std::invalid_argument,
153 Teuchos::typeName (*
this) <<
" constructor: Map is not uniform.");
157 template<
class LO,
class GO,
class NT>
161 std::ostringstream os;
162 os <<
"ContiguousUniformDirectory"
163 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
164 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
165 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
170 template<
class LO,
class GO,
class NT>
174 const Teuchos::ArrayView<const GO> &globalIDs,
175 const Teuchos::ArrayView<int> &nodeIDs,
176 const Teuchos::ArrayView<LO> &localIDs,
177 const bool computeLIDs)
const
181 typedef typename Teuchos::ArrayView<const GO>::size_type size_type;
182 const LO invalidLid = Teuchos::OrdinalTraits<LO>::invalid ();
185 RCP<const Comm<int> > comm = map.
getComm ();
209 const size_type N_G =
211 const size_type P =
static_cast<size_type
> (comm->getSize ());
212 const size_type N_L = N_G / P;
213 const size_type R = N_G - N_L * P;
214 const size_type N_R = R * (N_L +
static_cast<size_type
> (1));
216 #ifdef HAVE_TPETRA_DEBUG
217 TEUCHOS_TEST_FOR_EXCEPTION(
218 N_G != P*N_L + R, std::logic_error,
219 "Tpetra::ContiguousUniformDirectory::getEntriesImpl: "
220 "N_G = " << N_G <<
" != P*N_L + R = " << P <<
"*" << N_L <<
" + " << R
221 <<
" = " << P*N_L + R <<
". "
222 "Please report this bug to the Tpetra developers.");
223 #endif // HAVE_TPETRA_DEBUG
225 const size_type numGids = globalIDs.size ();
228 const GO ONE =
static_cast<GO
> (1);
231 for (size_type k = 0; k < numGids; ++k) {
232 const GO g_0 = globalIDs[k] - g_min;
238 if (g_0 + ONE < ONE || g_0 >= static_cast<GO> (N_G)) {
240 localIDs[k] = invalidLid;
243 else if (g_0 < static_cast<GO> (N_R)) {
245 nodeIDs[k] =
static_cast<int> (g_0 /
static_cast<GO
> (N_L + 1));
246 localIDs[k] =
static_cast<LO
> (g_0 %
static_cast<GO
> (N_L + 1));
248 else if (g_0 >= static_cast<GO> (N_R)) {
250 const GO g_R = g_0 -
static_cast<GO
> (N_R);
251 nodeIDs[k] =
static_cast<int> (R + g_R / N_L);
252 localIDs[k] =
static_cast<int> (g_R % N_L);
254 #ifdef HAVE_TPETRA_DEBUG
256 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
257 "Tpetra::ContiguousUniformDirectory::getEntriesImpl: "
258 "should never get here. "
259 "Please report this bug to the Tpetra developers.");
261 #endif // HAVE_TPETRA_DEBUG
265 for (size_type k = 0; k < numGids; ++k) {
266 const GO g_0 = globalIDs[k] - g_min;
271 if (g_0 + ONE < ONE || g_0 >= static_cast<GO> (N_G)) {
275 else if (g_0 < static_cast<GO> (N_R)) {
277 nodeIDs[k] =
static_cast<int> (g_0 /
static_cast<GO
> (N_L + 1));
279 else if (g_0 >= static_cast<GO> (N_R)) {
281 const GO g_R = g_0 -
static_cast<GO
> (N_R);
282 nodeIDs[k] =
static_cast<int> (R + g_R / N_L);
284 #ifdef HAVE_TPETRA_DEBUG
286 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
287 "Tpetra::ContiguousUniformDirectory::getEntriesImpl: "
288 "should never get here. "
289 "Please report this bug to the Tpetra developers.");
291 #endif // HAVE_TPETRA_DEBUG
297 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);
329 #ifdef HAVE_TPETRACORE_MPI
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_TPETRACORE_MPI
361 gatherAll<int, GO> (*comm, 1, &minMyGID, numProcs, allMinGIDs_.getRawPtr ());
362 #endif // HAVE_TPETRACORE_MPI
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)
528 using Teuchos::Array;
529 using Teuchos::ArrayRCP;
530 using Teuchos::ArrayView;
534 using Teuchos::typeName;
535 using Teuchos::TypeNameTraits;
538 typedef Array<int>::size_type size_type;
548 TEUCHOS_TEST_FOR_EXCEPTION(
sizeof(
global_size_t) <
sizeof(GO),
549 std::logic_error, typeName (*
this) <<
": sizeof(Tpetra::"
550 "global_size_t) = " <<
sizeof(
global_size_t) <<
" < sizeof(Global"
551 "Ordinal = " << TypeNameTraits<LO>::name () <<
") = " <<
sizeof(GO)
553 TEUCHOS_TEST_FOR_EXCEPTION(
sizeof(
global_size_t) <
sizeof(
int),
554 std::logic_error, typeName (*
this) <<
": sizeof(Tpetra::"
555 "global_size_t) = " <<
sizeof(
global_size_t) <<
" < sizeof(int) = "
556 <<
sizeof(
int) <<
".");
557 TEUCHOS_TEST_FOR_EXCEPTION(
sizeof(
global_size_t) <
sizeof(LO),
558 std::logic_error, typeName (*
this) <<
": sizeof(Tpetra::"
559 "global_size_t) = " <<
sizeof(
global_size_t) <<
" < sizeof(Local"
560 "Ordinal = " << TypeNameTraits<LO>::name () <<
") = " <<
sizeof(LO)
563 RCP<const Teuchos::Comm<int> > comm = map.getComm ();
564 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
565 const GO minAllGID = map.getMinAllGlobalIndex ();
566 const GO maxAllGID = map.getMaxAllGlobalIndex ();
573 const global_size_t numGlobalEntries = maxAllGID - minAllGID + 1;
583 directoryMap_ = rcp (
new map_type (numGlobalEntries, minAllGID, comm,
584 GloballyDistributed));
586 const size_t dir_numMyEntries = directoryMap_->getNodeNumElements ();
610 const size_t inverseSparsityThreshold = 10;
612 (dir_numMyEntries >= inverseSparsityThreshold * map.getNodeNumElements());
617 const int myRank = comm->getRank ();
618 const size_t numMyEntries = map.getNodeNumElements ();
619 Array<int> sendImageIDs (numMyEntries);
620 ArrayView<const GO> myGlobalEntries = map.getNodeElementList ();
625 directoryMap_->getRemoteIndexList (myGlobalEntries, sendImageIDs);
626 TEUCHOS_TEST_FOR_EXCEPTION(
627 lookupStatus ==
IDNotPresent, std::logic_error, Teuchos::typeName(*
this)
628 <<
" constructor: the Directory Map could not find out where one or "
629 "more of my Map's indices should go. The input to getRemoteIndexList "
630 "is " << Teuchos::toString (myGlobalEntries) <<
", and the output is "
631 << Teuchos::toString (sendImageIDs ()) <<
". The input Map itself has "
632 "the following entries on the calling process " <<
633 map.getComm ()->getRank () <<
": " <<
634 Teuchos::toString (map.getNodeElementList ()) <<
", and has "
635 << map.getGlobalNumElements () <<
" total global indices in ["
636 << map.getMinAllGlobalIndex () <<
"," << map.getMaxAllGlobalIndex ()
637 <<
"]. The Directory Map has "
638 << directoryMap_->getGlobalNumElements () <<
" total global indices in "
639 "[" << directoryMap_->getMinAllGlobalIndex () <<
"," <<
640 directoryMap_->getMaxAllGlobalIndex () <<
"], and the calling process "
641 "has GIDs [" << directoryMap_->getMinGlobalIndex () <<
"," <<
642 directoryMap_->getMaxGlobalIndex () <<
"]. "
643 "This probably means there is a bug in Map or Directory. "
644 "Please report this bug to the Tpetra developers.");
652 const size_t numReceives = distor.createFromSends (sendImageIDs);
666 const int packetSize = 3;
667 Array<GO> exportEntries (packetSize * numMyEntries);
669 size_type exportIndex = 0;
670 for (size_type i = 0; i < static_cast<size_type> (numMyEntries); ++i) {
671 exportEntries[exportIndex++] = myGlobalEntries[i];
672 exportEntries[exportIndex++] = as<GO> (myRank);
673 exportEntries[exportIndex++] = as<GO> (i);
679 Array<GO> importElements (packetSize * distor.getTotalReceiveLength ());
682 distor.doPostsAndWaits (exportEntries ().getConst (), packetSize, importElements ());
689 if (useHashTables_) {
704 LO* tableKeysRaw = NULL;
705 LO* tableLidsRaw = NULL;
706 int* tablePidsRaw = NULL;
708 tableKeysRaw =
new LO [numReceives];
709 tableLidsRaw =
new LO [numReceives];
710 tablePidsRaw =
new int [numReceives];
712 if (tableKeysRaw != NULL) {
713 delete [] tableKeysRaw;
715 if (tableLidsRaw != NULL) {
716 delete [] tableLidsRaw;
718 if (tablePidsRaw != NULL) {
719 delete [] tablePidsRaw;
723 ArrayRCP<LO> tableKeys (tableKeysRaw, 0, numReceives,
true);
724 ArrayRCP<LO> tableLids (tableLidsRaw, 0, numReceives,
true);
725 ArrayRCP<int> tablePids (tablePidsRaw, 0, numReceives,
true);
727 if (tie_break.is_null ()) {
729 size_type importIndex = 0;
730 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
731 const GO curGID = importElements[importIndex++];
732 const LO curLID = directoryMap_->getLocalElement (curGID);
733 TEUCHOS_TEST_FOR_EXCEPTION(
734 curLID == LINVALID, std::logic_error,
735 Teuchos::typeName(*
this) <<
" constructor: Incoming global index "
736 << curGID <<
" does not have a corresponding local index in the "
737 "Directory Map. Please report this bug to the Tpetra developers.");
738 tableKeys[i] = curLID;
739 tablePids[i] = importElements[importIndex++];
740 tableLids[i] = importElements[importIndex++];
745 typedef Kokkos::Device<
typename NT::execution_space,
746 typename NT::memory_space> DT;
748 rcp (
new Details::FixedHashTable<LO, int, DT> (tableKeys (),
750 locallyOneToOne_ = ! (lidToPidTable_->hasDuplicateKeys ());
752 rcp (
new Details::FixedHashTable<LO, LO, DT> (tableKeys (),
762 typedef std::map<LO, std::vector<std::pair<int, LO> > > pair_table_type;
763 pair_table_type ownedPidLidPairs;
767 size_type importIndex = 0;
768 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
769 const GO curGID = importElements[importIndex++];
770 const LO dirMapLid = directoryMap_->getLocalElement (curGID);
771 TEUCHOS_TEST_FOR_EXCEPTION(
772 dirMapLid == LINVALID, std::logic_error,
773 Teuchos::typeName(*
this) <<
" constructor: Incoming global index "
774 << curGID <<
" does not have a corresponding local index in the "
775 "Directory Map. Please report this bug to the Tpetra developers.");
776 tableKeys[i] = dirMapLid;
777 const int PID = importElements[importIndex++];
778 const int LID = importElements[importIndex++];
788 ownedPidLidPairs[dirMapLid].push_back (std::make_pair (PID, LID));
801 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
802 const LO dirMapLid = tableKeys[i];
803 const std::vector<std::pair<int, LO> >& pidLidList =
804 ownedPidLidPairs[dirMapLid];
805 const size_t listLen = pidLidList.size();
806 if (listLen == 0)
continue;
807 const GO dirMapGid = directoryMap_->getGlobalElement (dirMapLid);
809 locallyOneToOne_ =
false;
818 const size_type index =
819 static_cast<size_type
> (tie_break->selectedIndex (dirMapGid,
821 tablePids[i] = pidLidList[index].first;
822 tableLids[i] = pidLidList[index].second;
826 typedef Kokkos::Device<
typename NT::execution_space,
827 typename NT::memory_space> DT;
829 rcp (
new Details::FixedHashTable<LO, int, DT> (tableKeys (),
832 rcp (
new Details::FixedHashTable<LO, LO, DT> (tableKeys (),
837 if (tie_break.is_null ()) {
842 PIDs_ = arcp<int> (dir_numMyEntries);
843 std::fill (PIDs_.begin (), PIDs_.end (), -1);
844 LIDs_ = arcp<LO> (dir_numMyEntries);
845 std::fill (LIDs_.begin (), LIDs_.end (), LINVALID);
847 size_type importIndex = 0;
848 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
849 const GO curGID = importElements[importIndex++];
850 const LO curLID = directoryMap_->getLocalElement (curGID);
851 TEUCHOS_TEST_FOR_EXCEPTION(curLID == LINVALID, std::logic_error,
852 Teuchos::typeName(*
this) <<
" constructor: Incoming global index "
853 << curGID <<
" does not have a corresponding local index in the "
854 "Directory Map. Please report this bug to the Tpetra developers.");
859 if (PIDs_[curLID] != -1) {
860 locallyOneToOne_ =
false;
862 PIDs_[curLID] = importElements[importIndex++];
863 LIDs_[curLID] = importElements[importIndex++];
867 PIDs_ = arcp<int> (dir_numMyEntries);
868 LIDs_ = arcp<LO> (dir_numMyEntries);
869 std::fill (PIDs_.begin (), PIDs_.end (), -1);
878 Array<std::vector<std::pair<int, LO> > > ownedPidLidPairs (dir_numMyEntries);
879 size_type importIndex = 0;
880 for (size_type i = 0; i < static_cast<size_type> (numReceives); ++i) {
881 const GO GID = importElements[importIndex++];
882 const int PID = importElements[importIndex++];
883 const LO LID = importElements[importIndex++];
885 const LO dirMapLid = directoryMap_->getLocalElement (GID);
886 TEUCHOS_TEST_FOR_EXCEPTION(
887 dirMapLid == LINVALID, std::logic_error,
888 Teuchos::typeName(*
this) <<
" constructor: Incoming global index "
889 << GID <<
" does not have a corresponding local index in the "
890 "Directory Map. Please report this bug to the Tpetra developers.");
891 ownedPidLidPairs[dirMapLid].push_back (std::make_pair (PID, LID));
903 for (
size_t i = 0; i < dir_numMyEntries; ++i) {
904 const std::vector<std::pair<int, LO> >& pidLidList =
906 const size_t listLen = pidLidList.size();
907 if (listLen == 0)
continue;
909 const LO dirMapLid =
static_cast<LO
> (i);
910 const GO dirMapGid = directoryMap_->getGlobalElement (dirMapLid);
912 locallyOneToOne_ =
false;
921 const size_type index =
922 static_cast<size_type
> (tie_break->selectedIndex (dirMapGid,
924 PIDs_[i] = pidLidList[index].first;
925 LIDs_[i] = pidLidList[index].second;
931 template<
class LO,
class GO,
class NT>
935 std::ostringstream os;
936 os <<
"DistributedNoncontiguousDirectory"
937 <<
"<" << Teuchos::TypeNameTraits<LO>::name ()
938 <<
", " << Teuchos::TypeNameTraits<GO>::name ()
939 <<
", " << Teuchos::TypeNameTraits<NT>::name () <<
">";
943 template<
class LO,
class GO,
class NT>
947 const Teuchos::ArrayView<const GO> &globalIDs,
948 const Teuchos::ArrayView<int> &nodeIDs,
949 const Teuchos::ArrayView<LO> &localIDs,
950 const bool computeLIDs)
const
952 using Teuchos::Array;
953 using Teuchos::ArrayRCP;
954 using Teuchos::ArrayView;
959 typedef typename Array<GO>::size_type size_type;
961 RCP<const Teuchos::Comm<int> > comm = map.
getComm ();
962 const size_t numEntries = globalIDs.size ();
963 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid();
972 const int packetSize = computeLIDs ? 3 : 2;
978 Array<int> dirImages (numEntries);
979 res = directoryMap_->getRemoteIndexList (globalIDs, dirImages ());
981 size_t numMissing = 0;
983 for (
size_t i=0; i < numEntries; ++i) {
984 if (dirImages[i] == -1) {
987 localIDs[i] = LINVALID;
995 Array<int> sendImages;
996 distor.
createFromRecvs (globalIDs, dirImages (), sendGIDs, sendImages);
997 const size_type numSends = sendGIDs.size ();
1030 Array<global_size_t> exports (packetSize * numSends);
1043 size_type exportsIndex = 0;
1045 if (useHashTables_) {
1046 for (size_type gidIndex = 0; gidIndex < numSends; ++gidIndex) {
1047 const GO curGID = sendGIDs[gidIndex];
1049 exports[exportsIndex++] =
static_cast<global_size_t> (curGID);
1050 const LO curLID = directoryMap_->getLocalElement (curGID);
1051 TEUCHOS_TEST_FOR_EXCEPTION(curLID == LINVALID, std::logic_error,
1052 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): The Directory "
1053 "Map's global index " << curGID <<
" does not have a corresponding "
1054 "local index. Please report this bug to the Tpetra developers.");
1056 exports[exportsIndex++] =
static_cast<global_size_t> (lidToPidTable_->get (curLID));
1059 exports[exportsIndex++] =
static_cast<global_size_t> (lidToLidTable_->get (curLID));
1063 for (size_type gidIndex = 0; gidIndex < numSends; ++gidIndex) {
1064 const GO curGID = sendGIDs[gidIndex];
1066 exports[exportsIndex++] =
static_cast<global_size_t> (curGID);
1067 const LO curLID = directoryMap_->getLocalElement (curGID);
1068 TEUCHOS_TEST_FOR_EXCEPTION(curLID == LINVALID, std::logic_error,
1069 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): The Directory "
1070 "Map's global index " << curGID <<
" does not have a corresponding "
1071 "local index. Please report this bug to the Tpetra developers.");
1073 exports[exportsIndex++] =
static_cast<global_size_t> (PIDs_[curLID]);
1076 exports[exportsIndex++] =
static_cast<global_size_t> (LIDs_[curLID]);
1081 TEUCHOS_TEST_FOR_EXCEPTION(
1082 exportsIndex > exports.size (), std::logic_error,
1083 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): On Process " <<
1084 comm->getRank () <<
", exportsIndex = " << exportsIndex <<
1085 " > exports.size() = " << exports.size () <<
1086 ". Please report this bug to the Tpetra developers.");
1089 TEUCHOS_TEST_FOR_EXCEPTION(
1090 numEntries < numMissing, std::logic_error,
1091 Teuchos::typeName (*
this) <<
"::getEntriesImpl(): On Process "
1092 << comm->getRank () <<
", numEntries = " << numEntries
1093 <<
" < numMissing = " << numMissing
1094 <<
". Please report this bug to the Tpetra developers.");
1100 const size_t numRecv = numEntries - numMissing;
1104 const size_t requiredImportLen = numRecv * packetSize;
1105 const int myRank = comm->getRank ();
1106 TEUCHOS_TEST_FOR_EXCEPTION(
1107 importLen < requiredImportLen, std::logic_error,
1108 "Tpetra::Details::DistributedNoncontiguousDirectory::getEntriesImpl: "
1109 "On Process " << myRank <<
": The 'imports' array must have length "
1110 "at least " << requiredImportLen <<
", but its actual length is " <<
1111 importLen <<
". numRecv: " << numRecv <<
", packetSize: " <<
1112 packetSize <<
", numEntries (# GIDs): " << numEntries <<
1113 ", numMissing: " << numMissing <<
": distor.getTotalReceiveLength(): "
1115 "Distributor description: " << distor.
description () <<
". "
1117 "Please report this bug to the Tpetra developers.");
1124 distor.
doPostsAndWaits (exports ().getConst (), packetSize, imports ());
1126 Array<GO> sortedIDs (globalIDs);
1127 Array<GO> offset (numEntries);
1128 for (GO ii = 0; ii < static_cast<GO> (numEntries); ++ii) {
1131 sort2 (sortedIDs.begin(), sortedIDs.begin() + numEntries, offset.begin());
1133 size_t importsIndex = 0;
1135 typedef typename Array<GO>::iterator IT;
1138 for (
size_t i = 0; i < numRecv; ++i) {
1140 const GO curGID =
static_cast<GO
> (imports[importsIndex++]);
1141 std::pair<IT, IT> p1 = std::equal_range (sortedIDs.begin(), sortedIDs.end(), curGID);
1142 if (p1.first != p1.second) {
1143 const size_t j = p1.first - sortedIDs.begin();
1145 nodeIDs[offset[j]] =
static_cast<int> (imports[importsIndex++]);
1148 localIDs[offset[j]] =
static_cast<LO
> (imports[importsIndex++]);
1150 if (nodeIDs[offset[j]] == -1) {
1156 TEUCHOS_TEST_FOR_EXCEPTION(
1157 static_cast<size_t> (importsIndex) > static_cast<size_t> (imports.size ()),
1159 "Tpetra::Details::DistributedNoncontiguousDirectory::getEntriesImpl: "
1160 "On Process " << comm->getRank () <<
": importsIndex = " <<
1161 importsIndex <<
" > imports.size() = " << imports.size () <<
". "
1162 "numRecv: " << numRecv <<
", packetSize: " << packetSize <<
", "
1163 "numEntries (# GIDs): " << numEntries <<
", numMissing: " << numMissing
1164 <<
": distor.getTotalReceiveLength(): "
1166 "the Tpetra developers.");
1172 template<
class LO,
class GO,
class NT>
1177 if (oneToOneResult_ == ONE_TO_ONE_NOT_CALLED_YET) {
1178 const int lcl121 = isLocallyOneToOne () ? 1 : 0;
1180 Teuchos::reduceAll<int, int> (comm, Teuchos::REDUCE_MIN, lcl121,
1181 Teuchos::outArg (gbl121));
1182 oneToOneResult_ = (gbl121 == 1) ? ONE_TO_ONE_TRUE : ONE_TO_ONE_FALSE;
1184 return (oneToOneResult_ == ONE_TO_ONE_TRUE);
1194 #define TPETRA_DIRECTORY_IMPL_INSTANT(LO,GO,NODE) \
1195 template class Directory< LO , GO , NODE >; \
1196 template class ReplicatedDirectory< LO , GO , NODE >; \
1197 template class ContiguousUniformDirectory< LO, GO, NODE >; \
1198 template class DistributedContiguousDirectory< LO , GO , NODE >; \
1199 template class DistributedNoncontiguousDirectory< LO , GO , NODE >; \
1201 #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 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
Return a 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).
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.
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.
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.
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2)
Sort the first array, and apply the resulting permutation to the second array.
A parallel distribution of indices 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 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.
global_size_t getGlobalNumElements() const
The number of elements in this Map.