42 #ifndef TPETRA_IMPORT_DEF_HPP 43 #define TPETRA_IMPORT_DEF_HPP 45 #include <Tpetra_Import_decl.hpp> 46 #include <Tpetra_Distributor.hpp> 47 #include <Tpetra_Map.hpp> 48 #include <Tpetra_ImportExportData.hpp> 51 #include <Tpetra_Export.hpp> 52 #include <Teuchos_as.hpp> 57 const bool tpetraImportDebugDefault =
false;
62 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
64 Import<LocalOrdinal,GlobalOrdinal,Node>::
65 setParameterList (
const Teuchos::RCP<Teuchos::ParameterList>& plist)
67 bool debug = tpetraImportDebugDefault;
68 if (! plist.is_null ()) {
70 debug = plist->get<
bool> (
"Debug");
71 }
catch (Teuchos::Exceptions::InvalidParameter&) {}
74 ImportData_->distributor_.setParameterList (plist);
77 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
80 init (
const Teuchos::RCP<const map_type>& source,
81 const Teuchos::RCP<const map_type>& target,
83 Teuchos::Array<int> & remotePIDs,
84 const Teuchos::RCP<Teuchos::ParameterList>& plist)
93 bool debug = tpetraImportDebugDefault;
94 if (! plist.is_null ()) {
96 debug = plist->get<
bool> (
"Debug");
97 }
catch (Teuchos::Exceptions::InvalidParameter&) {}
101 if (! out_.is_null ()) {
105 std::ostringstream os;
106 const int myRank = source->getComm ()->getRank ();
107 os << myRank <<
": Import ctor" << endl;
110 ImportData_ = rcp (
new data_type (source, target, out_, plist));
112 Array<GlobalOrdinal> remoteGIDs;
113 setupSamePermuteRemote (remoteGIDs);
115 std::ostringstream os;
116 const int myRank = source->getComm ()->getRank ();
117 os << myRank <<
": Import ctor: " 118 <<
"setupSamePermuteRemote done" << endl;
121 if (source->isDistributed ()) {
122 setupExport (remoteGIDs,useRemotePIDs,remotePIDs);
125 std::ostringstream os;
126 const int myRank = source->getComm ()->getRank ();
127 os << myRank <<
": Import ctor: done" << endl;
130 if (! out_.is_null ()) {
135 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
137 Import (
const RCP<const map_type >& source,
138 const RCP<const map_type >& target) :
139 out_ (Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr))),
140 debug_ (tpetraImportDebugDefault)
142 Teuchos::Array<int> dummy;
143 init (source, target,
false, dummy, Teuchos::null);
146 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
148 Import (
const RCP<const map_type >& source,
149 const RCP<const map_type >& target,
150 const RCP<Teuchos::FancyOStream>& out) :
152 debug_ (tpetraImportDebugDefault)
154 Teuchos::Array<int> dummy;
155 init (source, target,
false, dummy, Teuchos::null);
158 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
160 Import (
const Teuchos::RCP<const map_type >& source,
161 const Teuchos::RCP<const map_type >& target,
162 const Teuchos::RCP<Teuchos::ParameterList>& plist) :
163 out_ (
Teuchos::getFancyOStream (
Teuchos::rcpFromRef (std::cerr))),
164 debug_ (tpetraImportDebugDefault)
166 Teuchos::Array<int> dummy;
167 init (source, target,
false, dummy, plist);
170 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
172 Import (
const Teuchos::RCP<const map_type >& source,
173 const Teuchos::RCP<const map_type >& target,
174 const RCP<Teuchos::FancyOStream>& out,
175 const Teuchos::RCP<Teuchos::ParameterList>& plist) :
177 debug_ (tpetraImportDebugDefault)
179 Teuchos::Array<int> dummy;
180 init (source, target,
false, dummy, plist);
183 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
185 Import (
const Teuchos::RCP<const map_type >& source,
186 const Teuchos::RCP<const map_type >& target,
187 Teuchos::Array<int> & remotePIDs) :
188 debug_ (tpetraImportDebugDefault)
190 init (source, target,
true, remotePIDs, Teuchos::null);
194 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
197 : ImportData_ (rhs.ImportData_)
199 , debug_ (rhs.debug_)
202 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
205 : out_ (exporter.out_)
206 , debug_ (exporter.debug_)
208 if (! exporter.ExportData_.is_null ()) {
209 ImportData_ = exporter.ExportData_->reverseClone ();
213 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
215 Import (
const Teuchos::RCP<const map_type>& source,
216 const Teuchos::RCP<const map_type>& target,
217 const size_t numSameIDs,
218 Teuchos::Array<LocalOrdinal>& permuteToLIDs,
219 Teuchos::Array<LocalOrdinal>& permuteFromLIDs,
220 Teuchos::Array<LocalOrdinal>& remoteLIDs,
221 Teuchos::Array<LocalOrdinal>& exportLIDs,
222 Teuchos::Array<int>& exportPIDs,
224 const Teuchos::RCP<Teuchos::FancyOStream>& out,
225 const Teuchos::RCP<Teuchos::ParameterList>& plist) :
226 out_ (out.is_null () ? Teuchos::getFancyOStream (Teuchos::rcpFromRef (std::cerr)) : out),
227 debug_ (tpetraImportDebugDefault)
237 bool debug = tpetraImportDebugDefault;
238 if (! plist.is_null ()) {
240 debug = plist->get<
bool> (
"Debug");
241 }
catch (Teuchos::Exceptions::InvalidParameter&) {}
245 if (! out_.is_null ()) {
248 if (debug_ && ! out_.is_null ()) {
249 std::ostringstream os;
250 const int myRank = source->getComm ()->getRank ();
251 os << myRank <<
": Import expert ctor" << endl;
254 ImportData_ = rcp (
new data_type (source, target, out_, plist));
256 ImportData_->numSameIDs_ = numSameIDs;
257 ImportData_->permuteToLIDs_.swap (permuteToLIDs);
258 ImportData_->permuteFromLIDs_.swap (permuteFromLIDs);
259 ImportData_->remoteLIDs_.swap (remoteLIDs);
260 ImportData_->distributor_.swap (distributor);
261 ImportData_->exportLIDs_.swap (exportLIDs);
262 ImportData_->exportPIDs_.swap (exportPIDs);
265 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
269 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
271 return ImportData_->numSameIDs_;
274 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
276 return ImportData_->permuteFromLIDs_.size();
279 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
280 ArrayView<const LocalOrdinal>
282 return ImportData_->permuteFromLIDs_();
285 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
286 ArrayView<const LocalOrdinal>
288 return ImportData_->permuteToLIDs_();
291 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
293 return ImportData_->remoteLIDs_.size();
296 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
297 ArrayView<const LocalOrdinal>
299 return ImportData_->remoteLIDs_();
302 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
304 return ImportData_->exportLIDs_.size();
307 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
308 ArrayView<const LocalOrdinal>
310 return ImportData_->exportLIDs_();
313 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
316 return ImportData_->exportPIDs_();
319 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
320 Teuchos::RCP<const typename Import<LocalOrdinal,GlobalOrdinal,Node>::map_type>
322 return ImportData_->source_;
325 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
326 Teuchos::RCP<const typename Import<LocalOrdinal,GlobalOrdinal,Node>::map_type>
328 return ImportData_->target_;
331 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
334 return ImportData_->distributor_;
337 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
342 ImportData_ = rhs.ImportData_;
347 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
352 using Teuchos::getFancyOStream;
354 using Teuchos::rcpFromRef;
355 using Teuchos::toString;
358 RCP<const Comm<int> > comm =
getSourceMap ()->getComm ();
359 const int myImageID = comm->getRank ();
360 const int numImages = comm->getSize ();
361 for (
int imageCtr = 0; imageCtr < numImages; ++imageCtr) {
362 if (myImageID == imageCtr) {
364 if (myImageID == 0) {
365 os <<
"Import Data Members:" << endl;
367 os <<
"Image ID : " << myImageID << endl;
371 os <<
"remoteLIDs : " << toString (
getRemoteLIDs ()) << endl;
372 os <<
"exportLIDs : " << toString (
getExportLIDs ()) << endl;
373 os <<
"exportPIDs : " << toString (
getExportPIDs ()) << endl;
386 const bool printMaps =
false;
388 if (myImageID == 0) {
389 os << endl << endl <<
"Source Map:" << endl << std::flush;
395 if (myImageID == 0) {
396 os << endl << endl <<
"Target Map:" << endl << std::flush;
406 if (myImageID == 0) {
407 os << endl << endl <<
"Distributor:" << endl << std::flush;
411 Teuchos::VERB_EXTREME);
415 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
421 using Teuchos::Array;
422 using Teuchos::ArrayRCP;
423 using Teuchos::ArrayView;
426 typedef LocalOrdinal LO;
427 typedef GlobalOrdinal GO;
428 typedef typename ArrayView<const GO>::size_type size_type;
434 #ifdef HAVE_TPETRA_DEBUG 435 ArrayView<const GO> rawSrcGids = sourceGIDs;
436 ArrayView<const GO> rawTgtGids = targetGIDs;
438 const GO*
const rawSrcGids = sourceGIDs.getRawPtr ();
439 const GO*
const rawTgtGids = targetGIDs.getRawPtr ();
440 #endif // HAVE_TPETRA_DEBUG 441 const size_type numSrcGids = sourceGIDs.size ();
442 const size_type numTgtGids = targetGIDs.size ();
443 const size_type numGids = std::min (numSrcGids, numTgtGids);
451 size_type numSameGids = 0;
452 for ( ; numSameGids < numGids && rawSrcGids[numSameGids] == rawTgtGids[numSameGids]; ++numSameGids)
454 ImportData_->numSameIDs_ = numSameGids;
466 Array<LO>& permuteToLIDs = ImportData_->permuteToLIDs_;
467 Array<LO>& permuteFromLIDs = ImportData_->permuteFromLIDs_;
468 Array<LO>& remoteLIDs = ImportData_->remoteLIDs_;
469 const LO LINVALID = Teuchos::OrdinalTraits<LO>::invalid ();
470 const LO numTgtLids = as<LO> (numTgtGids);
473 for (LO tgtLid = numSameGids; tgtLid < numTgtLids; ++tgtLid) {
474 const GO curTargetGid = rawTgtGids[tgtLid];
478 if (srcLid != LINVALID) {
479 permuteToLIDs.push_back (tgtLid);
480 permuteFromLIDs.push_back (srcLid);
482 remoteGIDs.push_back (curTargetGid);
483 remoteLIDs.push_back (tgtLid);
490 "::setupSamePermuteRemote(): Target has remote LIDs but Source is not " 491 "distributed globally." << std::endl
492 <<
"Importing to a submap of the target map.");
496 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
498 setupExport (Teuchos::Array<GlobalOrdinal>& remoteGIDs,
500 Teuchos::Array<int>& userRemotePIDs)
503 using Teuchos::Array;
504 using Teuchos::ArrayRCP;
505 using Teuchos::ArrayView;
508 typedef LocalOrdinal LO;
509 typedef GlobalOrdinal GO;
510 typedef typename Array<int>::difference_type size_type;
512 TEUCHOS_TEST_FOR_EXCEPTION(
513 getSourceMap ().is_null (), std::logic_error,
"Tpetra::Import::" 514 "setupExport: Source Map is null. Please report this bug to the Tpetra " 518 Teuchos::OSTab tab (out_);
527 TEUCHOS_TEST_FOR_EXCEPTION(
528 ! useRemotePIDs && (userRemotePIDs.size() > 0), std::invalid_argument,
529 "Tpetra::Import::setupExport: remotePIDs are non-empty but their use has " 530 "not been requested.");
531 TEUCHOS_TEST_FOR_EXCEPTION(
532 userRemotePIDs.size () > 0 && remoteGIDs.size () != userRemotePIDs.size (),
533 std::invalid_argument,
"Tpetra::Import::setupExport: remotePIDs must " 534 "either be of size zero or match the size of remoteGIDs.");
538 ArrayView<GO> remoteGIDsView = remoteGIDs ();
539 ArrayView<int> remoteProcIDsView;
559 Array<int> newRemotePIDs;
562 if (! useRemotePIDs) {
563 newRemotePIDs.resize (remoteGIDsView.size ());
564 if (debug_ && ! out_.is_null ()) {
565 std::ostringstream os;
566 const int myRank = source.
getComm ()->getRank ();
567 os << myRank <<
": Import::setupExport: about to call " 568 "getRemoteIndexList on source Map" << endl;
573 Array<int>& remoteProcIDs = useRemotePIDs ? userRemotePIDs : newRemotePIDs;
576 "::setupExport(): the source Map wasn't able to figure out which process " 577 "owns one or more of the GIDs in the list of remote GIDs. This probably " 578 "means that there is at least one GID owned by some process in the target" 579 " Map which is not owned by any process in the source Map. (That is, the" 580 " source and target Maps do not contain the same set of GIDs globally.)");
586 const size_type numInvalidRemote =
587 std::count_if (remoteProcIDs.begin (), remoteProcIDs.end (),
588 std::bind1st (std::equal_to<int> (), -1));
591 if (numInvalidRemote == totalNumRemote) {
593 remoteProcIDs.clear ();
595 ImportData_->remoteLIDs_.clear();
600 size_type numValidRemote = 0;
601 #ifdef HAVE_TPETRA_DEBUG 602 ArrayView<GlobalOrdinal> remoteGIDsPtr = remoteGIDsView;
604 GlobalOrdinal*
const remoteGIDsPtr = remoteGIDsView.getRawPtr ();
605 #endif // HAVE_TPETRA_DEBUG 606 for (size_type r = 0; r < totalNumRemote; ++r) {
608 if (remoteProcIDs[r] != -1) {
609 remoteProcIDs[numValidRemote] = remoteProcIDs[r];
610 remoteGIDsPtr[numValidRemote] = remoteGIDsPtr[r];
611 ImportData_->remoteLIDs_[numValidRemote] = ImportData_->remoteLIDs_[r];
615 TEUCHOS_TEST_FOR_EXCEPTION(
616 numValidRemote != totalNumRemote - numInvalidRemote, std::logic_error,
617 "Tpetra::Import::setupExport(): After removing invalid remote GIDs and" 618 " packing the valid remote GIDs, numValidRemote = " << numValidRemote
619 <<
" != totalNumRemote - numInvalidRemote = " 620 << totalNumRemote - numInvalidRemote
621 <<
". Please report this bug to the Tpetra developers.");
623 remoteProcIDs.resize (numValidRemote);
624 remoteGIDs.resize (numValidRemote);
625 ImportData_->remoteLIDs_.resize (numValidRemote);
628 remoteGIDsView = remoteGIDs ();
635 sort3 (remoteProcIDs.begin (),
636 remoteProcIDs.end (),
637 remoteGIDsView.begin (),
638 ImportData_->remoteLIDs_.begin ());
645 Array<GO> exportGIDs;
646 ImportData_->distributor_.createFromRecvs (remoteGIDsView ().getConst (),
647 remoteProcIDs, exportGIDs,
648 ImportData_->exportPIDs_);
664 const size_type numExportIDs = exportGIDs.size ();
665 if (numExportIDs > 0) {
666 ImportData_->exportLIDs_.resize (numExportIDs);
667 ArrayView<const GO> expGIDs = exportGIDs ();
668 ArrayView<LO> expLIDs = ImportData_->exportLIDs_ ();
669 for (size_type k = 0; k < numExportIDs; ++k) {
674 if (debug_ && ! out_.is_null ()) {
675 std::ostringstream os;
676 const int myRank = source.
getComm ()->getRank ();
677 os << myRank <<
": Import::setupExport: done" << endl;
683 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
684 Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node> >
689 using Teuchos::Array;
690 using Teuchos::ArrayView;
695 using Teuchos::outArg;
696 using Teuchos::REDUCE_MIN;
697 using Teuchos::reduceAll;
698 typedef LocalOrdinal LO;
699 typedef GlobalOrdinal GO;
701 typedef typename Array<GO>::size_type size_type;
703 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 704 using Teuchos::toString;
707 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 712 RCP<const Comm<int> > comm = srcMap->getComm ();
714 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 715 const int myRank = comm->getRank ();
716 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 718 #ifdef HAVE_TPETRA_DEBUG 719 TEUCHOS_TEST_FOR_EXCEPTION(
720 ! srcMap->isSameAs (* (rhs.
getSourceMap ())), std::invalid_argument,
721 "Tpetra::Import::setUnion: The source Map of the input Import must be the " 722 "same as (in the sense of Map::isSameAs) the source Map of this Import.");
723 TEUCHOS_TEST_FOR_EXCEPTION(
725 std::invalid_argument,
"Tpetra::Import::setUnion: " 726 "The target Maps must have congruent communicators.");
727 #endif // HAVE_TPETRA_DEBUG 732 if (tgtMap1->isSameAs (*tgtMap2)) {
733 return rcp (
new import_type (*
this));
738 ArrayView<const GO> srcGIDs = srcMap->getNodeElementList ();
739 ArrayView<const GO> tgtGIDs1 = tgtMap1->getNodeElementList ();
740 ArrayView<const GO> tgtGIDs2 = tgtMap2->getNodeElementList ();
742 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 745 std::ostringstream os;
746 os << myRank <<
": srcGIDs: " << toString (srcGIDs) << endl;
747 os << myRank <<
": tgtGIDs1: " << toString (tgtGIDs1) << endl;
748 os << myRank <<
": tgtGIDs2: " << toString (tgtGIDs2) << endl;
752 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 757 Array<GO> unionTgtGIDs;
762 unionTgtGIDs.reserve (tgtGIDs1.size () + tgtGIDs2.size ());
764 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 771 cerr << myRank <<
": Computing \"same\" GIDs" << endl;
772 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 780 ArrayView<const GO> sameGIDs1 = tgtGIDs1 (0, numSameGIDs1);
781 ArrayView<const GO> sameGIDs2 = tgtGIDs2 (0, numSameGIDs2);
782 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 784 std::ostringstream os;
785 os << myRank <<
": same IDs for target Map 1: " << toString (sameGIDs1) << endl;
786 os << myRank <<
": same IDs for target Map 2: " << toString (sameGIDs2) << endl;
789 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 797 ArrayView<const GO> doubleCountedSameGIDs;
798 size_type numSameIDsUnion;
799 bool tgtMap1HadMaxSameGIDs;
800 if (numSameGIDs1 >= numSameGIDs2) {
801 tgtMap1HadMaxSameGIDs =
true;
802 numSameIDsUnion = numSameGIDs1;
803 std::copy (sameGIDs1.begin (), sameGIDs1.end (), std::back_inserter (unionTgtGIDs));
808 doubleCountedSameGIDs = tgtGIDs1 (numSameGIDs2, numSameGIDs1 - numSameGIDs2);
810 tgtMap1HadMaxSameGIDs =
false;
811 numSameIDsUnion = numSameGIDs2;
812 std::copy (sameGIDs2.begin (), sameGIDs2.end (), std::back_inserter (unionTgtGIDs));
817 doubleCountedSameGIDs = tgtGIDs2 (numSameGIDs1, numSameGIDs2 - numSameGIDs1);
820 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 822 std::ostringstream os;
823 os << myRank <<
": union Map's same GIDs: " << toString (unionTgtGIDs ()) << endl;
824 os << myRank <<
": doubleCountedSameGIDs: " << toString (doubleCountedSameGIDs) << endl;
833 cerr << myRank <<
": Computing permute IDs" << endl;
834 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 840 Array<LO> permuteFromLIDsUnion;
841 Array<LO> permuteToLIDsUnion;
842 LO curTgtLid = as<LO> (numSameIDsUnion);
850 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 851 cerr << myRank <<
": Converting permute-to LIDs to GIDs" << endl;
852 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 856 Array<GO> permuteGIDs1 (numPermuteIDs1);
857 for (size_type k = 0; k < numPermuteIDs1; ++k) {
858 permuteGIDs1[k] = tgtMap1->getGlobalElement (permuteToLIDs1[k]);
860 Array<GO> permuteGIDs2 (numPermuteIDs2);
861 for (size_type k = 0; k < numPermuteIDs2; ++k) {
862 permuteGIDs2[k] = tgtMap2->getGlobalElement (permuteToLIDs2[k]);
865 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 867 std::ostringstream os;
868 os << myRank <<
": permuteGIDs1: " << toString (permuteGIDs1) << endl;
869 os << myRank <<
": permuteGIDs2: " << toString (permuteGIDs2) << endl;
872 cerr << myRank <<
": Sorting and merging permute GID lists" << endl;
873 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 878 std::sort (permuteGIDs1.begin (), permuteGIDs1.end ());
879 std::sort (permuteGIDs2.begin (), permuteGIDs2.end ());
881 typename Array<GO>::iterator permuteGIDs1_beg = permuteGIDs1.begin ();
882 typename Array<GO>::iterator permuteGIDs1_end = permuteGIDs1.end ();
883 typename Array<GO>::iterator permuteGIDs2_beg = permuteGIDs2.begin ();
884 typename Array<GO>::iterator permuteGIDs2_end = permuteGIDs2.end ();
885 if (tgtMap1HadMaxSameGIDs) {
888 std::set_difference(permuteGIDs2_beg,
890 doubleCountedSameGIDs.begin (),
891 doubleCountedSameGIDs.end (),
898 std::set_difference(permuteGIDs1_beg,
900 doubleCountedSameGIDs.begin (),
901 doubleCountedSameGIDs.end (),
905 std::set_union (permuteGIDs1_beg, permuteGIDs1_end,
906 permuteGIDs2_beg, permuteGIDs2_end,
907 std::back_inserter (unionTgtGIDs));
909 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 911 std::ostringstream os;
912 if(tgtMap1HadMaxSameGIDs) os << myRank <<
": tgtMap1HadMaxSameGIDs == true"<<endl;
913 else os << myRank <<
": tgtMap1HadMaxSameGIDs == false"<<endl;
915 os << myRank <<
": reduced permuteGIDs1: {";
916 for(
typename Array<GO>::iterator k = permuteGIDs1_beg; k != permuteGIDs1_end; k++)
919 os << myRank <<
": reduced permuteGIDs2: {";
920 for(
typename Array<GO>::iterator k = permuteGIDs2_beg; k != permuteGIDs2_end; k++)
926 const size_type numPermuteIDsUnion =
927 unionTgtGIDs.size () - numSameIDsUnion;
928 ArrayView<const GO> permuteGIDsUnion =
929 unionTgtGIDs (numSameIDsUnion, numPermuteIDsUnion).getConst ();
931 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 933 std::ostringstream os;
934 os << myRank <<
": permuteGIDsUnion: " << toString (permuteGIDsUnion) << endl;
937 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 939 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 941 cerr << myRank <<
": Computing permute-to LIDs" << endl;
942 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 945 permuteToLIDsUnion.resize (numPermuteIDsUnion);
946 for (size_type k = 0; k < numPermuteIDsUnion; ++k) {
947 permuteToLIDsUnion[k] = curTgtLid++;
950 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 952 std::ostringstream os;
953 os << myRank <<
": permuteToLIDsUnion: " << toString (permuteToLIDsUnion) << endl;
956 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 958 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 960 cerr << myRank <<
": Computing permute-from LIDs" << endl;
961 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 964 permuteFromLIDsUnion.resize (numPermuteIDsUnion);
965 for (size_type k = 0; k < numPermuteIDsUnion; ++k) {
966 permuteFromLIDsUnion[k] = srcMap->getLocalElement (permuteGIDsUnion[k]);
969 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 971 std::ostringstream os;
972 os << myRank <<
": permuteFromLIDsUnion: " << toString (permuteFromLIDsUnion) << endl;
975 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 979 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 981 std::ostringstream os;
982 os << myRank <<
": unionTgtGIDs after permutes: " 983 << toString (unionTgtGIDs ()) << endl;
986 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1007 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1014 cerr << myRank <<
": Computing remote IDs" << endl;
1015 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1017 Array<GO> remoteGIDsUnion;
1018 Array<int> remotePIDsUnion;
1019 Array<LO> remoteLIDsUnion;
1020 size_type numRemoteIDsUnion = 0;
1034 Array<int> remotePIDs1, remotePIDs2;
1035 Tpetra::Import_Util::getRemotePIDs(*
this,remotePIDs1);
1036 Tpetra::Import_Util::getRemotePIDs(rhs,remotePIDs2);
1039 Array<std::pair<int,GO> > remotePGIDs1, remotePGIDs2,remotePGUnion;
1040 remotePGIDs1.resize(remotePIDs1.size());
1041 remotePGIDs2.resize(remotePIDs2.size());
1043 for(size_type k=0; k < remotePIDs1.size(); k++)
1044 remotePGIDs1[k] = std::pair<int,GO>(remotePIDs1[k],this->
getTargetMap()->getGlobalElement(remoteLIDs1[k]));
1046 for(size_type k=0; k < remotePIDs2.size(); k++)
1047 remotePGIDs2[k] = std::pair<int,GO>(remotePIDs2[k],rhs.
getTargetMap()->getGlobalElement(remoteLIDs2[k]));
1051 std::sort(remotePGIDs1.begin(), remotePGIDs1.end());
1052 std::sort(remotePGIDs2.begin(), remotePGIDs2.end());
1053 std::merge(remotePGIDs1.begin(), remotePGIDs1.end(),
1054 remotePGIDs2.begin(), remotePGIDs2.end(),
1055 std::back_inserter(remotePGUnion));
1056 typename Array<std::pair<int,GO> >::iterator it = std::unique(remotePGUnion.begin(),remotePGUnion.end());
1057 remotePGUnion.resize(std::distance(remotePGUnion.begin(),it));
1060 numRemoteIDsUnion = remotePGUnion.size();
1061 remoteLIDsUnion.resize(numRemoteIDsUnion);
1062 remotePIDsUnion.resize(numRemoteIDsUnion);
1063 remoteGIDsUnion.resize(numRemoteIDsUnion);
1065 for (size_type k = 0; k < numRemoteIDsUnion; ++k) {
1066 remoteLIDsUnion[k] = curTgtLid++;
1067 remotePIDsUnion[k] = remotePGUnion[k].first;
1068 remoteGIDsUnion[k] = remotePGUnion[k].second;
1072 const size_type oldSize = unionTgtGIDs.size();
1073 unionTgtGIDs.resize(oldSize + numRemoteIDsUnion);
1074 for(size_type k=0; k<numRemoteIDsUnion; k++)
1075 unionTgtGIDs[oldSize+k] = remoteGIDsUnion[k];
1077 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1080 Array<GO> remoteGIDs1(remotePIDs1.size());
1081 Array<GO> remoteGIDs2(remotePIDs2.size());
1082 for(size_type k=0; k < remotePIDs1.size(); k++)
1083 remoteGIDs1[k] = this->
getTargetMap()->getGlobalElement(remoteLIDs1[k]);
1084 for(size_type k=0; k < remotePIDs2.size(); k++)
1085 remoteGIDs2[k] = rhs.
getTargetMap()->getGlobalElement(remoteLIDs2[k]);
1087 std::ostringstream os;
1088 os << myRank <<
": remoteGIDs1 : " << toString (remoteGIDs1 ()) << endl;
1089 os << myRank <<
": remotePIDs1 : " << toString (remotePIDs1 ()) << endl;
1090 os << myRank <<
": remoteGIDs2 : " << toString (remoteGIDs2 ()) << endl;
1091 os << myRank <<
": remotePIDs2 : " << toString (remotePIDs2 ()) << endl;
1097 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1099 std::ostringstream os;
1100 os << myRank <<
": remoteGIDsUnion sorted: " << toString (remoteGIDsUnion ()) << endl;
1101 os << myRank <<
": remotePIDsUnion sorted: " << toString (remotePIDsUnion ()) << endl;
1102 os << myRank <<
": remoteLIDsUnion sorted: " << toString (remoteLIDsUnion ()) << endl;
1105 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1108 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1110 std::ostringstream os;
1111 os << myRank <<
": unionTgtGIDs after remotes: " 1112 << toString (unionTgtGIDs ()) << endl;
1115 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1122 const GO indexBaseUnion =
1123 std::min (tgtMap1->getIndexBase (), tgtMap2->getIndexBase ());
1125 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1126 cerr << myRank <<
"Creating union target Map" << endl;
1127 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1149 const GST INVALID = Teuchos::OrdinalTraits<GST>::invalid ();
1150 RCP<const map_type> unionTgtMap =
1151 rcp (
new map_type (INVALID, unionTgtGIDs (), indexBaseUnion,
1152 comm, srcMap->getNode ()));
1154 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1161 cerr << myRank <<
": Computing export IDs and Distributor" << endl;
1162 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1172 Array<GO> exportGIDsUnion;
1173 Array<LO> exportLIDsUnion;
1174 Array<int> exportPIDsUnion;
1177 #ifdef TPETRA_IMPORT_SETUNION_USE_CREATE_FROM_SENDS 1199 Array<LO> exportLIDs1Copy (exportLIDs1.begin (), exportLIDs1.end ());
1200 Array<int> exportPIDs1Copy (exportLIDs1.begin (), exportLIDs1.end ());
1201 sort2 (exportLIDs1Copy.begin (), exportLIDs1Copy.end (),
1202 exportPIDs1Copy.begin ());
1203 typename ArrayView<LO>::iterator exportLIDs1_end = exportLIDs1Copy.end ();
1204 typename ArrayView<LO>::iterator exportPIDs1_end = exportPIDs1Copy.end ();
1205 merge2 (exportLIDs1_end, exportPIDs1_end,
1206 exportLIDs1Copy.begin (), exportLIDs1_end,
1207 exportPIDs1Copy.begin (), exportPIDs1_end,
1210 Array<LO> exportLIDs2Copy (exportLIDs2.begin (), exportLIDs2.end ());
1211 Array<int> exportPIDs2Copy (exportLIDs2.begin (), exportLIDs2.end ());
1212 sort2 (exportLIDs2Copy.begin (), exportLIDs2Copy.end (),
1213 exportPIDs2Copy.begin ());
1214 typename ArrayView<LO>::iterator exportLIDs2_end = exportLIDs2Copy.end ();
1215 typename ArrayView<LO>::iterator exportPIDs2_end = exportPIDs2Copy.end ();
1216 merge2 (exportLIDs2_end, exportPIDs2_end,
1217 exportLIDs2Copy.begin (), exportLIDs2_end,
1218 exportPIDs2Copy.begin (), exportPIDs2_end,
1225 keyValueMerge (exportLIDs1Copy.begin (), exportLIDs1Copy.end (),
1226 exportPIDs1Copy.begin (), exportPIDs1Copy.end (),
1227 exportLIDs2Copy.begin (), exportLIDs2Copy.end (),
1228 exportPIDs2Copy.begin (), exportPIDs2Copy.end (),
1229 std::back_inserter (exportLIDsUnion),
1230 std::back_inserter (exportPIDsUnion),
1234 sort2 (exportPIDsUnion.begin (), exportPIDsUnion.end (),
1235 exportLIDsUnion.begin ());
1241 #else // NOT TPETRA_IMPORT_SETUNION_USE_CREATE_FROM_SENDS 1249 remotePIDsUnion ().getConst (),
1250 exportGIDsUnion, exportPIDsUnion);
1253 const size_type numExportIDsUnion = exportGIDsUnion.size ();
1254 exportLIDsUnion.resize (numExportIDsUnion);
1255 for (size_type k = 0; k < numExportIDsUnion; ++k) {
1256 exportLIDsUnion[k] = srcMap->getLocalElement (exportGIDsUnion[k]);
1258 #endif // TPETRA_IMPORT_SETUNION_USE_CREATE_FROM_SENDS 1260 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1262 std::ostringstream os;
1263 os << myRank <<
": exportGIDsUnion: " << toString (exportGIDsUnion ()) << endl;
1264 os << myRank <<
": exportPIDsUnion: " << toString (exportPIDsUnion ()) << endl;
1265 os << myRank <<
": exportLIDsUnion: " << toString (exportLIDsUnion ()) << endl;
1269 cerr <<
"Creating union Import" << endl;
1270 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1273 RCP<const import_type> unionImport =
1274 rcp (
new import_type (srcMap, unionTgtMap,
1275 as<size_t> (numSameIDsUnion),
1276 permuteToLIDsUnion, permuteFromLIDsUnion,
1277 remoteLIDsUnion, exportLIDsUnion,
1278 exportPIDsUnion, distributor, this->out_));
1279 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1281 cerr <<
"Created union Import; done!" << endl;
1282 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1289 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1290 Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node> >
1294 using Teuchos::Array;
1295 using Teuchos::ArrayView;
1297 using Teuchos::Comm;
1300 using Teuchos::outArg;
1301 using Teuchos::REDUCE_MIN;
1302 using Teuchos::reduceAll;
1303 typedef LocalOrdinal LO;
1304 typedef GlobalOrdinal GO;
1305 Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node> > unionImport;
1308 RCP<const Comm<int> > comm = srcMap->getComm ();
1310 #ifdef HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1311 const int myRank = comm->getRank ();
1312 #endif // HAVE_TPETRA_IMPORT_SETUNION_EXTRA_DEBUG_OUTPUT 1314 ArrayView<const GO> srcGIDs = srcMap->getNodeElementList ();
1315 ArrayView<const GO> tgtGIDs = tgtMap->getNodeElementList ();
1318 size_t numSameIDsNew = srcMap->getNodeNumElements();
1320 Array<LO> permuteToLIDsNew, permuteFromLIDsNew;
1327 Array<GO> GIDs(numSameIDsNew + numRemoteIDsNew);
1328 for(
size_t i=0; i<numSameIDsNew; i++)
1329 GIDs[i] = srcGIDs[i];
1332 Array<LO> remoteLIDsNew(numRemoteIDsNew);
1333 for(
size_t i=0; i<numRemoteIDsNew; i++) {
1334 GIDs[numSameIDsNew + i] = tgtGIDs[remoteLIDsOld[i]];
1335 remoteLIDsNew[i] = numSameIDsNew+i;
1339 GO GO_INVALID = Teuchos::OrdinalTraits<GO>::invalid();
1340 RCP<const map_type> targetMapNew = rcp(
new map_type(GO_INVALID,GIDs,tgtMap->getIndexBase(),tgtMap->getComm(),tgtMap->getNode()));
1351 remoteLIDsNew,exportLIDsnew,exportPIDsnew,D));
1359 template <
class LocalOrdinal,
class GlobalOrdinal,
class Node>
1360 Teuchos::RCP<const Import<LocalOrdinal, GlobalOrdinal, Node> >
1368 TEUCHOS_TEST_FOR_EXCEPTION(
1369 NumRemotes != remoteTarget->getNodeNumElements (),
1370 std::runtime_error,
"Tpetra::createRemoteOnlyImport: " 1371 "remoteTarget map ID count doesn't match.");
1374 Teuchos::ArrayView<const LocalOrdinal> oldRemoteLIDs =
getRemoteLIDs ();
1375 Teuchos::Array<LocalOrdinal> newRemoteLIDs (NumRemotes);
1376 for (
size_t i = 0; i < NumRemotes; ++i) {
1377 newRemoteLIDs[i] = remoteTarget->getLocalElement (
getTargetMap ()->getGlobalElement (oldRemoteLIDs[i]));
1379 TEUCHOS_TEST_FOR_EXCEPTION(
1380 i > 0 && newRemoteLIDs[i] < newRemoteLIDs[i-1],
1381 std::runtime_error,
"Tpetra::createRemoteOnlyImport: " 1382 "this and remoteTarget order don't match.");
1391 Teuchos::Array<LocalOrdinal> newExportLIDs (
getExportLIDs ());
1392 Teuchos::Array<LocalOrdinal> dummy;
1395 return rcp (
new import_type (
getSourceMap (), remoteTarget,
1396 static_cast<size_t> (0), dummy, dummy,
1397 newRemoteLIDs, newExportLIDs,
1398 newExportPIDs, newDistor));
1403 #define TPETRA_IMPORT_CLASS_INSTANT(LO, GO, NODE) \ 1405 template class Import< LO , GO , NODE >; 1414 #define TPETRA_IMPORT_INSTANT(LO, GO, NODE) \ 1415 TPETRA_IMPORT_CLASS_INSTANT(LO, GO, NODE) 1417 #endif // TPETRA_IMPORT_DEF_HPP bool congruent(const Teuchos::Comm< int > &comm1, const Teuchos::Comm< int > &comm2)
Whether the two communicators are congruent.
Communication plan for data redistribution from a uniquely-owned to a (possibly) multiply-owned distr...
::Tpetra::Map< LocalOrdinal, GlobalOrdinal, Node > map_type
The specialization of Map used by this class.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
ArrayView< const int > getExportPIDs() const
List of processes to which entries will be sent.
ArrayView< const LocalOrdinal > getRemoteLIDs() const
List of entries in the target Map to receive from other processes.
Teuchos::RCP< const Import< LocalOrdinal, GlobalOrdinal, Node > > createRemoteOnlyImport(const Teuchos::RCP< const map_type > &remoteTarget) const
Returns an importer that contains only the remote entries of this.
void sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT3 &first3)
Sort the first array, and apply the same permutation to the second and third arrays.
LookupStatus
Return status of Map remote index lookup (getRemoteIndexList()).
size_t getNumExportIDs() const
Number of entries that must be sent by the calling process to other processes.
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.
virtual ~Import()
Destructor.
Teuchos::RCP< const Import< LocalOrdinal, GlobalOrdinal, Node > > setUnion() const
Return the union of this Import this->getSourceMap()
size_t global_size_t
Global size_t object.
void merge2(IT1 &indResultOut, IT2 &valResultOut, IT1 indBeg, IT1 indEnd, IT2 valBeg, IT2 valEnd)
Merge values in place, additively, with the same index.
Import(const Teuchos::RCP< const map_type > &source, const Teuchos::RCP< const map_type > &target)
Construct an Import from the source and target Maps.
void keyValueMerge(KeyInputIterType keyBeg1, KeyInputIterType keyEnd1, ValueInputIterType valBeg1, ValueInputIterType valEnd1, KeyInputIterType keyBeg2, KeyInputIterType keyEnd2, ValueInputIterType valBeg2, ValueInputIterType valEnd2, KeyOutputIterType keyOut, ValueOutputIterType valOut, BinaryFunction f)
Merge two sorted (by keys) sequences of unique (key,value) pairs by combining pairs with equal keys...
ArrayView< const LocalOrdinal > getPermuteFromLIDs() const
List of local IDs in the source Map that are permuted.
Communication plan for data redistribution from a (possibly) multiply-owned to a uniquely-owned distr...
#define TPETRA_ABUSE_WARNING(throw_exception_test, Exception, msg)
Handle an abuse warning, according to HAVE_TPETRA_THROW_ABUSE_WARNINGS and HAVE_TPETRA_PRINT_ABUSE_WA...
Import< LocalOrdinal, GlobalOrdinal, Node > & operator=(const Import< LocalOrdinal, GlobalOrdinal, Node > &Source)
Assignment operator.
Implementation detail of Import and Export.
Sets up and executes a communication plan for a Tpetra DistObject.
size_t createFromSends(const ArrayView< const int > &exportNodeIDs)
Set up Distributor using list of process ranks to which this process will send.
LookupStatus getRemoteIndexList(const Teuchos::ArrayView< const GlobalOrdinal > &GIDList, const Teuchos::ArrayView< int > &nodeIDList, const Teuchos::ArrayView< LocalOrdinal > &LIDList) const
Return the process ranks and corresponding local indices for the given global indices.
ArrayView< const LocalOrdinal > getPermuteToLIDs() const
List of local IDs in the target Map that are permuted.
ArrayView< const LocalOrdinal > getExportLIDs() const
List of entries in the source Map that will be sent to other processes.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a view of the global indices owned by this process.
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2)
Sort the first array, and apply the resulting permutation to the second array.
Describes a parallel distribution of objects over processes.
Internal functions and macros designed for use with Tpetra::Import and Tpetra::Export objects...
Stand-alone utility functions and macros.
size_t getNumPermuteIDs() const
Number of IDs to permute but not to communicate.
size_t getNumSameIDs() const
Number of initial identical IDs.
Teuchos::RCP< const map_type > getSourceMap() const
The Source Map used to construct this Import object.
Distributor & getDistributor() const
The Distributor that this Import object uses to move data.
virtual void print(std::ostream &os) const
Print the Import's data to the given output stream.
size_t getNumRemoteIDs() const
Number of entries not on the calling process.
void describe(Teuchos::FancyOStream &out, const Teuchos::EVerbosityLevel verbLevel=Teuchos::Describable::verbLevel_default) const
Print the object with some verbosity level to an FancyOStream.
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.
Teuchos::RCP< const map_type > getTargetMap() const
The Target Map used to construct this Import object.
Binary function that returns its first argument.