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, map.getNode ()));
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